SIP Witch 1.9.15
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sipquery.cpp
Go to the documentation of this file.
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>
20 #include <eXosip2/eXosip.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;
62  eXosip_event_t *sevent;
63  const char *cp, *user;
64  char buffer[256];
65  char pbuffer[256];
66  char tbuffer[256];
67  osip_message_t *msg = NULL;
68  int rid;
69  osip_contact_t *contact;
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
221  context = eXosip_malloc();
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 
235  if(eXosip_listen_addr(OPTION_CONTEXT protocol, binding, port, family, tls)) {
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)
246  eXosip_masquerade_contact(OPTION_CONTEXT forwarded, port);
247 
248  eXosip_set_user_agent(OPTION_CONTEXT "SIPW/sipquery");
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 
298  rid = eXosip_register_build_initial_register(OPTION_CONTEXT buffer, proxy, NULL, 60, &msg);
299  if(!msg) {
301  shell::errexit(3, "*** sipuser: cannot create query for %s\n", user);
302  }
303  snprintf(tbuffer, sizeof(tbuffer), "<%s>", buffer);
304  osip_message_set_to(msg, tbuffer);
308 
309  while(!stop) {
310  sevent = eXosip_event_wait(OPTION_CONTEXT 0, timeout);
311  if(!sevent)
312  shell::errexit(2, "*** sipuser: timed out\n");
313 
314  if(sevent->type == EXOSIP_REGISTRATION_FAILURE) {
315  error = 1;
316  ++stop;
317  }
318 
319  if(sevent->type == EXOSIP_REGISTRATION_SUCCESS) {
320  pos = 0;
321  while(verbose && sevent->response && !osip_list_eol(OSIP2_LIST_PTR sevent->response->contacts, pos)) {
322  contact = (osip_contact_t *)osip_list_get(OSIP2_LIST_PTR sevent->response->contacts, pos++);
323  if(contact && contact->url)
324  printf("%s:%s@%s:%s\n",
325  contact->url->scheme, contact->url->username,
326  contact->url->host, contact->url->port);
327  }
328  error = 0;
329  ++stop;
330  }
331 
332  eXosip_event_free(sevent);
333  }
336  PROGRAM_EXIT(error);
337 }
338 
Structure for SIP Message (REQUEST and RESPONSE).
Definition: osip_message.h:55
user is successfully registred.
Definition: eXosip.h:290
char * port
Port number.
Definition: osip_uri.h:172
osip_list_t contacts
Contacts headers.
Definition: osip_message.h:74
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.
Definition: eXosip.h:359
void eXosip_event_free(eXosip_event_t *je)
Free ressource in an eXosip event.
user is not registred.
Definition: eXosip.h:291
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.
osip_uri_t * url
url
Definition: osip_from.h:51
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.
#define EXOSIP_UNLOCK
Definition: sipquery.cpp:46
int osip_message_set_to(osip_message_t *sip, const char *hvalue)
Set the To header.
char * username
Username.
Definition: osip_uri.h:169
#define OPTION_CONTEXT
Definition: sipquery.cpp:48
PROGRAM_MAIN(argc, argv)
Definition: sipquery.cpp:59
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.
Definition: osip_from.h:48
#define EXOSIP_CONTEXT
Definition: sipquery.cpp:47
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.
short argc
Definition: cgiserver.cpp:93
eXosip API
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.
#define EXOSIP_LOCK
Definition: sipquery.cpp:45
char * scheme
Uri Scheme (sip or sips)
Definition: osip_uri.h:168
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
Definition: eXosip.h:365
eXosip_event_type_t type
type of the event
Definition: eXosip.h:360
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.
char * host
Domain.
Definition: osip_uri.h:171