OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / user / ser / ip_addr.h
1 /* $Id: ip_addr.h,v 1.35 2004/11/30 16:28:23 andrei Exp $
2  *
3  * ip address family related 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 aligned 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; /* 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 */
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 struct socket_id{
122         char* name;
123         int proto;
124         int port;
125         struct socket_id* next;
126 };
127
128
129
130 /* len of the sockaddr */
131 #ifdef HAVE_SOCKADDR_SA_LEN
132 #define sockaddru_len(su)       ((su).s.sa_len)
133 #else
134 #ifdef USE_IPV6
135 #define sockaddru_len(su)       \
136                         (((su).s.sa_family==AF_INET6)?sizeof(struct sockaddr_in6):\
137                                         sizeof(struct sockaddr_in))
138 #else
139 #define sockaddru_len(su)       sizeof(struct sockaddr_in)
140 #endif /*USE_IPV6*/
141 #endif /* HAVE_SOCKADDR_SA_LEN*/
142         
143 /* inits an ip_addr with the addr. info from a hostent structure
144  * ip = struct ip_addr*
145  * he= struct hostent*
146  */
147 #define hostent2ip_addr(ip, he, addr_no) \
148         do{ \
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); \
152         }while(0)
153         
154
155
156
157 /* gets the protocol family corresponding to a specific address family
158  * ( PF_INET - AF_INET, PF_INET6 - AF_INET6, af for others)
159  */
160 #ifdef USE_IPV6
161 #define AF2PF(af)   (((af)==AF_INET)?PF_INET:((af)==AF_INET6)?PF_INET6:(af))
162 #else
163 #define AF2PF(af)   (((af)==AF_INET)?PF_INET:(af))
164 #endif
165
166
167
168
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);
171
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);
175
176 #ifdef USE_MCAST
177 /* Returns 1 if the given address is a multicast address */
178 int is_mcast(struct ip_addr* ip);
179 #endif /* USE_MCAST */
180
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)
184 {
185         unsigned int r;
186         int ret;
187         
188         ret=-1;
189         if (ip->af == net->ip.af){
190                 for(r=0; r<ip->len/4; r++){ /* ipv4 & ipv6 addresses are
191                                                                            all multiple of 4*/
192                         if ((ip->u.addr32[r]&net->mask.u.addr32[r])!=
193                                                                                                                  net->ip.u.addr32[r]){
194                                 return 0;
195                         }
196                 }
197                 return 1;
198         };
199         return -1;
200 }
201
202
203
204
205 /* inits an ip_addr pointer from a sockaddr structure*/
206 static inline void sockaddr2ip_addr(struct ip_addr* ip, struct sockaddr* sa)
207 {
208         switch(sa->sa_family){
209         case AF_INET:
210                         ip->af=AF_INET;
211                         ip->len=4;
212                         memcpy(ip->u.addr, &((struct sockaddr_in*)sa)->sin_addr, 4);
213                         break;
214 #ifdef USE_IPV6
215         case AF_INET6:
216                         ip->af=AF_INET6;
217                         ip->len=16;
218                         memcpy(ip->u.addr, &((struct sockaddr_in6*)sa)->sin6_addr, 16);
219                         break;
220 #endif
221         default:
222                         LOG(L_CRIT, "sockaddr2ip_addr: BUG: unknown address family %d\n",
223                                         sa->sa_family);
224         }
225 }
226
227
228
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))
233
234
235
236 /* compare 2 sockaddr_unions */
237 static inline int su_cmp(union sockaddr_union* s1, union sockaddr_union* s2)
238 {
239         if (s1->s.sa_family!=s2->s.sa_family) return 0;
240         switch(s1->s.sa_family){
241                 case AF_INET:
242                         return (s1->sin.sin_port==s2->sin.sin_port)&&
243                                         (memcmp(&s1->sin.sin_addr, &s2->sin.sin_addr, 4)==0);
244 #ifdef USE_IPV6
245                 case AF_INET6:
246                         return (s1->sin6.sin6_port==s2->sin6.sin6_port)&&
247                                         (memcmp(&s1->sin6.sin6_addr, &s2->sin6.sin6_addr, 16)==0);
248 #endif
249                 default:
250                         LOG(L_CRIT,"su_cmp: BUG: unknown address family %d\n",
251                                                 s1->s.sa_family);
252                         return 0;
253         }
254 }
255
256
257
258 /* gets the port number (host byte order) */
259 static inline unsigned short su_getport(union sockaddr_union* su)
260 {
261         switch(su->s.sa_family){
262                 case AF_INET:
263                         return ntohs(su->sin.sin_port);
264 #ifdef USE_IPV6
265                 case AF_INET6:
266                         return ntohs(su->sin6.sin6_port);
267 #endif
268                 default:
269                         LOG(L_CRIT,"su_get_port: BUG: unknown address family %d\n",
270                                                 su->s.sa_family);
271                         return 0;
272         }
273 }
274
275
276
277 /* sets the port number (host byte order) */
278 static inline void su_setport(union sockaddr_union* su, unsigned short port)
279 {
280         switch(su->s.sa_family){
281                 case AF_INET:
282                         su->sin.sin_port=htons(port);
283                         break;
284 #ifdef USE_IPV6
285                 case AF_INET6:
286                          su->sin6.sin6_port=htons(port);
287                          break;
288 #endif
289                 default:
290                         LOG(L_CRIT,"su_set_port: BUG: unknown address family %d\n",
291                                                 su->s.sa_family);
292         }
293 }
294
295
296
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)
299 {
300         switch(su->s.sa_family){
301         case AF_INET: 
302                                         ip->af=AF_INET;
303                                         ip->len=4;
304                                         memcpy(ip->u.addr, &su->sin.sin_addr, 4);
305                                         break;
306 #ifdef USE_IPV6
307         case AF_INET6:
308                                         ip->af=AF_INET6;
309                                         ip->len=16;
310                                         memcpy(ip->u.addr, &su->sin6.sin6_addr, 16);
311                                         break;
312 #endif
313         default:
314                                         LOG(L_CRIT,"su2ip_addr: BUG: unknown address family %d\n",
315                                                         su->s.sa_family);
316         }
317 }
318
319
320 /* ip_addr2su -> the same as init_su*/
321 #define ip_addr2su init_su
322
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,
327                                                         struct ip_addr* ip,
328                                                         unsigned short   port ) 
329 {
330         memset(su, 0, sizeof(union sockaddr_union));/*needed on freebsd*/
331         su->s.sa_family=ip->af;
332         switch(ip->af){
333 #ifdef USE_IPV6
334         case    AF_INET6:
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);
338                 #endif
339                 su->sin6.sin6_port=htons(port);
340                 break;
341 #endif
342         case AF_INET:
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);
346                 #endif
347                 su->sin.sin_port=htons(port);
348                 break;
349         default:
350                 LOG(L_CRIT, "init_ss: BUG: unknown address family %d\n", ip->af);
351                 return -1;
352         }
353         return 0;
354 }
355
356
357
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,
363                                                                 struct hostent* he,
364                                                                 unsigned int idx,
365                                                                 unsigned short   port ) 
366 {
367         memset(su, 0, sizeof(union sockaddr_union)); /*needed on freebsd*/
368         su->s.sa_family=he->h_addrtype;
369         switch(he->h_addrtype){
370 #ifdef USE_IPV6
371         case    AF_INET6:
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);
375                 #endif
376                 su->sin6.sin6_port=htons(port);
377                 break;
378 #endif
379         case AF_INET:
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);
383                 #endif
384                 su->sin.sin_port=htons(port);
385                 break;
386         default:
387                 LOG(L_CRIT, "hostent2su: BUG: unknown address family %d\n", 
388                                 he->h_addrtype);
389                 return -1;
390         }
391         return 0;
392 }
393
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
398  */
399 static inline char* ip_addr2a(struct ip_addr* ip)
400 {
401
402         static char buff[IP_ADDR_MAX_STR_SIZE];
403         int offset;
404         register unsigned char a,b,c;
405 #ifdef USE_IPV6
406         register unsigned char d;
407         register unsigned short hex4;
408 #endif
409         int r;
410         #define HEXDIG(x) (((x)>=10)?(x)-10+'A':(x)+'0')
411         
412         
413         offset=0;
414         switch(ip->af){
415         #ifdef USE_IPV6
416                 case AF_INET6:
417                         for(r=0;r<7;r++){
418                                 hex4=ntohs(ip->u.addr16[r]);
419                                 a=hex4>>12;
420                                 b=(hex4>>8)&0xf;
421                                 c=(hex4>>4)&0xf;
422                                 d=hex4&0xf;
423                                 if (a){
424                                         buff[offset]=HEXDIG(a);
425                                         buff[offset+1]=HEXDIG(b);
426                                         buff[offset+2]=HEXDIG(c);
427                                         buff[offset+3]=HEXDIG(d);
428                                         buff[offset+4]=':';
429                                         offset+=5;
430                                 }else if(b){
431                                         buff[offset]=HEXDIG(b);
432                                         buff[offset+1]=HEXDIG(c);
433                                         buff[offset+2]=HEXDIG(d);
434                                         buff[offset+3]=':';
435                                         offset+=4;
436                                 }else if(c){
437                                         buff[offset]=HEXDIG(c);
438                                         buff[offset+1]=HEXDIG(d);
439                                         buff[offset+2]=':';
440                                         offset+=3;
441                                 }else{
442                                         buff[offset]=HEXDIG(d);
443                                         buff[offset+1]=':';
444                                         offset+=2;
445                                 }
446                         }
447                         /* last int16*/
448                         hex4=ntohs(ip->u.addr16[r]);
449                         a=hex4>>12;
450                         b=(hex4>>8)&0xf;
451                         c=(hex4>>4)&0xf;
452                         d=hex4&0xf;
453                         if (a){
454                                 buff[offset]=HEXDIG(a);
455                                 buff[offset+1]=HEXDIG(b);
456                                 buff[offset+2]=HEXDIG(c);
457                                 buff[offset+3]=HEXDIG(d);
458                                 buff[offset+4]=0;
459                         }else if(b){
460                                 buff[offset]=HEXDIG(b);
461                                 buff[offset+1]=HEXDIG(c);
462                                 buff[offset+2]=HEXDIG(d);
463                                 buff[offset+3]=0;
464                         }else if(c){
465                                 buff[offset]=HEXDIG(c);
466                                 buff[offset+1]=HEXDIG(d);
467                                 buff[offset+2]=0;
468                         }else{
469                                 buff[offset]=HEXDIG(d);
470                                 buff[offset+1]=0;
471                         }
472                         break;
473         #endif
474                 case AF_INET:
475                         for(r=0;r<3;r++){
476                                 a=ip->u.addr[r]/100;
477                                 c=ip->u.addr[r]%10;
478                                 b=ip->u.addr[r]%100/10;
479                                 if (a){
480                                         buff[offset]=a+'0';
481                                         buff[offset+1]=b+'0';
482                                         buff[offset+2]=c+'0';
483                                         buff[offset+3]='.';
484                                         offset+=4;
485                                 }else if (b){
486                                         buff[offset]=b+'0';
487                                         buff[offset+1]=c+'0';
488                                         buff[offset+2]='.';
489                                         offset+=3;
490                                 }else{
491                                         buff[offset]=c+'0';
492                                         buff[offset+1]='.';
493                                         offset+=2;
494                                 }
495                         }
496                         /* last number */
497                         a=ip->u.addr[r]/100;
498                         c=ip->u.addr[r]%10;
499                         b=ip->u.addr[r]%100/10;
500                         if (a){
501                                 buff[offset]=a+'0';
502                                 buff[offset+1]=b+'0';
503                                 buff[offset+2]=c+'0';
504                                 buff[offset+3]=0;
505                         }else if (b){
506                                 buff[offset]=b+'0';
507                                 buff[offset+1]=c+'0';
508                                 buff[offset+2]=0;
509                         }else{
510                                 buff[offset]=c+'0';
511                                 buff[offset+1]=0;
512                         }
513                         break;
514                 
515                 default:
516                         LOG(L_CRIT, "BUG: ip_addr2a: unknown address family %d\n",
517                                         ip->af);
518                         return 0;
519         }
520         
521         return buff;
522 }
523
524
525
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)
529 {
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];
535         
536         p_aliases[0]=0; /* no aliases*/
537         p_addr[1]=0; /* only one address*/
538         p_addr[0]=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);
542         
543         he.h_addrtype=ip->af;
544         he.h_length=ip->len;
545         he.h_addr_list=p_addr;
546         he.h_aliases=p_aliases;
547         he.h_name=hostname;
548         return &he;
549 }
550 #endif