- changed sip_msg (new rcv member containing all the ips, ports, protocol)
[sip-router] / ip_addr.h
1 /* $Id$
2  *
3  * ip address family realted structures
4  *
5  * Copyright (C) 2001-2003 Fhg Fokus
6  *
7  * This file is part of ser, a free SIP server.
8  *
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
13  *
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:
17  *    info@iptel.org
18  *
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.
23  *
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
27  */
28
29
30 #ifndef ip_addr_h
31 #define ip_addr_h
32
33 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <netdb.h>
38 #include "str.h"
39
40
41 #include "dprint.h"
42
43 enum sip_protos { PROTO_UDP, PROTO_TCP, PROTO_TLS };
44
45
46 struct ip_addr{
47         unsigned int af; /* address family: AF_INET6 or AF_INET */
48         unsigned int len;    /* address len, 16 or 4 */
49         
50         /* 64 bits alligned address */
51         union {
52                 unsigned int   addr32[4];
53                 unsigned short addr16[8];
54                 unsigned char  addr[16];
55         }u;
56 };
57
58
59
60 struct net{
61         struct ip_addr ip;
62         struct ip_addr mask;
63 };
64
65 union sockaddr_union{
66                 struct sockaddr     s;
67                 struct sockaddr_in  sin;
68         #ifdef USE_IPV6
69                 struct sockaddr_in6 sin6;
70         #endif
71 };
72
73
74 struct socket_info{
75         int socket;
76         str name; /* name - eg.: foo.bar or 10.0.0.1 */
77         struct ip_addr address; /* ip address */
78         str address_str;        /* ip address converted to string -- optimization*/
79         unsigned short port_no;  /* port number */
80         str port_no_str; /* port number converted to string -- optimization*/
81         int is_ip; /* 1 if name is an ip address, 0 if not  -- optimization*/
82         int is_lo; /* 1 if is a loopback, 0 if not */
83         union sockaddr_union su; 
84         int proto; /* tcp or udp*/
85 };
86
87
88 struct receive_info{
89         struct ip_addr src_ip;
90         struct ip_addr dst_ip;
91         short src_port;
92         short dst_port;
93         int proto;
94         int proto_reserved1;
95         int proto_reserved2;
96         union sockaddr_union src_su; /* usefull for replies*/
97         struct socket_info* bind_address; /* sock_info structure on which 
98                                                                           the msg was received*/
99         /* no need for dst_su yet */
100 };
101
102
103 /* len of the sockaddr */
104 #ifdef HAVE_SOCKADDR_SA_LEN
105 #define sockaddru_len(su)       ((su).s.sa_len)
106 #else
107 #ifdef USE_IPV6
108 #define sockaddru_len(su)       \
109                         (((su).s.sa_family==AF_INET6)?sizeof(struct sockaddr_in6):\
110                                         sizeof(struct sockaddr_in))
111 #else
112 #define sockaddru_len(su)       sizeof(struct sockaddr_in)
113 #endif /*USE_IPV6*/
114 #endif /* HAVE_SOCKADDR_SA_LEN*/
115         
116 /* inits an ip_addr with the addr. info from a hostent structure
117  * ip = struct ip_addr*
118  * he= struct hostent*
119  */
120 #define hostent2ip_addr(ip, he, addr_no) \
121         do{ \
122                 (ip)->af=(he)->h_addrtype; \
123                 (ip)->len=(he)->h_length;  \
124                 memcpy((ip)->u.addr, (he)->h_addr_list[(addr_no)], (ip)->len); \
125         }while(0)
126         
127
128
129
130 /* gets the protocol family corresponding to a specific address family
131  * ( PF_INET - AF_INET, PF_INET6 - AF_INET6, af for others)
132  */
133 #ifdef USE_IPV6
134 #define AF2PF(af)   (((af)==AF_INET)?PF_INET:((af)==AF_INET6)?PF_INET6:(af))
135 #else
136 #define AF2PF(af)   (((af)==AF_INET)?PF_INET:(af))
137 #endif
138
139
140
141
142 struct net* mk_net(struct ip_addr* ip, struct ip_addr* mask);
143 struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen);
144
145 void print_ip(struct ip_addr* ip);
146 void stdout_print_ip(struct ip_addr* ip);
147 void print_net(struct net* net);
148
149
150
151
152 /* returns 1 if ip & net.mask == net.ip ; 0 otherwise & -1 on error 
153         [ diff. adress fams ]) */
154 inline static int matchnet(struct ip_addr* ip, struct net* net)
155 {
156         unsigned int r;
157         int ret;
158         
159         ret=-1;
160         if (ip->af == net->ip.af){
161                 for(r=0; r<ip->len/4; r++){ /* ipv4 & ipv6 addresses are
162                                                                            all multiple of 4*/
163                         if ((ip->u.addr32[r]&net->mask.u.addr32[r])!=
164                                                                                                                  net->ip.u.addr32[r]){
165                                 return 0;
166                         }
167                 }
168                 return 1;
169         };
170         return -1;
171 }
172
173
174
175
176 /* inits an ip_addr pointer from a sockaddr structure*/
177 static inline void sockaddr2ip_addr(struct ip_addr* ip, struct sockaddr* sa)
178 {
179         switch(sa->sa_family){
180         case AF_INET:
181                         ip->af=AF_INET;
182                         ip->len=4;
183                         memcpy(ip->u.addr, &((struct sockaddr_in*)sa)->sin_addr, 4);
184                         break;
185 #ifdef USE_IPV6
186         case AF_INET6:
187                         ip->af=AF_INET6;
188                         ip->len=16;
189                         memcpy(ip->u.addr, &((struct sockaddr_in6*)sa)->sin6_addr, 16);
190                         break;
191 #endif
192         default:
193                         LOG(L_CRIT, "sockaddr2ip_addr: BUG: unknown address family %d\n",
194                                         sa->sa_family);
195         }
196 }
197
198
199
200 /* compare 2 ip_addrs (both args are pointers)*/
201 #define ip_addr_cmp(ip1, ip2) \
202         (((ip1)->af==(ip2)->af)&& \
203                 (memcmp((ip1)->u.addr, (ip2)->u.addr, (ip1)->len)==0))
204
205
206
207 /* compare 2 sockaddr_unions */
208 static inline int su_cmp(union sockaddr_union* s1, union sockaddr_union* s2)
209 {
210         if (s1->s.sa_family!=s2->s.sa_family) return 0;
211         switch(s1->s.sa_family){
212                 case AF_INET:
213                         return (s1->sin.sin_port==s2->sin.sin_port)&&
214                                         (memcmp(&s1->sin.sin_addr, &s2->sin.sin_addr, 4)==0);
215                 case AF_INET6:
216                         return (s1->sin6.sin6_port==s2->sin6.sin6_port)&&
217                                         (memcmp(&s1->sin6.sin6_addr, &s2->sin6.sin6_addr, 16)==0);
218                 default:
219                         LOG(L_CRIT,"su_cmp: BUG: unknown address family %d\n",
220                                                 s1->s.sa_family);
221                         return 0;
222         }
223 }
224
225
226
227 /* gets the port number */
228 static inline short su_getport(union sockaddr_union* su)
229 {
230         switch(su->s.sa_family){
231                 case AF_INET:
232                         return su->sin.sin_port;
233                 case AF_INET6:
234                         return su->sin6.sin6_port;
235                 default:
236                         LOG(L_CRIT,"su_get_port: BUG: unknown address family %d\n",
237                                                 su->s.sa_family);
238                         return 0;
239         }
240 }
241
242
243
244 /* inits an ip_addr pointer from a sockaddr_union ip address */
245 static inline void su2ip_addr(struct ip_addr* ip, union sockaddr_union* su)
246 {
247         switch(su->s.sa_family){
248         case AF_INET: 
249                                         ip->af=AF_INET;
250                                         ip->len=4;
251                                         memcpy(ip->u.addr, &su->sin.sin_addr, 4);
252                                         break;
253 #ifdef USE_IPV6
254         case AF_INET6:
255                                         ip->af=AF_INET6;
256                                         ip->len=16;
257                                         memcpy(ip->u.addr, &su->sin6.sin6_addr, 16);
258                                         break;
259 #endif
260         default:
261                                         LOG(L_CRIT,"su2ip_addr: BUG: unknown address family %d\n",
262                                                         su->s.sa_family);
263         }
264 }
265
266
267 /* ip_addr2su -> the same as init_su*/
268 #define ip_addr2su init_su
269
270 /* inits a struct sockaddr_union from a struct ip_addr and a port no 
271  * returns 0 if ok, -1 on error (unknown address family) */
272 static inline int init_su( union sockaddr_union* su,
273                                                         struct ip_addr* ip,
274                                                         unsigned short   port ) 
275 {
276         memset(su, 0, sizeof(union sockaddr_union));/*needed on freebsd*/
277         su->s.sa_family=ip->af;
278         switch(ip->af){
279 #ifdef USE_IPV6
280         case    AF_INET6:
281                 memcpy(&su->sin6.sin6_addr, ip->u.addr, ip->len); 
282                 #ifdef HAVE_SOCKADDR_SA_LEN
283                         su->sin6.sin6_len=sizeof(struct sockaddr_in6);
284                 #endif
285                 su->sin6.sin6_port=port;
286                 break;
287 #endif
288         case AF_INET:
289                 memcpy(&su->sin.sin_addr, ip->u.addr, ip->len);
290                 #ifdef HAVE_SOCKADDR_SA_LEN
291                         su->sin.sin_len=sizeof(struct sockaddr_in);
292                 #endif
293                 su->sin.sin_port=port;
294                 break;
295         default:
296                 LOG(L_CRIT, "init_ss: BUG: unknown address family %d\n", ip->af);
297                 return -1;
298         }
299         return 0;
300 }
301
302
303
304 /* inits a struct sockaddr_union from a struct hostent, an address index in
305  * the hostent structure and a port no.
306  * WARNING: no index overflow  checks!
307  * returns 0 if ok, -1 on error (unknown address family) */
308 static inline int hostent2su( union sockaddr_union* su,
309                                                                 struct hostent* he,
310                                                                 unsigned int idx,
311                                                                 unsigned short   port ) 
312 {
313         memset(su, 0, sizeof(union sockaddr_union)); /*needed on freebsd*/
314         su->s.sa_family=he->h_addrtype;
315         switch(he->h_addrtype){
316 #ifdef USE_IPV6
317         case    AF_INET6:
318                 memcpy(&su->sin6.sin6_addr, he->h_addr_list[idx], he->h_length);
319                 #ifdef HAVE_SOCKADDR_SA_LEN
320                         su->sin6.sin6_len=sizeof(struct sockaddr_in6);
321                 #endif
322                 su->sin6.sin6_port=port;
323                 break;
324 #endif
325         case AF_INET:
326                 memcpy(&su->sin.sin_addr, he->h_addr_list[idx], he->h_length);
327                 #ifdef HAVE_SOCKADDR_SA_LEN
328                         su->sin.sin_len=sizeof(struct sockaddr_in);
329                 #endif
330                 su->sin.sin_port=port;
331                 break;
332         default:
333                 LOG(L_CRIT, "hostent2su: BUG: unknown address family %d\n", 
334                                 he->h_addrtype);
335                 return -1;
336         }
337         return 0;
338 }
339
340
341
342 /* fast ip_addr -> string convertor;
343  * it uses an internal buffer
344  */
345 static inline char* ip_addr2a(struct ip_addr* ip)
346 {
347
348         static char buff[40];/* 1234:5678:9012:3456:7890:1234:5678:9012\0 */
349         int offset;
350         register unsigned char a,b,c;
351 #ifdef USE_IPV6
352         register unsigned char d;
353         register unsigned short hex4;
354 #endif
355         int r;
356         #define HEXDIG(x) (((x)>=10)?(x)-10+'A':(x)+'0')
357         
358         
359         offset=0;
360         switch(ip->af){
361         #ifdef USE_IPV6
362                 case AF_INET6:
363                         for(r=0;r<7;r++){
364                                 hex4=ntohs(ip->u.addr16[r]);
365                                 a=hex4>>12;
366                                 b=(hex4>>8)&0xf;
367                                 c=(hex4>>4)&0xf;
368                                 d=hex4&0xf;
369                                 if (a){
370                                         buff[offset]=HEXDIG(a);
371                                         buff[offset+1]=HEXDIG(b);
372                                         buff[offset+2]=HEXDIG(c);
373                                         buff[offset+3]=HEXDIG(d);
374                                         buff[offset+4]=':';
375                                         offset+=5;
376                                 }else if(b){
377                                         buff[offset]=HEXDIG(b);
378                                         buff[offset+1]=HEXDIG(c);
379                                         buff[offset+2]=HEXDIG(d);
380                                         buff[offset+3]=':';
381                                         offset+=4;
382                                 }else if(c){
383                                         buff[offset]=HEXDIG(c);
384                                         buff[offset+1]=HEXDIG(d);
385                                         buff[offset+2]=':';
386                                         offset+=3;
387                                 }else{
388                                         buff[offset]=HEXDIG(d);
389                                         buff[offset+1]=':';
390                                         offset+=2;
391                                 }
392                         }
393                         /* last int16*/
394                         hex4=ntohs(ip->u.addr16[r]);
395                         a=hex4>>12;
396                         b=(hex4>>8)&0xf;
397                         c=(hex4>>4)&0xf;
398                         d=hex4&0xf;
399                         if (a){
400                                 buff[offset]=HEXDIG(a);
401                                 buff[offset+1]=HEXDIG(b);
402                                 buff[offset+2]=HEXDIG(c);
403                                 buff[offset+3]=HEXDIG(d);
404                                 buff[offset+4]=0;
405                         }else if(b){
406                                 buff[offset]=HEXDIG(b);
407                                 buff[offset+1]=HEXDIG(c);
408                                 buff[offset+2]=HEXDIG(d);
409                                 buff[offset+3]=0;
410                         }else if(c){
411                                 buff[offset]=HEXDIG(c);
412                                 buff[offset+1]=HEXDIG(d);
413                                 buff[offset+2]=0;
414                         }else{
415                                 buff[offset]=HEXDIG(d);
416                                 buff[offset+1]=0;
417                         }
418                         break;
419         #endif
420                 case AF_INET:
421                         for(r=0;r<3;r++){
422                                 a=ip->u.addr[r]/100;
423                                 c=ip->u.addr[r]%10;
424                                 b=ip->u.addr[r]%100/10;
425                                 if (a){
426                                         buff[offset]=a+'0';
427                                         buff[offset+1]=b+'0';
428                                         buff[offset+2]=c+'0';
429                                         buff[offset+3]='.';
430                                         offset+=4;
431                                 }else if (b){
432                                         buff[offset]=b+'0';
433                                         buff[offset+1]=c+'0';
434                                         buff[offset+2]='.';
435                                         offset+=3;
436                                 }else{
437                                         buff[offset]=c+'0';
438                                         buff[offset+1]='.';
439                                         offset+=2;
440                                 }
441                         }
442                         /* last number */
443                         a=ip->u.addr[r]/100;
444                         c=ip->u.addr[r]%10;
445                         b=ip->u.addr[r]%100/10;
446                         if (a){
447                                 buff[offset]=a+'0';
448                                 buff[offset+1]=b+'0';
449                                 buff[offset+2]=c+'0';
450                                 buff[offset+3]=0;
451                         }else if (b){
452                                 buff[offset]=b+'0';
453                                 buff[offset+1]=c+'0';
454                                 buff[offset+2]=0;
455                         }else{
456                                 buff[offset]=c+'0';
457                                 buff[offset+1]=0;
458                         }
459                         break;
460                 
461                 default:
462                         LOG(L_CRIT, "BUG: ip_addr2a: unknown address family %d\n",
463                                         ip->af);
464                         return 0;
465         }
466         
467         return buff;
468 }
469
470
471
472 /* converts an ip_addr structure to a hostent, returns pointer to internal
473  * statical structure */
474 static inline struct hostent* ip_addr2he(char* name, int len,
475                                                                                         struct ip_addr* ip)
476 {
477         static struct hostent he;
478         static char hostname[256];
479         static char* p_aliases[1];
480         static char* p_addr[2];
481         static char address[16];
482         
483         p_aliases[0]=0; /* no aliases*/
484         p_addr[1]=0; /* only one address*/
485         p_addr[0]=address;
486         strncpy(hostname, name, (len<256)?len+1:256);
487         if (ip->len>16) return 0;
488         memcpy(address, ip->u.addr, ip->len);
489         
490         he.h_addrtype=ip->af;
491         he.h_length=ip->len;
492         he.h_addr_list=p_addr;
493         he.h_aliases=p_aliases;
494         he.h_name=hostname;
495         return &he;
496 }
497 #endif