2ec8ad4a0936f148ecf6fccd66e131a5d67a7bc5
[sip-router] / ip_addr.c
1 /*
2  * $Id$
3  *
4  *
5  * ip address & address family related functions
6  *
7  * Copyright (C) 2001-2003 Fhg Fokus
8  *
9  * This file is part of ser, a free SIP server.
10  *
11  * ser is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version
15  *
16  * For a license to use the ser software under conditions
17  * other than those described here, or to purchase support for this
18  * software, please contact iptel.org by e-mail at the following addresses:
19  *    info@iptel.org
20  *
21  * ser is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License 
27  * along with this program; if not, write to the Free Software 
28  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29  */
30 /*
31  * History:
32  * --------
33  *  2003-03-19  replaced all mallocs/frees w/ pkg_malloc/pkg_free
34  */
35
36
37 #include <stdlib.h>
38 #include <stdio.h>
39
40 #include "ip_addr.h"
41 #include "dprint.h"
42 #include "mem/mem.h"
43
44
45 struct net* mk_net(struct ip_addr* ip, struct ip_addr* mask)
46 {
47         struct net* n;
48         
49         if ((ip->af != mask->af) || (ip->len != mask->len)){
50                 LOG(L_CRIT, "ERROR: mk_net: trying to use a different mask family"
51                                 " (eg. ipv4/ipv6mask or ipv6/ipv4mask)\n");
52                 goto error;
53         }
54         n=(struct net*)pkg_malloc(sizeof(struct net));
55         if (n==0){ 
56                 LOG(L_CRIT, "ERROR: mk_net: memory allocation failure\n");
57                 goto error;
58         }
59         n->ip=*ip;
60         n->mask=*mask;
61         return n;
62 error:
63         return 0;
64 }
65
66
67
68 struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen)
69 {
70         struct net* n;
71         int r;
72         
73         if (bitlen>ip->len*8){
74                 LOG(L_CRIT, "ERROR: mk_net_bitlen: bad bitlen number %d\n", bitlen);
75                 goto error;
76         }
77         n=(struct net*)pkg_malloc(sizeof(struct net));
78         if (n==0){
79                 LOG(L_CRIT, "ERROR: mk_net_bitlen: memory allocation failure\n"); 
80                 goto error;
81         }
82         memset(n,0, sizeof(struct net));
83         n->ip=*ip;
84         for (r=0;r<bitlen/8;r++) n->mask.u.addr[r]=0xff;
85         if (bitlen%8) n->mask.u.addr[r]=  ~((1<<(8-(bitlen%8)))-1);
86         n->mask.af=ip->af;
87         n->mask.len=ip->len;
88         
89         return n;
90 error:
91         return 0;
92 }
93
94
95
96 void print_ip(char* p, struct ip_addr* ip, char *s)
97 {
98         switch(ip->af){
99                 case AF_INET:
100                         DBG("%s%d.%d.%d.%d%s", (p)?p:"",
101                                                                 ip->u.addr[0],
102                                                                 ip->u.addr[1],
103                                                                 ip->u.addr[2],
104                                                                 ip->u.addr[3],
105                                                                 (s)?s:""
106                                                                 );
107                         break;
108                 case AF_INET6:
109                         DBG("%s%x:%x:%x:%x:%x:%x:%x:%x%s", (p)?p:"",
110                                                                                         htons(ip->u.addr16[0]),
111                                                                                         htons(ip->u.addr16[1]),
112                                                                                         htons(ip->u.addr16[2]),
113                                                                                         htons(ip->u.addr16[3]),
114                                                                                         htons(ip->u.addr16[4]),
115                                                                                         htons(ip->u.addr16[5]),
116                                                                                         htons(ip->u.addr16[6]),
117                                                                                         htons(ip->u.addr16[7]),
118                                                                                         (s)?s:""
119                                 );
120                         break;
121                 default:
122                         DBG("print_ip: warning unknown adress family %d\n", ip->af);
123         }
124 }
125
126
127
128 void stdout_print_ip(struct ip_addr* ip)
129 {
130         switch(ip->af){
131                 case AF_INET:
132                         printf("%d.%d.%d.%d",   ip->u.addr[0],
133                                                                 ip->u.addr[1],
134                                                                 ip->u.addr[2],
135                                                                 ip->u.addr[3]);
136                         break;
137                 case AF_INET6:
138                         printf("%x:%x:%x:%x:%x:%x:%x:%x",       htons(ip->u.addr16[0]),
139                                                                                         htons(ip->u.addr16[1]),
140                                                                                         htons(ip->u.addr16[2]),
141                                                                                         htons(ip->u.addr16[3]),
142                                                                                         htons(ip->u.addr16[4]),
143                                                                                         htons(ip->u.addr16[5]),
144                                                                                         htons(ip->u.addr16[6]),
145                                                                                         htons(ip->u.addr16[7])
146                                 );
147                         break;
148                 default:
149                         DBG("print_ip: warning unknown adress family %d\n", ip->af);
150         }
151 }
152
153
154
155 void print_net(struct net* net)
156 {
157         if (net==0){
158                 LOG(L_WARN, "ERROR: print net: null pointer\n");
159                 return;
160         }
161         print_ip("", &net->ip, "/"); print_ip("", &net->mask, "");
162 }
163
164
165 #ifdef USE_MCAST
166
167 /* Returns 1 if the given address is a multicast address */
168 int is_mcast(struct ip_addr* ip)
169 {
170         if (!ip){
171                 LOG(L_ERR, "ERROR: is_mcast: Invalid parameter value\n");
172                 return -1;
173         }
174
175         if (ip->af==AF_INET){
176                 return IN_MULTICAST(htonl(ip->u.addr32[0]));
177 #ifdef USE_IPV6
178         } else if (ip->af==AF_INET6){
179                 return IN6_IS_ADDR_MULTICAST((struct in6_addr *)ip->u.addr);
180 #endif /* USE_IPV6 */
181         } else {
182                 LOG(L_ERR, "ERROR: is_mcast: Unsupported protocol family\n");
183                 return -1;
184         }
185 }
186
187 #endif /* USE_MCAST */