1 /**
2 * ip address family related structures
3 *
4 * Copyright (C) 2001-2003 FhG Fokus
5 *
6 * This file is part of Kamailio, a free SIP server.
7 *
8 * Kamailio is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version
12 *
13 * Kamailio is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22 /*!
23 * \file
24 * \brief Kamailio core :: ip address family related structures
25 * \ingroup core
26 * Module: \ref core
27 */
28
29 #ifndef ip_addr_h
30 #define ip_addr_h
31
32 #include <string.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <netdb.h>
37 #include "str.h"
38 #include "compiler_opt.h"
39 #include "ut.h"
40
41
42 #include "dprint.h"
43
44 enum sip_protos { PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP,
45 PROTO_WS, PROTO_WSS, PROTO_OTHER };
46 #define PROTO_LAST PROTO_OTHER
47
48 #ifdef USE_COMP
49 enum comp_methods { COMP_NONE, COMP_SIGCOMP, COMP_SERGZ };
50 #endif
51
52 #ifndef INADDR_LOOPBACK
53 #define INADDR_LOOPBACK (u_int32_t)0x7f000001
54 #endif
55
56 typedef struct ip_addr {
57 unsigned int af; /* address family: AF_INET6 or AF_INET */
58 unsigned int len; /* address len, 16 or 4 */
59
60 /* 64 bits aligned address */
61 union {
62 unsigned long addrl[16/sizeof(long)]; /* long format*/
63 unsigned int addr32[4];
64 unsigned short addr16[8];
65 unsigned char addr[16];
66 }u;
67 } ip_addr_t;
68
69 typedef struct net {
70 struct ip_addr ip;
71 struct ip_addr mask;
72 } sr_net_t;
73
74 union sockaddr_union{
75 struct sockaddr s;
76 struct sockaddr_in sin;
77 struct sockaddr_in6 sin6;
78 struct sockaddr_storage sas;
79 };
80
81
82 enum si_flags { SI_NONE=0, SI_IS_IP=1, SI_IS_LO=2, SI_IS_MCAST=4,
83 SI_IS_ANY=8, SI_IS_MHOMED=16 };
84
85 typedef struct addr_info {
86 str name; /* name - eg.: foo.bar or 10.0.0.1 */
87 struct ip_addr address; /*ip address */
88 str address_str; /*ip address converted to string -- optimization*/
89 enum si_flags flags; /* SI_IS_IP | SI_IS_LO | SI_IS_MCAST */
90 union sockaddr_union su;
91 struct addr_info* next;
92 struct addr_info* prev;
93 } addr_info_t;
94
95
96 typedef struct advertise_info {
97 str name; /* name - eg.: foo.bar or 10.0.0.1 */
98 unsigned short port_no; /* port number */
99 short port_pad; /* padding field */
100 str port_no_str; /* port number converted to string -- optimization*/
101 str address_str; /*ip address converted to string -- optimization*/
102 struct ip_addr address; /* ip address */
103 str sock_str; /* Socket proto, ip, and port as string */
104 } advertise_info_t;
105
106 typedef struct socket_info {
107 int socket;
108 str name; /* name - eg.: foo.bar or 10.0.0.1 */
109 struct ip_addr address; /* ip address */
110 str address_str; /*ip address converted to string -- optimization*/
111 str port_no_str; /* port number converted to string -- optimization*/
112 enum si_flags flags; /* SI_IS_IP | SI_IS_LO | SI_IS_MCAST */
113 union sockaddr_union su;
114 struct socket_info* next;
115 struct socket_info* prev;
116 unsigned short port_no; /* port number */
117 char proto; /* tcp or udp*/
118 char proto_pad0; /* padding field */
119 short proto_pad1; /* padding field */
120 str sock_str; /* Socket proto, ip, and port as string */
121 struct addr_info* addr_info_lst; /* extra addresses (e.g. SCTP mh) */
122 int workers; /* number of worker processes for this socket */
123 int workers_tcpidx; /* index of workers in tcp children array */
124 str sockname; /* socket name given in config listen value */
125 struct advertise_info useinfo; /* details to be used in SIP msg */
126 #ifdef USE_MCAST
127 str mcast; /* name of interface that should join multicast group*/
128 #endif /* USE_MCAST */
129 } socket_info_t;
130
131
132 /* send flags */
133 #define SND_F_FORCE_CON_REUSE 1 /* reuse an existing connection or fail */
134 #define SND_F_CON_CLOSE 2 /* close the connection after sending */
135 #define SND_F_FORCE_SOCKET 4 /* send socket in dst is forced */
136
137 typedef struct snd_flags {
138 unsigned short f; /* snd flags */
139 unsigned short blst_imask; /* blacklist ignore mask */
140 } snd_flags_t;
141
142
143 typedef struct receive_info {
144 struct ip_addr src_ip;
145 struct ip_addr dst_ip;
146 unsigned short src_port; /* host byte order */
147 unsigned short dst_port; /* host byte order */
148 int proto_reserved1; /* tcp stores the connection id here */
149 int proto_reserved2;
150 union sockaddr_union src_su; /* useful for replies*/
151 struct socket_info* bind_address; /* sock_info structure on which
152 * the msg was received */
153 char proto;
154 #ifdef USE_COMP
155 char proto_pad0; /* padding field */
156 short comp; /* compression */
157 #else
158 char proto_pad0; /* padding field */
159 short proto_pad1; /* padding field */
160 #endif
161 /* no need for dst_su yet */
162 } receive_info_t;
163
164
165 typedef struct dest_info {
166 struct socket_info* send_sock;
167 union sockaddr_union to;
168 int id; /* tcp stores the connection id here */
169 snd_flags_t send_flags;
170 char proto;
171 #ifdef USE_COMP
172 char proto_pad0; /* padding field */
173 short comp;
174 #else
175 char proto_pad0; /* padding field */
176 short proto_pad1; /* padding field */
177 #endif
178 } dest_info_t;
179
180
181 typedef struct ksr_coninfo {
182 ip_addr_t src_ip;
183 ip_addr_t dst_ip;
184 unsigned short src_port; /* host byte order */
185 unsigned short dst_port; /* host byte order */
186 int proto;
187 socket_info_t *csocket;
188 } ksr_coninfo_t;
189
190 typedef struct sr_net_info {
191 str data;
192 receive_info_t* rcv;
193 dest_info_t* dst;
194 } sr_net_info_t;
195
196 sr_net_info_t *ksr_evrt_rcvnetinfo_get(void);
197
198 #define SND_FLAGS_INIT(sflags) \
199 do{ \
200 (sflags)->f=0; \
201 (sflags)->blst_imask=0; \
202 }while(0)
203
204
205 #define SND_FLAGS_OR(dst, src1, src2) \
206 do{ \
207 (dst)->f = (src1)->f | (src2)->f; \
208 (dst)->blst_imask = (src1)->blst_imask | (src2)->blst_imask; \
209 }while(0)
210
211
212 #define SND_FLAGS_AND(dst, src1, src2) \
213 do{ \
214 (dst)->f = (src1)->f & (src2)->f; \
215 (dst)->blst_imask = (src1)->blst_imask & (src2)->blst_imask; \
216 }while(0)
217
218
219 /* list of names for multi-homed sockets that need to bind on
220 * multiple addresses in the same time (sctp ) */
221 typedef struct name_lst {
222 char* name;
223 struct name_lst* next;
224 int flags;
225 } name_lst_t;
226
227
228 typedef struct socket_id {
229 struct name_lst* addr_lst; /* address list, the first one must
230 * be present and is the main one
231 * (in case of multihoming sctp) */
232 int flags;
233 int proto;
234 int port;
235 struct socket_id* next;
236 } socket_id_t;
237
238
239 /* len of the sockaddr */
240 #ifdef HAVE_SOCKADDR_SA_LEN
241 #define sockaddru_len(su) ((su).s.sa_len)
242 #else
243 #define sockaddru_len(su) \
244 (((su).s.sa_family==AF_INET6)?sizeof(struct sockaddr_in6):\
245 sizeof(struct sockaddr_in))
246 #endif /* HAVE_SOCKADDR_SA_LEN*/
247
248 /* inits an ip_addr with the addr. info from a hostent structure
249 * ip = struct ip_addr*
250 * he= struct hostent*
251 */
252 #define hostent2ip_addr(ip, he, addr_no) \
253 do{ \
254 (ip)->af=(he)->h_addrtype; \
255 (ip)->len=(he)->h_length; \
256 memcpy((ip)->u.addr, (he)->h_addr_list[(addr_no)], (ip)->len); \
257 }while(0)
258
259
260 /* gets the protocol family corresponding to a specific address family
261 * ( PF_INET - AF_INET, PF_INET6 - AF_INET6, af for others)
262 */
263 #define AF2PF(af) (((af)==AF_INET)?PF_INET:((af)==AF_INET6)?PF_INET6:(af))
264
265
266 struct net* mk_new_net(struct ip_addr* ip, struct ip_addr* mask);
267 struct net* mk_new_net_bitlen(struct ip_addr* ip, unsigned int bitlen);
268 int mk_net(struct net* n, struct ip_addr* ip, struct ip_addr* mask);
269 int mk_net_bitlen(struct net* n, struct ip_addr* ip, unsigned int bitlen);
270 int mk_net_str(struct net* dst, str* s);
271
272 void print_ip(char* prefix, struct ip_addr* ip, char* suffix);
273 void stdout_print_ip(struct ip_addr* ip);
274 void print_net(struct net* net);
275
276 char* get_proto_name(unsigned int proto);
277 #define proto2a get_proto_name
278
279 int get_valid_proto_string(unsigned int iproto, int utype, int vtype,
280 str *sproto);
281
282 #ifdef USE_MCAST
283 /* Returns 1 if the given address is a multicast address */
284 int is_mcast(struct ip_addr* ip);
285 #endif /* USE_MCAST */
286
287 /* returns 1 if the given ip address is INADDR_ANY or IN6ADDR_ANY,
288 * 0 otherwise */
ip_addr_any(struct ip_addr * ip)289 inline static int ip_addr_any(struct ip_addr* ip)
290 {
291 int r;
292 int l;
293
294 l=ip->len/4;
295 for (r=0; r<l; r++)
296 if (ip->u.addr32[r]!=0)
297 return 0;
298 return 1;
299 }
300
301
302 /* returns 1 if the given ip address is a loopback address
303 * 0 otherwise */
ip_addr_loopback(struct ip_addr * ip)304 inline static int ip_addr_loopback(struct ip_addr* ip)
305 {
306 if (ip->af==AF_INET)
307 return ip->u.addr32[0]==htonl(INADDR_LOOPBACK);
308 else if (ip->af==AF_INET6)
309 return IN6_IS_ADDR_LOOPBACK((struct in6_addr*)ip->u.addr32);
310 return 0;
311 }
312
313
314 /* creates an ANY ip_addr (filled with 0, af and len properly set) */
ip_addr_mk_any(int af,struct ip_addr * ip)315 inline static void ip_addr_mk_any(int af, struct ip_addr* ip)
316 {
317 ip->af=af;
318 if (likely(af==AF_INET)){
319 ip->len=4;
320 ip->u.addr32[0]=0;
321 }
322 else{
323 ip->len=16;
324 #if (defined (ULONG_MAX) && ULONG_MAX > 4294967295) || defined LP64
325 /* long is 64 bits */
326 ip->u.addrl[0]=0;
327 ip->u.addrl[1]=0;
328 #else
329 ip->u.addr32[0]=0;
330 ip->u.addr32[1]=0;
331 ip->u.addr32[2]=0;
332 ip->u.addr32[3]=0;
333 #endif /* ULONG_MAX */
334 }
335 }
336
337
338 /* returns 1 if ip & net.mask == net.ip ; 0 otherwise & -1 on error
339 * [ diff. address families ]) */
matchnet(struct ip_addr * ip,struct net * net)340 inline static int matchnet(struct ip_addr* ip, struct net* net)
341 {
342 unsigned int r;
343
344 if (ip->af == net->ip.af){
345 for(r=0; r<ip->len/4; r++){ /* ipv4 & ipv6 addresses are
346 * all multiple of 4*/
347 if ((ip->u.addr32[r]&net->mask.u.addr32[r])
348 !=net->ip.u.addr32[r]) {
349 return 0;
350 }
351 }
352 return 1;
353 };
354 return -1;
355 }
356
357
358 /* inits an ip_addr pointer from a sockaddr structure*/
sockaddr2ip_addr(struct ip_addr * ip,struct sockaddr * sa)359 static inline void sockaddr2ip_addr(struct ip_addr* ip, struct sockaddr* sa)
360 {
361 switch(sa->sa_family){
362 case AF_INET:
363 ip->af=AF_INET;
364 ip->len=4;
365 memcpy(ip->u.addr, &((struct sockaddr_in*)sa)->sin_addr, 4);
366 break;
367 case AF_INET6:
368 ip->af=AF_INET6;
369 ip->len=16;
370 memcpy(ip->u.addr, &((struct sockaddr_in6*)sa)->sin6_addr, 16);
371 break;
372 default:
373 LM_CRIT("unknown address family %d\n", sa->sa_family);
374 }
375 }
376
377
378 /* compare 2 ip_addrs (both args are pointers)*/
379 #define ip_addr_cmp(ip1, ip2) \
380 (((ip1)->af==(ip2)->af)&& \
381 (memcmp((ip1)->u.addr, (ip2)->u.addr, (ip1)->len)==0))
382
383
384 /* compare 2 sockaddr_unions */
su_cmp(const union sockaddr_union * s1,const union sockaddr_union * s2)385 static inline int su_cmp(const union sockaddr_union* s1,
386 const union sockaddr_union* s2)
387 {
388 if (s1->s.sa_family!=s2->s.sa_family) return 0;
389 switch(s1->s.sa_family){
390 case AF_INET:
391 return (s1->sin.sin_port==s2->sin.sin_port)&&
392 (memcmp(&s1->sin.sin_addr, &s2->sin.sin_addr, 4)==0);
393 case AF_INET6:
394 return (s1->sin6.sin6_port==s2->sin6.sin6_port)&&
395 (memcmp(&s1->sin6.sin6_addr, &s2->sin6.sin6_addr, 16)==0);
396 default:
397 LM_CRIT("unknown address family %d\n", s1->s.sa_family);
398 return 0;
399 }
400 }
401
402
403 /* gets the port number (host byte order) */
su_getport(const union sockaddr_union * su)404 static inline unsigned short su_getport(const union sockaddr_union* su)
405 {
406 switch(su->s.sa_family){
407 case AF_INET:
408 return ntohs(su->sin.sin_port);
409 case AF_INET6:
410 return ntohs(su->sin6.sin6_port);
411 default:
412 LM_CRIT("unknown address family %d\n", su->s.sa_family);
413 return 0;
414 }
415 }
416
417
418 /* sets the port number (host byte order) */
su_setport(union sockaddr_union * su,unsigned short port)419 static inline void su_setport(union sockaddr_union* su, unsigned short port)
420 {
421 switch(su->s.sa_family){
422 case AF_INET:
423 su->sin.sin_port=htons(port);
424 break;
425 case AF_INET6:
426 su->sin6.sin6_port=htons(port);
427 break;
428 default:
429 LM_CRIT("unknown address family %d\n", su->s.sa_family);
430 }
431 }
432
433
434 /* inits an ip_addr pointer from a sockaddr_union ip address */
su2ip_addr(struct ip_addr * ip,union sockaddr_union * su)435 static inline void su2ip_addr(struct ip_addr* ip, union sockaddr_union* su)
436 {
437 switch(su->s.sa_family){
438 case AF_INET:
439 ip->af=AF_INET;
440 ip->len=4;
441 memcpy(ip->u.addr, &su->sin.sin_addr, 4);
442 break;
443 case AF_INET6:
444 ip->af=AF_INET6;
445 ip->len=16;
446 memcpy(ip->u.addr, &su->sin6.sin6_addr, 16);
447 break;
448 default:
449 LM_CRIT("unknown address family %d\n", su->s.sa_family);
450 memset(ip, 0, sizeof(ip_addr_t));
451 }
452 }
453
454
455 /* ip_addr2su -> the same as init_su*/
456 #define ip_addr2su init_su
457
458 /* inits a struct sockaddr_union from a struct ip_addr and a port no
459 * returns 0 if ok, -1 on error (unknown address family)
460 * the port number is in host byte order */
init_su(union sockaddr_union * su,struct ip_addr * ip,unsigned short port)461 static inline int init_su( union sockaddr_union* su,
462 struct ip_addr* ip,
463 unsigned short port )
464 {
465 memset(su, 0, sizeof(union sockaddr_union));/*needed on freebsd*/
466 su->s.sa_family=ip->af;
467 switch(ip->af){
468 case AF_INET6:
469 memcpy(&su->sin6.sin6_addr, ip->u.addr, ip->len);
470 #ifdef HAVE_SOCKADDR_SA_LEN
471 su->sin6.sin6_len=sizeof(struct sockaddr_in6);
472 #endif
473 su->sin6.sin6_port=htons(port);
474 break;
475 case AF_INET:
476 memcpy(&su->sin.sin_addr, ip->u.addr, ip->len);
477 #ifdef HAVE_SOCKADDR_SA_LEN
478 su->sin.sin_len=sizeof(struct sockaddr_in);
479 #endif
480 su->sin.sin_port=htons(port);
481 break;
482 default:
483 LM_CRIT("unknown address family %d\n", ip->af);
484 return -1;
485 }
486 return 0;
487 }
488
489
490 /* inits a struct sockaddr_union from a struct hostent, an address index in
491 * the hostent structure and a port no. (host byte order)
492 * WARNING: no index overflow checks!
493 * returns 0 if ok, -1 on error (unknown address family) */
hostent2su(union sockaddr_union * su,struct hostent * he,unsigned int idx,unsigned short port)494 static inline int hostent2su( union sockaddr_union* su,
495 struct hostent* he,
496 unsigned int idx,
497 unsigned short port )
498 {
499 memset(su, 0, sizeof(union sockaddr_union)); /*needed on freebsd*/
500 su->s.sa_family=he->h_addrtype;
501 switch(he->h_addrtype){
502 case AF_INET6:
503 memcpy(&su->sin6.sin6_addr, he->h_addr_list[idx], he->h_length);
504 #ifdef HAVE_SOCKADDR_SA_LEN
505 su->sin6.sin6_len=sizeof(struct sockaddr_in6);
506 #endif
507 su->sin6.sin6_port=htons(port);
508 break;
509 case AF_INET:
510 memcpy(&su->sin.sin_addr, he->h_addr_list[idx], he->h_length);
511 #ifdef HAVE_SOCKADDR_SA_LEN
512 su->sin.sin_len=sizeof(struct sockaddr_in);
513 #endif
514 su->sin.sin_port=htons(port);
515 break;
516 default:
517 LM_CRIT("unknown address family %d\n", he->h_addrtype);
518 return -1;
519 }
520 return 0;
521 }
522
523
524 /* maximum size of a str returned by ip_addr2str */
525 #define IP6_MAX_STR_SIZE 39 /*1234:5678:9012:3456:7890:1234:5678:9012*/
526 #define IP4_MAX_STR_SIZE 15 /*123.456.789.012*/
527
528 /* converts a raw ipv6 addr (16 bytes) to ascii */
ip6tosbuf(unsigned char * ip6,char * buff,int len)529 static inline int ip6tosbuf(unsigned char* ip6, char* buff, int len)
530 {
531 int offset;
532 register unsigned char a,b,c;
533 register unsigned char d;
534 register unsigned short hex4;
535 int r;
536
537 #define HEXDIG(x) (((x)>=10)?(x)-10+'A':(x)+'0')
538
539 offset=0;
540 if (unlikely(len<IP6_MAX_STR_SIZE))
541 return 0;
542 for(r=0;r<7;r++){
543 hex4=((unsigned char)ip6[r*2]<<8)+(unsigned char)ip6[r*2+1];
544 a=hex4>>12;
545 b=(hex4>>8)&0xf;
546 c=(hex4>>4)&0xf;
547 d=hex4&0xf;
548 if (a){
549 buff[offset]=HEXDIG(a);
550 buff[offset+1]=HEXDIG(b);
551 buff[offset+2]=HEXDIG(c);
552 buff[offset+3]=HEXDIG(d);
553 buff[offset+4]=':';
554 offset+=5;
555 }else if(b){
556 buff[offset]=HEXDIG(b);
557 buff[offset+1]=HEXDIG(c);
558 buff[offset+2]=HEXDIG(d);
559 buff[offset+3]=':';
560 offset+=4;
561 }else if(c){
562 buff[offset]=HEXDIG(c);
563 buff[offset+1]=HEXDIG(d);
564 buff[offset+2]=':';
565 offset+=3;
566 }else{
567 buff[offset]=HEXDIG(d);
568 buff[offset+1]=':';
569 offset+=2;
570 }
571 }
572 /* last int16*/
573 hex4=((unsigned char)ip6[r*2]<<8)+(unsigned char)ip6[r*2+1];
574 a=hex4>>12;
575 b=(hex4>>8)&0xf;
576 c=(hex4>>4)&0xf;
577 d=hex4&0xf;
578 if (a){
579 buff[offset]=HEXDIG(a);
580 buff[offset+1]=HEXDIG(b);
581 buff[offset+2]=HEXDIG(c);
582 buff[offset+3]=HEXDIG(d);
583 offset+=4;
584 }else if(b){
585 buff[offset]=HEXDIG(b);
586 buff[offset+1]=HEXDIG(c);
587 buff[offset+2]=HEXDIG(d);
588 offset+=3;
589 }else if(c){
590 buff[offset]=HEXDIG(c);
591 buff[offset+1]=HEXDIG(d);
592 offset+=2;
593 }else{
594 buff[offset]=HEXDIG(d);
595 offset+=1;
596 }
597
598 return offset;
599 }
600
601
602 /* converts a raw ipv4 addr (4 bytes) to ascii */
ip4tosbuf(unsigned char * ip4,char * buff,int len)603 static inline int ip4tosbuf(unsigned char* ip4, char* buff, int len)
604 {
605 int offset;
606 register unsigned char a,b,c;
607 int r;
608
609 offset=0;
610 if (unlikely(len<IP4_MAX_STR_SIZE))
611 return 0;
612 for(r=0;r<3;r++){
613 a=(unsigned char)ip4[r]/100;
614 c=(unsigned char)ip4[r]%10;
615 b=(unsigned char)ip4[r]%100/10;
616 if (a){
617 buff[offset]=a+'0';
618 buff[offset+1]=b+'0';
619 buff[offset+2]=c+'0';
620 buff[offset+3]='.';
621 offset+=4;
622 }else if (b){
623 buff[offset]=b+'0';
624 buff[offset+1]=c+'0';
625 buff[offset+2]='.';
626 offset+=3;
627 }else{
628 buff[offset]=c+'0';
629 buff[offset+1]='.';
630 offset+=2;
631 }
632 }
633 /* last number */
634 a=(unsigned char)ip4[r]/100;
635 c=(unsigned char)ip4[r]%10;
636 b=(unsigned char)ip4[r]%100/10;
637 if (a){
638 buff[offset]=a+'0';
639 buff[offset+1]=b+'0';
640 buff[offset+2]=c+'0';
641 offset+=3;
642 }else if (b){
643 buff[offset]=b+'0';
644 buff[offset+1]=c+'0';
645 offset+=2;
646 }else{
647 buff[offset]=c+'0';
648 offset+=1;
649 }
650
651 return offset;
652 }
653
654
655 /* fast ip_addr -> string converter;
656 * returns number of bytes written in buf on success, <=0 on error
657 * The buffer must have enough space to hold the maximum size ip address
658 * of the corresponding address (see IP[46] above) or else the function
659 * will return error (no detailed might fit checks are made, for example
660 * if len==7 the function will fail even for 1.2.3.4).
661 */
ip_addr2sbuf(struct ip_addr * ip,char * buff,int len)662 static inline int ip_addr2sbuf(struct ip_addr* ip, char* buff, int len)
663 {
664 switch(ip->af){
665 case AF_INET6:
666 return ip6tosbuf(ip->u.addr, buff, len);
667 break;
668 case AF_INET:
669 return ip4tosbuf(ip->u.addr, buff, len);
670 break;
671 default:
672 LM_CRIT("unknown address family %d\n", ip->af);
673 return 0;
674 }
675 }
676
677 /* same as ip_addr2sbuf, but with [ ] around IPv6 addresses */
ip_addr2sbufz(struct ip_addr * ip,char * buff,int len)678 static inline int ip_addr2sbufz(struct ip_addr* ip, char* buff, int len)
679 {
680 char *p;
681 int sz;
682
683 p = buff;
684 switch(ip->af){
685 case AF_INET6:
686 *p++ = '[';
687 sz = ip6tosbuf(ip->u.addr, p, len-2);
688 p += sz;
689 *p++ = ']';
690 *p=0;
691 return sz + 2;
692 break;
693 case AF_INET:
694 return ip4tosbuf(ip->u.addr, buff, len);
695 break;
696 default:
697 LM_CRIT("unknown address family %d\n", ip->af);
698 return 0;
699 }
700 }
701
702 /* maximum size of a str returned by ip_addr2a (including \0) */
703 #define IP_ADDR_MAX_STR_SIZE (IP6_MAX_STR_SIZE+1) /* ip62ascii + \0*/
704 #define IP_ADDR_MAX_STRZ_SIZE (IP6_MAX_STR_SIZE+3) /* ip62ascii + [ + ] + \0*/
705 /* fast ip_addr -> string converter;
706 * it uses an internal buffer
707 */
ip_addr2a(struct ip_addr * ip)708 static inline char* ip_addr2a(struct ip_addr* ip)
709 {
710 static char buff[IP_ADDR_MAX_STR_SIZE];
711 int len;
712
713 len=ip_addr2sbuf(ip, buff, sizeof(buff)-1);
714 buff[len]=0;
715
716 return buff;
717 }
718
719
720 /* full address in text representation, including [] for ipv6 */
ip_addr2strz(struct ip_addr * ip)721 static inline char* ip_addr2strz(struct ip_addr* ip)
722 {
723
724 static char buff[IP_ADDR_MAX_STRZ_SIZE];
725 char *p;
726 int len;
727
728 p = buff;
729 if(ip->af==AF_INET6) {
730 *p++ = '[';
731 }
732 len=ip_addr2sbuf(ip, p, sizeof(buff)-3);
733 p += len;
734 if(ip->af==AF_INET6) {
735 *p++ = ']';
736 }
737 *p=0;
738
739 return buff;
740 }
741
742 #define SU2A_MAX_STR_SIZE (IP6_MAX_STR_SIZE + 2 /* [] */+\
743 1 /* : */ + USHORT2SBUF_MAX_LEN + 1 /* \0 */)
744
745 /* returns an asciiz string containing the ip and the port
746 * (<ip_addr>:port or [<ipv6_addr>]:port)
747 */
su2a(union sockaddr_union * su,int su_len)748 static inline char* su2a(union sockaddr_union* su, int su_len)
749 {
750 static char buf[SU2A_MAX_STR_SIZE];
751 int offs;
752
753 if (unlikely(su->s.sa_family==AF_INET6)){
754 if (unlikely(su_len<sizeof(su->sin6)))
755 return "<addr. error>";
756 buf[0]='[';
757 offs=1+ip6tosbuf((unsigned char*)su->sin6.sin6_addr.s6_addr, &buf[1],
758 sizeof(buf)-4);
759 buf[offs]=']';
760 offs++;
761 }else
762 if (unlikely(su_len<sizeof(su->sin)))
763 return "<addr. error>";
764 else
765 offs=ip4tosbuf((unsigned char*)&su->sin.sin_addr, buf, sizeof(buf)-2);
766 buf[offs]=':';
767 offs+=1+ushort2sbuf(su_getport(su), &buf[offs+1], sizeof(buf)-(offs+1)-1);
768 buf[offs]=0;
769 return buf;
770 }
771
772 #define SUIP2A_MAX_STR_SIZE (IP6_MAX_STR_SIZE + 2 /* [] */ + 1 /* \0 */)
773 /* returns an asciiz string containing the ip
774 * (<ipv4_addr> or [<ipv6_addr>])
775 */
suip2a(union sockaddr_union * su,int su_len)776 static inline char* suip2a(union sockaddr_union* su, int su_len)
777 {
778 static char buf[SUIP2A_MAX_STR_SIZE];
779 int offs;
780
781 if (unlikely(su->s.sa_family==AF_INET6)){
782 if (unlikely(su_len<sizeof(su->sin6)))
783 return "<addr. error>";
784 buf[0]='[';
785 offs=1+ip6tosbuf((unsigned char*)su->sin6.sin6_addr.s6_addr, &buf[1],
786 IP6_MAX_STR_SIZE);
787 buf[offs]=']';
788 offs++;
789 }else
790 if (unlikely(su_len<sizeof(su->sin)))
791 return "<addr. error>";
792 else
793 offs=ip4tosbuf((unsigned char*)&su->sin.sin_addr, buf, IP4_MAX_STR_SIZE);
794 buf[offs]=0;
795 return buf;
796 }
797
798
799 /* converts an ip_addr structure to a hostent, returns pointer to internal
800 * statical structure */
ip_addr2he(str * name,struct ip_addr * ip)801 static inline struct hostent* ip_addr2he(str* name, struct ip_addr* ip)
802 {
803 static struct hostent he;
804 static char hostname[256];
805 static char* p_aliases[1];
806 static char* p_addr[2];
807 static char address[16];
808 int len;
809
810 p_aliases[0]=0; /* no aliases*/
811 p_addr[1]=0; /* only one address*/
812 p_addr[0]=address;
813 len = (name->len<255)?name->len:255;
814 memcpy(hostname, name->s, len);
815 hostname[len] = '\0';
816 if (ip->len>16) return 0;
817 memcpy(address, ip->u.addr, ip->len);
818
819 he.h_addrtype=ip->af;
820 he.h_length=ip->len;
821 he.h_addr_list=p_addr;
822 he.h_aliases=p_aliases;
823 he.h_name=hostname;
824 return &he;
825 }
826
827
828 /* init a dest_info structure */
829 #define init_dest_info(dst) \
830 do{ \
831 memset((dst), 0, sizeof(struct dest_info)); \
832 } while(0)
833
834
835 /* init a dest_info structure from a recv_info structure */
init_dst_from_rcv(struct dest_info * dst,struct receive_info * rcv)836 inline static void init_dst_from_rcv(struct dest_info* dst,
837 struct receive_info* rcv)
838 {
839 dst->send_sock=rcv->bind_address;
840 dst->to=rcv->src_su;
841 dst->id=rcv->proto_reserved1;
842 dst->proto=rcv->proto;
843 dst->send_flags.f=0;
844 dst->send_flags.blst_imask=0;
845 #ifdef USE_COMP
846 dst->comp=rcv->comp;
847 #endif
848 }
849
850
851 /**
852 * match ip address with net address and bitmask
853 * - return 0 on match, -1 otherwise
854 */
855 int ip_addr_match_net(ip_addr_t *iaddr, ip_addr_t *naddr, int mask);
856
857 int si_get_signaling_data(struct socket_info *si, str **addr, str **port);
858
859 #endif
860