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