4 * Copyright (C) 2001-2003 FhG Fokus
6 * This file is part of Kamailio, a free SIP server.
8 * Kamailio is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version
13 * Kamailio is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "ip_helper.h"
28 #include <sys/types.h>
29 #include <netinet/in.h>
31 /* given an ip and a mask it provides network address */
33 net_address (unsigned int ip, unsigned int mask)
39 returns 1 if ip belongs to address/net or 0 if not
42 same_net (unsigned int ip, unsigned int address, unsigned int mask)
44 return ((address & mask) == (ip & mask));
48 /* Small help func takes ip-address-integer and returns string
51 ip2str (unsigned int address, char **rr)
54 char *hlp, hlp2[5]; /* initial era hlp2[18] */
55 unsigned char *addrp = (unsigned char *) &address;
56 hlp = (char *) malloc (18);
59 for (i = 0; i < 3; i++)
61 sprintf (hlp2, "%i.", addrp[i]);
62 hlp = strcat (hlp, (char *) hlp2);
64 sprintf (hlp2, "%i", addrp[3]);
65 hlp = strcat (hlp, hlp2);
69 /* Small help func takes ip-address-string, determines its validity
70 and write the integer representation at address.
71 Returns 1 if successful converted, 0 if the dotted isn't valid.
72 If you want to parse IP/netmask pairs, call parse_ip_netmask
73 first - it will remove the netmask, then use this func */
75 parse_ip_address (char *c, unsigned int *address) //inet_aton
77 int quat, i, j, digit_bol;
90 /* cool dirty hack to address the bytes of the int easily */
91 addrp = (unsigned char *) address;
93 /* make a copy of the dotted string, because we modify it */
97 /* search three times for a dot in the string */
98 for (i = 0; i < 3; i++)
100 if ((q = strchr (p, '.')) == NULL)
104 *q = '\0'; /* cut off at the dot */
105 if (strlen (p)) /* is the distance between dots greater 0 */
108 for (j = 0; j < strlen (p); j++, r++) /* are all char of the
110 digit_bol = digit_bol && isdigit ((unsigned char)*r);
114 if (quat > 255) /* is it a byte or greater */
118 (unsigned char) quat;
129 /* and the last byte */
133 for (j = 0; j < strlen (p); j++, r++)
134 digit_bol = digit_bol && isdigit ((unsigned char)*r);
143 addrp[3] = (unsigned char) quat;
157 /* return 1 if ALL str is a positive number or 0. no + signs allowed*/
159 is_positive_number (char *str)
164 for (i = 0; i < strlen (str); i++)
166 if (isdigit ((unsigned char)str[i]) == 0)
172 /* return 0 in case of error */
174 make_mask (unsigned int length)
177 if ((length < 8) || (length > 30))
178 return -1; /* invalid value for mask */
181 /* shift it to right with 32-length positions */
182 res = htonl (res << (32 - length));
186 /* Small help func takes ip-address-string, determines if a valid
187 netmask is specified and inserts the netmask into mask.
188 Cuts of the netmask of the string, if it founds a netmask !!!
189 Returns 0 if no netmask found, -1 if netmask isn't valid, and
191 According to this function a mask is in form of 255.255.192.0
192 so an ip/mask looks like 10.0.0.0/255.255.192.0
193 we will extend it to 10.0.0.0/18 which will be also valid
196 parse_ip_netmask (char *c, char **ip, unsigned int *mask)
199 unsigned int netmask;
208 if ((q = strchr (p, '/')) == NULL)
211 return 0; /* no mask */
215 *ip = (char *) malloc (q - p + 1);
218 memcpy (*ip, p, q - p);
221 // wrong (*q) = 0; /* cut of the netmask */
224 * two possibilities /16 or /255.255.192.0
226 if (is_positive_number (q) == 1)
228 /* we have a /16 mask */
229 if ((netmask = make_mask (atoi (q))) == 0)
231 *mask = 0; /* error in value of /43 or something like */
240 else /* we may have a 255.255.192.0 mask */ if (parse_ip_address (q, &netmask) == 1) /* and parse the netmask */