1 // Copyright (C) 2008-2014 David Sugar, Tycho Softworks.
2 // Copyright (C) 2015 Cherokees of Idaho.
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 #undef HAVE_CONFIG_H
18
19 #include <sipwitch-config.h>
21 #include <ucommon/ucommon.h>
22
23 static int verbose = 0;
24 static int port = 0;
25 static int family = AF_INET;
26 static int protocol = IPPROTO_UDP;
27 static const char *server = NULL;
28 static const char *forwarded = NULL;
29 static const char *proxy = NULL;
30 static const char *binding = NULL;
31 static unsigned timeout = 1000;
32 static int tls = 0;
33
34 #if defined(EXOSIP_OPT_BASE_OPTION) && !defined(EXOSIP_OPT_DONT_SEND_101)
35 #define EXOSIP_API4
36 #endif
37
38 #ifdef EXOSIP_API4
39 #define EXOSIP_CONTEXT context
40 #define OPTION_CONTEXT context,
41 #define EXOSIP_LOCK eXosip_lock(context);
42 #define EXOSIP_UNLOCK eXosip_unlock(context);
43 static struct eXosip_t *context = NULL;
44 #else
45 #define EXOSIP_LOCK eXosip_lock();
46 #define EXOSIP_UNLOCK eXosip_unlock();
47 #define EXOSIP_CONTEXT
48 #define OPTION_CONTEXT
49 #endif
50
51 using namespace ucommon;
52
53 #if defined(_MSWINDOWS_) && defined(__GNUC__)
54 // binds addrinfo for mingw32 linkage since otherwise mingw32 cannot
55 // cannot link proper getaddrinfo/freeaddrinfo calls that eXosip uses.
56 static Socket::address localhost("127.0.0.1");
57 #endif
58
60 {
61 int error = 2;
63 const char *cp, *user;
64 char buffer[256];
65 char pbuffer[256];
66 char tbuffer[256];
68 int rid;
70 int pos = 0;
71 int stop = 0;
72
73 cp = getenv("SIP_PROXY");
74 if(cp)
75 proxy = cp;
76
77 cp = getenv("SIP_SERVER");
78 if(cp)
79 server = cp;
80
81
82 while(NULL != *(++argv)) {
83 if(!strcmp(*argv, "--")) {
84 ++argv;
85 break;
86 }
87
88 if(!strncmp(*argv, "--", 2))
89 ++*argv;
90
91 if(!strcmp(*argv, "-q") || !strcmp(*argv, "-quiet")) {
92 verbose = 0;
93 continue;
94 }
95
96 if(!strcmp(*argv, "-version")) {
97 printf("sipquery 0.1\n"
98 "Copyright (C) 2008 David Sugar, Tycho Softworks\n"
99 "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n"
100 "This is free software: you are free to change and redistribute it.\n"
101 "There is NO WARRANTY, to the extent permitted by law.\n");
102 exit(0);
103 }
104
105 if(!strcmp(*argv, "-v") || !strcmp(*argv, "-verbose")) {
106 verbose = 1;
107 continue;
108 }
109
110
111 if(!strcmp(*argv, "-t") || !strcmp(*argv, "-timeout")) {
112 if(NULL == *(++argv))
113 shell::errexit(3, "*** sipuser: timeout option missing timeout\n");
114 timeout = atoi(*argv) * 1000;
115 if(!timeout)
116 shell::errexit(3, "*** sipuser: timeout option invalid\n");
117
118 continue;
119 }
120
121 if(!strncmp(*argv, "-timeout=", 9)) {
122 timeout = atoi(*argv + 9) * 1000;
123 if(!timeout)
124 shell::errexit(3, "*** sipuser: timeout option invalid\n");
125
126 continue;
127 }
128
129 if(!strcmp(*argv, "-p") || !strcmp(*argv, "-port")) {
130 if(NULL == *(++argv))
131 shell::errexit(3, "*** sipuser: port option missing port\n");
132
133 port = atoi(*argv);
134 if(!port)
135 shell::errexit(3, "*** sipuser: port option invalid number\n");
136
137 continue;
138 }
139
140 if(!strncmp(*argv, "-port=", 6)) {
141 port = atoi(*argv + 6);
142 if(!port)
143 shell::errexit(3, "*** sipuser: port option invalid number\n");
144
145 continue;
146 }
147
148 if(!strcmp(*argv, "-proxy")) {
149 proxy = *(++argv);
150 if(!proxy)
151 shell::errexit(3, "*** sipuser: proxy option missing proxy\n");
152 continue;
153 }
154
155 if(!strncmp(*argv, "-proxy=", 7)) {
156 proxy = *argv + 7;
157 continue;
158 }
159
160 if(!strcmp(*argv, "-server")) {
161 server = *(++argv);
162 if(!server)
163 shell::errexit(3, "*** sipuser: server option missing proxy\n");
164 continue;
165 }
166
167 if(!strncmp(*argv, "-server=", 8)) {
168 server = *argv + 8;
169 continue;
170 }
171
172 if(!strcmp(*argv, "-forward")) {
173 forwarded = *(++argv);
174 if(!forwarded)
175 shell::errexit(3, "*** sipuser: forwarding option missing interface\n");
176 continue;
177 }
178
179 if(!strncmp(*argv, "-forward=", 9)) {
180 forwarded = *argv + 8;
181 continue;
182 }
183
184 if(!strcmp(*argv, "-?") || !strcmp(*argv, "-h") || !strcmp(*argv, "-help")) {
185 fprintf(stderr, "usage: sipuser [options] userid\n"
186 "[options]\n"
187 " -proxy sip:proxyhost[:port]\n"
188 " -server sip:server[:port]\n"
189 " -forward ip-address\n"
190 " -port port-numer\n"
191 " -timeout seconds\n"
192 " -verbsose\n"
193 "Report bugs to sipwitch-devel@gnu.org\n");
194 exit(3);
195 }
196
197 if(**argv == '-')
198 shell::errexit(3, "*** sipuser: %s: unknown option\n", *argv);
199
200 break;
201 }
202
203 if(!*argv) {
204 usage:
205 shell::errexit(3, "use: sipuser [options] userid\n");
206 }
207
208 user = *(argv++);
209 if(*argv)
210 goto usage;
211
212 #if defined(WIN32) || defined(_WIn32)
213 if(!port)
214 port = 5060;
215 #else
216 if(!port)
217 port = 5060 + getuid();
218 #endif
219
220 #ifdef EXOSIP_API4
222 #endif
223
225 shell::errexit(3, "*** sipuser: failed exosip init\n");
226
227 #ifdef AF_INET6
228 if(family == AF_INET6) {
230 if(binding == NULL)
231 binding = "::0";
232 }
233 #endif
234
236 #ifdef AF_INET6
237 if(!binding && family == AF_INET6)
238 binding = "::0";
239 #endif
240 if(!binding)
241 binding = "*";
242 shell::errexit(3, "*** sipuser: failed to listen %s:%d\n", binding, port);
243 }
244
245 if(forwarded)
247
249
250 if(!strncmp(user, "sip:", 4)) {
251 tls = 0;
252 user += 4;
253 }
254 else if(!strncmp(user, "sips:", 5)) {
255 tls = 1;
256 user += 5;
257 }
258
259 if(!server && strchr(user, '@')) {
260 server = strchr(user, '@');
261 ++server;
262 }
263
264 if(server && !strncmp(server, "sip:", 4))
265 server += 4;
266 else if(server && !strncmp(server, "sips:", 5))
267 server += 5;
268
269 #ifdef AF_INET6
270 if(family == AF_INET6 && server == NULL)
271 server = "::1";
272 #endif
273 if(server == NULL)
274 server = "127.0.0.1";
275
276 if(!proxy)
277 proxy = server;
278
279 if(strncmp(proxy, "sip:", 4) && strncmp(proxy, "sips:", 5)) {
280 if(tls)
281 snprintf(pbuffer, sizeof(pbuffer), "sips:%s", proxy);
282 else
283 snprintf(pbuffer, sizeof(pbuffer), "sip:%s", proxy);
284 proxy = pbuffer;
285 }
286
287 if(tls && !strchr(user, '@'))
288 snprintf(buffer, sizeof(buffer), "sips:%s@%s", user, server);
289 else if(!strchr(user, '@'))
290 snprintf(buffer, sizeof(buffer), "sip:%s@%s", user, server);
291 else if(tls)
292 snprintf(buffer, sizeof(buffer), "sips:%s", user);
293 else
294 snprintf(buffer, sizeof(buffer), "sip:%s", user);
295
296
299 if(!msg) {
301 shell::errexit(3, "*** sipuser: cannot create query for %s\n", user);
302 }
303 snprintf(tbuffer, sizeof(tbuffer), "<%s>", buffer);
308
309 while(!stop) {
311 if(!sevent)
312 shell::errexit(2, "*** sipuser: timed out\n");
313
315 error = 1;
316 ++stop;
317 }
318
320 pos = 0;
323 if(contact && contact->
url)
324 printf("%s:%s@%s:%s\n",
327 }
328 error = 0;
329 ++stop;
330 }
331
333 }
336 PROGRAM_EXIT(error);
337 }
338
Structure for SIP Message (REQUEST and RESPONSE).
user is successfully registred.
osip_list_t contacts
Contacts headers.
void eXosip_set_user_agent(struct eXosip_t *excontext, const char *user_agent)
Set the SIP User-Agent: header string.
void * osip_list_get(const osip_list_t *li, int pos)
Get an element from a list.
Structure for event description.
void eXosip_event_free(eXosip_event_t *je)
Free ressource in an eXosip event.
int eXosip_init(struct eXosip_t *excontext)
Initiate the eXtented oSIP library.
void eXosip_quit(struct eXosip_t *excontext)
Release ressource used by the eXtented oSIP library.
int eXosip_register_build_initial_register(struct eXosip_t *excontext, const char *from, const char *proxy, const char *contact, int expires, osip_message_t **reg)
Build initial REGISTER request.
int eXosip_register_remove(struct eXosip_t *excontext, int rid)
Remove existing registration without sending REGISTER.
int osip_message_set_to(osip_message_t *sip, const char *hvalue)
Set the To header.
int eXosip_register_send_register(struct eXosip_t *excontext, int rid, osip_message_t *reg)
Send a REGISTER request for an existing registration.
int osip_list_eol(const osip_list_t *li, int pos)
Check if the end of list is detected .
Definition of the From header.
struct eXosip_t * eXosip_malloc(void)
Allocate an eXosip context.
eXosip_event_t * eXosip_event_wait(struct eXosip_t *excontext, int tv_s, int tv_ms)
Wait for an eXosip event.
void eXosip_masquerade_contact(struct eXosip_t *excontext, const char *public_address, int port)
This method is used to replace contact address with the public address of your NAT.
char * scheme
Uri Scheme (sip or sips)
void osip_list_ofchar_free(osip_list_t *li)
Free a list of element where elements are pointer to 'char'.
osip_message_t * response
last response within current transaction
eXosip_event_type_t type
type of the event
int eXosip_listen_addr(struct eXosip_t *excontext, int transport, const char *addr, int port, int family, int secure)
Listen on a specified socket.
void eXosip_enable_ipv6(int ipv6_enable)
Use IPv6 instead of IPv4.