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