1 /* $Id: ip_addr.h,v 1.35 2004/11/30 16:28:23 andrei Exp $
3 * ip address family related structures
5 * Copyright (C) 2001-2003 FhG Fokus
7 * This file is part of ser, a free SIP server.
9 * ser is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version
14 * For a license to use the ser software under conditions
15 * other than those described here, or to purchase support for this
16 * software, please contact iptel.org by e-mail at the following addresses:
19 * ser is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 * 2003-02-13 added struct dest_info (andrei)
32 * 2003-04-06 all ports are stored/passed in host byte order now (andrei)
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <netinet/in.h>
48 enum sip_protos { PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP };
52 unsigned int af; /* address family: AF_INET6 or AF_INET */
53 unsigned int len; /* address len, 16 or 4 */
55 /* 64 bits aligned address */
57 unsigned long addrl[16/sizeof(long)]; /* long format*/
58 unsigned int addr32[4];
59 unsigned short addr16[8];
60 unsigned char addr[16];
73 struct sockaddr_in sin;
75 struct sockaddr_in6 sin6;
81 enum si_flags { SI_NONE=0, SI_IS_IP=1, SI_IS_LO=2, SI_IS_MCAST=4 };
85 str name; /* name - eg.: foo.bar or 10.0.0.1 */
86 struct ip_addr address; /* ip address */
87 str address_str; /* ip address converted to string -- optimization*/
88 unsigned short port_no; /* port number */
89 str port_no_str; /* port number converted to string -- optimization*/
90 enum si_flags flags; /* SI_IS_IP | SI_IS_LO | SI_IS_MCAST */
91 union sockaddr_union su;
92 int proto; /* tcp or udp*/
93 struct socket_info* next;
94 struct socket_info* prev;
99 struct ip_addr src_ip;
100 struct ip_addr dst_ip;
101 unsigned short src_port; /* host byte order */
102 unsigned short dst_port; /* host byte order */
104 int proto_reserved1; /* tcp stores the connection id here */
106 union sockaddr_union src_su; /* useful for replies*/
107 struct socket_info* bind_address; /* sock_info structure on which
108 the msg was received*/
109 /* no need for dst_su yet */
115 int proto_reserved1; /* tcp stores the connection id here */
116 union sockaddr_union to;
117 struct socket_info* send_sock;
125 struct socket_id* next;
130 /* len of the sockaddr */
131 #ifdef HAVE_SOCKADDR_SA_LEN
132 #define sockaddru_len(su) ((su).s.sa_len)
135 #define sockaddru_len(su) \
136 (((su).s.sa_family==AF_INET6)?sizeof(struct sockaddr_in6):\
137 sizeof(struct sockaddr_in))
139 #define sockaddru_len(su) sizeof(struct sockaddr_in)
141 #endif /* HAVE_SOCKADDR_SA_LEN*/
143 /* inits an ip_addr with the addr. info from a hostent structure
144 * ip = struct ip_addr*
145 * he= struct hostent*
147 #define hostent2ip_addr(ip, he, addr_no) \
149 (ip)->af=(he)->h_addrtype; \
150 (ip)->len=(he)->h_length; \
151 memcpy((ip)->u.addr, (he)->h_addr_list[(addr_no)], (ip)->len); \
157 /* gets the protocol family corresponding to a specific address family
158 * ( PF_INET - AF_INET, PF_INET6 - AF_INET6, af for others)
161 #define AF2PF(af) (((af)==AF_INET)?PF_INET:((af)==AF_INET6)?PF_INET6:(af))
163 #define AF2PF(af) (((af)==AF_INET)?PF_INET:(af))
169 struct net* mk_net(struct ip_addr* ip, struct ip_addr* mask);
170 struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen);
172 void print_ip(char* prefix, struct ip_addr* ip, char* suffix);
173 void stdout_print_ip(struct ip_addr* ip);
174 void print_net(struct net* net);
177 /* Returns 1 if the given address is a multicast address */
178 int is_mcast(struct ip_addr* ip);
179 #endif /* USE_MCAST */
181 /* returns 1 if ip & net.mask == net.ip ; 0 otherwise & -1 on error
182 [ diff. address families ]) */
183 inline static int matchnet(struct ip_addr* ip, struct net* net)
189 if (ip->af == net->ip.af){
190 for(r=0; r<ip->len/4; r++){ /* ipv4 & ipv6 addresses are
192 if ((ip->u.addr32[r]&net->mask.u.addr32[r])!=
193 net->ip.u.addr32[r]){
205 /* inits an ip_addr pointer from a sockaddr structure*/
206 static inline void sockaddr2ip_addr(struct ip_addr* ip, struct sockaddr* sa)
208 switch(sa->sa_family){
212 memcpy(ip->u.addr, &((struct sockaddr_in*)sa)->sin_addr, 4);
218 memcpy(ip->u.addr, &((struct sockaddr_in6*)sa)->sin6_addr, 16);
222 LOG(L_CRIT, "sockaddr2ip_addr: BUG: unknown address family %d\n",
229 /* compare 2 ip_addrs (both args are pointers)*/
230 #define ip_addr_cmp(ip1, ip2) \
231 (((ip1)->af==(ip2)->af)&& \
232 (memcmp((ip1)->u.addr, (ip2)->u.addr, (ip1)->len)==0))
236 /* compare 2 sockaddr_unions */
237 static inline int su_cmp(union sockaddr_union* s1, union sockaddr_union* s2)
239 if (s1->s.sa_family!=s2->s.sa_family) return 0;
240 switch(s1->s.sa_family){
242 return (s1->sin.sin_port==s2->sin.sin_port)&&
243 (memcmp(&s1->sin.sin_addr, &s2->sin.sin_addr, 4)==0);
246 return (s1->sin6.sin6_port==s2->sin6.sin6_port)&&
247 (memcmp(&s1->sin6.sin6_addr, &s2->sin6.sin6_addr, 16)==0);
250 LOG(L_CRIT,"su_cmp: BUG: unknown address family %d\n",
258 /* gets the port number (host byte order) */
259 static inline unsigned short su_getport(union sockaddr_union* su)
261 switch(su->s.sa_family){
263 return ntohs(su->sin.sin_port);
266 return ntohs(su->sin6.sin6_port);
269 LOG(L_CRIT,"su_get_port: BUG: unknown address family %d\n",
277 /* sets the port number (host byte order) */
278 static inline void su_setport(union sockaddr_union* su, unsigned short port)
280 switch(su->s.sa_family){
282 su->sin.sin_port=htons(port);
286 su->sin6.sin6_port=htons(port);
290 LOG(L_CRIT,"su_set_port: BUG: unknown address family %d\n",
297 /* inits an ip_addr pointer from a sockaddr_union ip address */
298 static inline void su2ip_addr(struct ip_addr* ip, union sockaddr_union* su)
300 switch(su->s.sa_family){
304 memcpy(ip->u.addr, &su->sin.sin_addr, 4);
310 memcpy(ip->u.addr, &su->sin6.sin6_addr, 16);
314 LOG(L_CRIT,"su2ip_addr: BUG: unknown address family %d\n",
320 /* ip_addr2su -> the same as init_su*/
321 #define ip_addr2su init_su
323 /* inits a struct sockaddr_union from a struct ip_addr and a port no
324 * returns 0 if ok, -1 on error (unknown address family)
325 * the port number is in host byte order */
326 static inline int init_su( union sockaddr_union* su,
328 unsigned short port )
330 memset(su, 0, sizeof(union sockaddr_union));/*needed on freebsd*/
331 su->s.sa_family=ip->af;
335 memcpy(&su->sin6.sin6_addr, ip->u.addr, ip->len);
336 #ifdef HAVE_SOCKADDR_SA_LEN
337 su->sin6.sin6_len=sizeof(struct sockaddr_in6);
339 su->sin6.sin6_port=htons(port);
343 memcpy(&su->sin.sin_addr, ip->u.addr, ip->len);
344 #ifdef HAVE_SOCKADDR_SA_LEN
345 su->sin.sin_len=sizeof(struct sockaddr_in);
347 su->sin.sin_port=htons(port);
350 LOG(L_CRIT, "init_ss: BUG: unknown address family %d\n", ip->af);
358 /* inits a struct sockaddr_union from a struct hostent, an address index in
359 * the hostent structure and a port no. (host byte order)
360 * WARNING: no index overflow checks!
361 * returns 0 if ok, -1 on error (unknown address family) */
362 static inline int hostent2su( union sockaddr_union* su,
365 unsigned short port )
367 memset(su, 0, sizeof(union sockaddr_union)); /*needed on freebsd*/
368 su->s.sa_family=he->h_addrtype;
369 switch(he->h_addrtype){
372 memcpy(&su->sin6.sin6_addr, he->h_addr_list[idx], he->h_length);
373 #ifdef HAVE_SOCKADDR_SA_LEN
374 su->sin6.sin6_len=sizeof(struct sockaddr_in6);
376 su->sin6.sin6_port=htons(port);
380 memcpy(&su->sin.sin_addr, he->h_addr_list[idx], he->h_length);
381 #ifdef HAVE_SOCKADDR_SA_LEN
382 su->sin.sin_len=sizeof(struct sockaddr_in);
384 su->sin.sin_port=htons(port);
387 LOG(L_CRIT, "hostent2su: BUG: unknown address family %d\n",
394 /* maximum size of a str returned by ip_addr2a (including \0) */
395 #define IP_ADDR_MAX_STR_SIZE 40 /* 1234:5678:9012:3456:7890:1234:5678:9012\0 */
396 /* fast ip_addr -> string converter;
397 * it uses an internal buffer
399 static inline char* ip_addr2a(struct ip_addr* ip)
402 static char buff[IP_ADDR_MAX_STR_SIZE];
404 register unsigned char a,b,c;
406 register unsigned char d;
407 register unsigned short hex4;
410 #define HEXDIG(x) (((x)>=10)?(x)-10+'A':(x)+'0')
418 hex4=ntohs(ip->u.addr16[r]);
424 buff[offset]=HEXDIG(a);
425 buff[offset+1]=HEXDIG(b);
426 buff[offset+2]=HEXDIG(c);
427 buff[offset+3]=HEXDIG(d);
431 buff[offset]=HEXDIG(b);
432 buff[offset+1]=HEXDIG(c);
433 buff[offset+2]=HEXDIG(d);
437 buff[offset]=HEXDIG(c);
438 buff[offset+1]=HEXDIG(d);
442 buff[offset]=HEXDIG(d);
448 hex4=ntohs(ip->u.addr16[r]);
454 buff[offset]=HEXDIG(a);
455 buff[offset+1]=HEXDIG(b);
456 buff[offset+2]=HEXDIG(c);
457 buff[offset+3]=HEXDIG(d);
460 buff[offset]=HEXDIG(b);
461 buff[offset+1]=HEXDIG(c);
462 buff[offset+2]=HEXDIG(d);
465 buff[offset]=HEXDIG(c);
466 buff[offset+1]=HEXDIG(d);
469 buff[offset]=HEXDIG(d);
478 b=ip->u.addr[r]%100/10;
481 buff[offset+1]=b+'0';
482 buff[offset+2]=c+'0';
487 buff[offset+1]=c+'0';
499 b=ip->u.addr[r]%100/10;
502 buff[offset+1]=b+'0';
503 buff[offset+2]=c+'0';
507 buff[offset+1]=c+'0';
516 LOG(L_CRIT, "BUG: ip_addr2a: unknown address family %d\n",
526 /* converts an ip_addr structure to a hostent, returns pointer to internal
527 * statical structure */
528 static inline struct hostent* ip_addr2he(str* name, struct ip_addr* ip)
530 static struct hostent he;
531 static char hostname[256];
532 static char* p_aliases[1];
533 static char* p_addr[2];
534 static char address[16];
536 p_aliases[0]=0; /* no aliases*/
537 p_addr[1]=0; /* only one address*/
539 strncpy(hostname, name->s, (name->len<256)?(name->len)+1:256);
540 if (ip->len>16) return 0;
541 memcpy(address, ip->u.addr, ip->len);
543 he.h_addrtype=ip->af;
545 he.h_addr_list=p_addr;
546 he.h_aliases=p_aliases;