JunkBox_Lib  1.10.2
sip_tool.c
Go to the documentation of this file.
1 
41 #include "sip_tool.h"
42 
43 
45 //
46 
53 {
54  char num[LEN_INT];
55 
56  set_protocol_contents(lp, sdp);
57 
58  // reset size of contents
59  snprintf(num, LEN_INT, "%d", sdp.vldsz);
60  num[LEN_INT-1] = '\0';
61  set_protocol_header(lp, (char*)"Content-Length", num, 1, ON);
62 
63  return;
64 }
65 
66 
67 
69 // SIP Header
70 //
71 
72 
74 // Via
75 
84 {
85  char* pp;
87 
88  if (lp==NULL) return buf;
89  if (no<=0) no = 1;
90 
91  buf = search_protocol_header_item(lp, (char*)"Via", no, ' ', 2);
92  if (buf.buf!=NULL) {
93  // received, rport
94  Buffer wrk = dup_Buffer(buf);
95  pp = strstrcase((char*)wrk.buf, "received=");
96  if (pp!=NULL) {
97  char* pa = pp = pp + 9;
98  while (*pp!=';' && *pp!='\0') pp++;
99  if (*pp==';') *pp = '\0';
100 
101  pp = strstrcase((char*)buf.buf, "rport=");
102  if (pp!=NULL) {
103  char* pt = pp = pp + 6;
104  while (*pp!=';' && *pp!='\0') pp++;
105  if (*pp==';') *pp = '\0';
106 
107  Buffer hostport = comp_hostport(pa, (unsigned short)atoi(pt));
108  free_Buffer(&buf);
109  free_Buffer(&wrk);
110  return hostport;
111  }
112  }
113  free_Buffer(&wrk);
114 
115  //
116  pp = (char*)buf.buf;
117  while (*pp!=';' && *pp!='\0') pp++;
118  if (*pp==';') *pp = '\0';
119  }
120 
121  return buf;
122 }
123 
124 
130 void insert_sip_via(tList* lp, char* host, unsigned short port, char* branch, int add_mode)
131 {
132  char sipver[] = "SIP/2.0/UDP ";
133  char hostport[LBUF];
134  Buffer buf;
135  tList* pm;
136 
137  if (lp==NULL || host==NULL) return;
138 
139  pm = strncasecmp_tList(lp, (char*)"Via", 0, 1);
140  if (pm==NULL) {
141  if (add_mode) pm = strncmp_tList(lp, (char*)HDLIST_FIRST_LINE_KEY, 0, 1);
142  if (pm==NULL) return;
143  }
144  else if (pm->prev!=NULL) pm = pm->prev;
145  else return;
146 
147  buf = make_Buffer(LBUF);
148  if (port!=0) snprintf(hostport, LBUF, "%s:%d", host, port);
149  else snprintf(hostport, LBUF, "%s", host);
150  hostport[LBUF-1] = '\0'; // to make sure
151 
152  copy_s2Buffer(sipver, &buf);
153  cat_s2Buffer (hostport, &buf);
154  if (branch!=NULL) {
155  cat_s2Buffer(";branch=z9hG4bK", &buf);
156  cat_s2Buffer(branch, &buf);
157  }
158 
159  add_tList_node_str(pm, "Via", (char*)buf.buf);
160  free_Buffer(&buf);
161 
162  return;
163 }
164 
165 
171 void del_sip_via(tList* lp, char* host, unsigned short port)
172 {
173  char hostport[LBUF];
174 
175  if (lp==NULL || host==NULL) return;
176 
177  if (port!=0) snprintf(hostport, LBUF, "%s:%d", host, port);
178  else snprintf(hostport, LBUF, "%s", host);
179  hostport[LBUF-1] = '\0'; // to make sure
180 
181  while (lp!=NULL) {
182  if (lp->ldat.key.buf!=NULL && !strcasecmp((char*)lp->ldat.key.buf, "Via")) {
183  Buffer via_hostport = cawk_Buffer(lp->ldat.val, ' ', 2);
184  if (!strncmp(hostport, (char*)via_hostport.buf, strlen(hostport))) {
185  lp = del_tList_node(&lp);
186  }
187  else lp = lp->next;
188  free_Buffer(&via_hostport);
189  }
190  else lp = lp->next;
191  }
192 
193  return;
194 }
195 
196 
198 // Record-Route
199 
205 void insert_sip_record_route(tList* lp, char* host, unsigned short port, int add_mode)
206 {
207  char ftag[LBUF];
208  char sipuri[LBUF];
209  tList* pm;
210 
211  if (lp==NULL || host==NULL) return;
212 
213  ftag[0] = '\0';
214 
215  pm = strncasecmp_tList(lp, (char*)"Record-Route", 0, 1);
216  if (pm==NULL) {
217  if (add_mode) pm = strncmp_tList(lp, (char*)HDLIST_FIRST_LINE_KEY, 0, 1);
218  if (pm==NULL) return;
219  }
220  else if (pm->prev!=NULL) {
221  char* pp = strstrcase((char*)pm->ldat.val.buf, "ftag=");
222  if (pp!=NULL) {
223  pp = pp + 5;
224  int i = 0;
225  while (pp[i]!='\0' && pp[i]!=';' && pp[i]!='>' && i<LBUF) {
226  ftag[i] = pp[i];
227  i++;
228  }
229  ftag[i] = '\0';
230  }
231  pm = pm->prev;
232  }
233  else return;
234 
235  if (port!=0) {
236  if (ftag[0]!='\0') snprintf(sipuri, LBUF, "<sip:%s:%d;ftag=%s;lr=on>", host, port, ftag);
237  else snprintf(sipuri, LBUF, "<sip:%s:%d;lr=on>", host, port);
238  }
239  else {
240  if (ftag[0]!='\0') snprintf(sipuri, LBUF, "<sip:%s;ftag=%s;lr=on>", host, ftag);
241  else snprintf(sipuri, LBUF, "<sip:%s;lr=on>", host);
242  }
243  sipuri[LBUF-1] = '\0'; // to make sure
244 
245  add_tList_node_str(pm, "Record-Route", sipuri);
246 
247  return;
248 }
249 
250 
256 void del_sip_record_route(tList* lp, char* host, unsigned short port)
257 {
258  char sipuri[LBUF];
259 
260  if (lp==NULL || host==NULL) return;
261 
262  if (port!=0) snprintf(sipuri, LBUF, "sip:%s:%d", host, port);
263  else snprintf(sipuri, LBUF, "sip:%s", host);
264  sipuri[LBUF-1] = '\0'; // to make sure
265 
266  while (lp!=NULL) {
267  if (lp->ldat.key.buf!=NULL && !strcasecmp((char*)lp->ldat.key.buf, "Record-Route")) {
268  char* rrt = (char*)lp->ldat.val.buf;
269  if (rrt[0]=='<') rrt++;
270 
271  if (!strncmp(sipuri, rrt, strlen(sipuri))) {
272  lp = del_tList_node(&lp);
273  }
274  else lp = lp->next;
275  }
276  else lp = lp->next;
277  }
278 
279  return;
280 }
281 
282 
289 {
290  while (lp!=NULL) {
291  if (lp->ldat.key.buf!=NULL && !strcasecmp((char*)lp->ldat.key.buf, "Record-Route")) {
292  lp = del_tList_node(&lp);
293  }
294  else lp = lp->next;
295  }
296 }
297 
298 
299 
301 // Cotact
302 
308 void replace_sip_contact(tList* lp, char* host, unsigned short port)
309 {
310  char contct[LBUF];
311  char hostport[LBUF];
312 
313  if (lp==NULL || host==NULL) return;
314 
315  tList* lc = strncasecmp_tList(lp, (char*)"Contact", 0, 1);
316  if (lc==NULL || lc->ldat.val.buf==NULL) return;
317 
318  char* pa = (char*)lc->ldat.val.buf;
319  char* ps = strstrcase(pa, "sip:");
320 
321  while (ps!=NULL) {
322  char* pp = strstr(ps, "@");
323  if (pp==NULL) pp = ps + 3;
324 
325  pp++;
326  //int i, cnt=0;
327  int i;
328  for (i=0; i<LBUF-1; i++) {
329  //if (*pp==':') cnt++;
330  if (*pp=='\0' || *pp=='>' || *pp==' ' || *pp==';') break;
331  contct[i] = *pp;
332  pp++;
333  }
334  contct[i] = '\0';
335 
336  if (i<LBUF-1) {
337  //if (cnt==1 && port!=0) snprintf(hostport, LBUF, "%s:%d", host, port);
338  //else snprintf(hostport, LBUF, "%s", host);
339  if (port!=0) snprintf(hostport, LBUF, "%s:%d", host, port);
340  else snprintf(hostport, LBUF, "%s", host);
341  hostport[LBUF-1] = '\0';
342 
343  Buffer buf = replace_sBuffer(lc->ldat.val, contct, hostport);
344  free_Buffer(&lc->ldat.val);
345  lc->ldat.val = buf;
346  }
347 
348  ps = strstrcase(pp, "sip:");
349  }
350 
351  return;
352 }
353 
354 
366 {
367  Buffer cturi = init_Buffer();
368  Buffer cntct = search_protocol_header(lp, (char*)"Contact", 1);
369 
370  if (cntct.buf!=NULL) {
371  int i = 0;
372  while (cntct.buf[i]!='\0' && cntct.buf[i]!=';' && cntct.buf[i]!=',' && cntct.buf[i]!=CHAR_LF && cntct.buf[i]!=CHAR_CR) i++;
373  cntct.buf[i] = '\0';
374 
375  cturi = cntct;
376  }
377 
378  return cturi;
379 }
380 
381 
393 {
394  Buffer sipdmn = init_Buffer();
395  Buffer siptmp = dup_Buffer(sipuri);
396 
397  if (siptmp.buf!=NULL) {
398  int i = 0;
399  char* pp = NULL;
400  while (siptmp.buf[i]!='\0' && siptmp.buf[i]!='>' && siptmp.buf[i]!=';' &&
401  siptmp.buf[i]!=',' && siptmp.buf[i]!=CHAR_LF && siptmp.buf[i]!=CHAR_CR) {
402  if (siptmp.buf[i]=='@') pp = (char*)&siptmp.buf[i+1];
403  i++;
404  }
405  siptmp.buf[i] = '\0';
406 
407  if (pp!=NULL) sipdmn = make_Buffer_bystr(pp);
408  free_Buffer(&siptmp);
409  }
410 
411  return sipdmn;
412 }
413 
414 
415 
417 // Max-Forwards
418 
425 {
426  int mxfd = SIP_NOMAXFORWARDS;
427 
428  if (lp==NULL) return mxfd;
429 
430  tList* lt = strncasecmp_tList(lp, (char*)"Max-Forwards", 0, 1);
431  if (lt!=NULL) {
432  mxfd = atoi((char*)lt->ldat.val.buf);
433  }
434 
435  return mxfd;
436 }
437 
438 
444 void set_max_forwards(tList* lp, int nm)
445 {
446  char mxfd[LEN_INT];
447 
448  if (lp==NULL) return;
449 
450  tList* lt = strncasecmp_tList(lp, (char*)"Max-Forwards", 0, 1);
451  if (lt!=NULL) {
452  snprintf(mxfd, LEN_INT, "%d", nm);
453  mxfd[LEN_INT-1] = '\0';
454  free_Buffer(&lt->ldat.val);
455  lt->ldat.val = make_Buffer_bystr(mxfd);
456  }
457 
458  return;
459 }
460 
461 
462 
464 // SDP Body
465 //
466 
474 {
476  tList* ls = get_protocol_header_list(cnt, '=', FALSE, FALSE);
477 
478  free_Buffer(&cnt);
479  return ls;
480 }
481 
482 
489 {
490  Buffer buf = init_Buffer();
491 
492  if (ls==NULL) return buf;
493 
494  buf = restore_protocol_header(ls, (char*)"=", OFF, NULL);
495  if (buf.buf!=NULL) {
496  buf.vldsz = buf.vldsz - 2;
497  buf.buf[buf.vldsz] = '\0';
498  }
499 
500  return buf;
501 }
502 
503 
515 int replace_sdp_invite_addr(tList*lp, tList* ls, char* host, unsigned short port, int del_candi)
516 {
517  tList* lsdp;
518  Buffer num, sdp;
519 
520  if (lp==NULL || host==NULL || port==0) return FALSE;
521 
522  num = make_Buffer(LEN_INT);
523  copy_i2Buffer((int)port, &num);
524 
525  if (ls==NULL) lsdp = get_sdp_body_list(lp);
526  else lsdp = ls;
527 
528  if (del_candi) {
529  tList* pm = lsdp;
530  while (pm!=NULL) {
531  if (pm->ldat.key.buf!=NULL && !strcasecmp("a", (char*)pm->ldat.key.buf)) {
532  if (pm->ldat.val.buf!=NULL && !strncasecmp("candidate ", (char*)pm->ldat.val.buf, 10)) {
533  pm = del_tList_node(&pm);
534  }
535  else pm = pm->next;
536  }
537  else pm = pm->next;
538  }
539  }
540 
541  set_protocol_header_item(lsdp, (char*)"o", 1, ' ', 6, host);
542  set_protocol_header_item(lsdp, (char*)"c", 1, ' ', 3, host);
543  set_protocol_header_item(lsdp, (char*)"m", 1, ' ', 2, (char*)num.buf);
544 
545  sdp = restore_sdp_body(lsdp);
546  set_sip_contents(lp, sdp);
547 
548  if (ls==NULL) del_tList(&lsdp);
549  free_Buffer(&sdp);
550  free_Buffer(&num);
551 
552  return TRUE;
553 }
554 
555 
556 
558 // RTP
559 //
560 
573 unsigned short get_valid_rtp_pair_sockets(int min, int max, int* rtp, int* rtcp)
574 {
575  int i = 1;
576  int range, sock1, sock2, port;
577 
578  max = max - 1;
579  min = min + 1;
580 
581  range = max - min + 1;
582  port = ((rand()%range + min)/2)*2;
583 
584  sock1 = udp_server_socket(port, NULL); // RTP
585  sock2 = udp_server_socket(port+1, NULL); // RTCP
586  if (sock1<=0 || sock2<=0) {
587  if (sock1>0) socket_close(sock1);
588  if (sock2>0) socket_close(sock2);
589  sock1 = sock2 = 0;
590  }
591 
592  while(sock1==0 && i<range) {
593  port = port + 2;
594  if (port>max) port = ((port%max + min - 1)/2)*2;
595 
596  sock1 = udp_server_socket(port, NULL); // RTP
597  sock2 = udp_server_socket(port+1, NULL); // RTCP
598  if (sock1<=0 || sock2<=0) {
599  if (sock1>0) socket_close(sock1);
600  if (sock2>0) socket_close(sock2);
601  sock1 = sock2 = 0;
602  }
603  i = i + 2;
604  }
605 
606  if (sock1==0) {
607  port = 0;
608  *rtp = *rtcp =0;
609  }
610  else {
611  *rtp = sock1;
612  *rtcp = sock2;
613  }
614 
615  return (unsigned short)port;
616 }
617 
618 
619 
621 // Junk
622 
630 Buffer replace_sip_via(tList* lp, char* host, unsigned short port, int no)
631 {
632  Buffer buf = init_Buffer();
633 
634  if (lp==NULL || host==NULL || port==0) return buf;
635  if (no<=0) no = 1;
636 
637  buf = search_protocol_header_item(lp, (char*)"Via", no, ' ', 2);
638  if (buf.buf!=NULL) {
639  int i = 0;
640  char hostport[LBUF];
641 
642  while (buf.buf[i]!=';' && buf.buf[i]!='\0') i++;
643  if (buf.buf[i]!='\0') buf.buf[i] = '\0';
644 
645  snprintf(hostport, LBUF, "%s:%d", host, port);
646  hostport[LBUF-1] = '\0'; // to make sure
647 
648  replace_protocol_header(lp, (char*)"Via", 1, (char*)buf.buf, hostport);
649  }
650 
651  return buf;
652 }
653 
654 
658 int replace_sip_contact_dstipport(tList* lp, char* ipaddr, unsigned short port)
659 {
660  int i;
661  char dstip[] = "dstip=";
662  char dstport[] = "dstport=";
663  char* ip = NULL;
664  char* pt = NULL;
665 
666  Buffer frip, frpt;
667  Buffer toip, topt;
668 
669  if (lp==NULL || ipaddr==NULL || port==0) return FALSE;
670 
671  tList* lc = strncasecmp_tList(lp, (char*)"Contact", 0, 1);
672  if (lc==NULL || lc->ldat.val.buf==NULL) return FALSE;
673 
674  frip = search_protocol_header_partvalue(lp, (char*)"Contact", dstip, 1);
675  frpt = search_protocol_header_partvalue(lp, (char*)"Contact", dstport, 1);
676  if (frip.buf==NULL || frpt.buf==NULL) {
677  free_Buffer(&frip);
678  free_Buffer(&frpt);
679  return FALSE;
680  }
681 
682  i = 0;
683  ip = strstr((char*)frip.buf, dstip);
684  while (ip[i]!='\0' && ip[i]!=';' && ip[i]!='"') i++;
685  ip[i] = '\0';
686 
687  i = 0;
688  pt = strstr((char*)frpt.buf, dstport);
689  while (pt[i]!='\0' && pt[i]!=';' && pt[i]!='"') i++;
690  pt[i] = '\0';
691 
692  toip = make_Buffer(LBUF);
693  topt = make_Buffer(LBUF);
694 
695  copy_s2Buffer(dstip, &toip);
696  cat_s2Buffer (ipaddr, &toip);
697  copy_s2Buffer(dstport, &topt);
698  cat_i2Buffer (port, &topt);
699 
700  Buffer buftemp = replace_sBuffer(lc->ldat.val, ip, (char*)toip.buf);
701  Buffer nwcntct = replace_sBuffer(buftemp, pt, (char*)topt.buf);
702 
703  free_Buffer(&lc->ldat.val);
704  lc->ldat.val = nwcntct;
705 
706  free_Buffer(&frip);
707  free_Buffer(&frpt);
708  free_Buffer(&toip);
709  free_Buffer(&topt);
710  free_Buffer(&buftemp);
711 
712  return TRUE;
713 }
714 
Buffer make_Buffer(int sz)
Buffer型変数のバッファ部をつくり出す.
Definition: buffer.c:71
void free_Buffer(Buffer *buf)
Buffer型変数のバッファ部を解放する
Definition: buffer.c:128
Buffer init_Buffer()
初期化したBuffer型変数を返す.
Definition: buffer.c:47
Buffer dup_Buffer(Buffer buf)
Buffer型変数のコピーをつくる.
Definition: buffer.c:211
int copy_i2Buffer(int src, Buffer *dst)
整数 srcを文字列に変換して,dstへ copyする.
Definition: buffer.c:664
int cat_i2Buffer(int src, Buffer *dst)
整数 srcを文字列に変換して,dstへ catする.
Definition: buffer.c:678
Buffer cawk_Buffer(Buffer str, char cc, int n)
Buffer文字列に対する(変形の)awk.
Definition: buffer.c:1094
#define copy_s2Buffer(src, dst)
copy_b2Buffer()
Definition: buffer.h:108
#define replace_sBuffer(buf, f, t)
replace_sBuffer()
Definition: buffer.h:175
#define cat_s2Buffer(src, dst)
cat_b2Buffer()
Definition: buffer.h:122
#define make_Buffer_bystr(str)
set_Buffer()
Definition: buffer.h:57
#define OFF
Definition: common.h:231
#define LBUF
Definition: common.h:146
#define TRUE
Definition: common.h:226
#define FALSE
Definition: common.h:223
#define LEN_INT
log 2^64 + '\0' + 1(予備)
Definition: common.h:171
#define ON
Definition: common.h:230
unsigned char ** buf
Definition: jpeg_tool.h:96
int socket_close(int sofd)
call shutdown(), close()
Definition: network.c:1022
#define udp_server_socket(p, a)
Definition: network.h:82
Buffer search_protocol_header_item(tList *list, char *key, int no, char deli, int nm)
Definition: protocol.c:408
void set_protocol_contents(tList *list, Buffer contents)
Definition: protocol.c:132
Buffer search_protocol_header(tList *list, char *key, int no)
Definition: protocol.c:372
int set_protocol_header(tList *list, char *key, char *value, int no, int add_mode)
Definition: protocol.c:574
Buffer restore_protocol_header(tList *list, char *deli, int mode, int *hdsz)
Definition: protocol.c:55
Buffer restore_protocol_contents(tList *list)
Definition: protocol.c:109
tList * get_protocol_header_list(Buffer buf, char deli, int fstline, int rcntnt)
Definition: protocol.c:34
Buffer search_protocol_header_partvalue(tList *list, char *key, char *data, int no)
Definition: protocol.c:500
#define replace_protocol_header(list, key, no, srcval, value)
Definition: protocol.h:90
#define HDLIST_FIRST_LINE_KEY
Definition: protocol.h:31
#define set_protocol_header_item(list, key, no, deli, nm, value)
Definition: protocol.h:123
Buffer restore_sdp_body(tList *ls)
Definition: sip_tool.c:488
void insert_sip_via(tList *lp, char *host, unsigned short port, char *branch, int add_mode)
Definition: sip_tool.c:130
void insert_sip_record_route(tList *lp, char *host, unsigned short port, int add_mode)
Definition: sip_tool.c:205
void replace_sip_contact(tList *lp, char *host, unsigned short port)
Definition: sip_tool.c:308
void set_max_forwards(tList *lp, int nm)
Definition: sip_tool.c:444
void del_sip_record_route(tList *lp, char *host, unsigned short port)
Definition: sip_tool.c:256
int replace_sip_contact_dstipport(tList *lp, char *ipaddr, unsigned short port)
Definition: sip_tool.c:658
int replace_sdp_invite_addr(tList *lp, tList *ls, char *host, unsigned short port, int del_candi)
Definition: sip_tool.c:515
void del_sip_record_route_all(tList *lp)
Definition: sip_tool.c:288
void set_sip_contents(tList *lp, Buffer sdp)
Definition: sip_tool.c:52
Buffer get_sip_domain(Buffer sipuri)
Definition: sip_tool.c:392
Buffer replace_sip_via(tList *lp, char *host, unsigned short port, int no)
Definition: sip_tool.c:630
Buffer get_sip_via_address(tList *lp, int no)
Definition: sip_tool.c:83
unsigned short get_valid_rtp_pair_sockets(int min, int max, int *rtp, int *rtcp)
Definition: sip_tool.c:573
Buffer get_sip_contact_uri(tList *lp)
Definition: sip_tool.c:365
int get_max_forwards(tList *lp)
Definition: sip_tool.c:424
void del_sip_via(tList *lp, char *host, unsigned short port)
Definition: sip_tool.c:171
tList * get_sdp_body_list(tList *lp)
Definition: sip_tool.c:473
SIP用ライブラリヘッダ
#define SIP_NOMAXFORWARDS
Definition: sip_tool.h:45
Definition: buffer.h:35
int vldsz
データの長さ.バイナリデータの場合も使用可能.文字列の場合は 0x00 を含まない.
Definition: buffer.h:37
unsigned char * buf
バッファの先頭へのポインタ.str[bufsz]は必ず 0x00となる.
Definition: buffer.h:39
tList * strncasecmp_tList(tList *pl, const char *key, int len, int no)
char* 型変数によるノードのサーチ.大文字小文字を無視する
Definition: tlist.c:1094
tList * del_tList_node(tList **node)
リスト用のノードを削除.
Definition: tlist.c:270
tList * strncmp_tList(tList *pl, const char *key, int len, int no)
char* 型変数によるノードのサーチ.
Definition: tlist.c:1056
tList * del_tList(tList **pp)
指定したリストノード以降のリストを削除.
Definition: tlist.c:735
#define add_tList_node_str(p, k, v)
add_tList_node_bystr()
Definition: tlist.h:142
char * strstrcase(const char *buf, const char *nd)
文字列 bufの中に文字列 ndがあるかどうかをチェックする.大文字小文字は区別しない.
Definition: tools.c:736
#define CHAR_CR
改行
Definition: tools.h:78
#define CHAR_LF
ラインフィード
Definition: tools.h:79
Buffer comp_hostport(char *host, unsigned short port)
ホスト名とポート番号から,"ホスト名:ポート番号" の文字列を生成する.
Definition: xtools.c:687