summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Greenwalt2011-02-01 17:21:21 -0600
committerRobert Greenwalt2011-02-02 16:18:44 -0600
commit09dd819d2794caf1a17cd03592c100755fb25577 (patch)
tree9bf2c60804977ff55db33a1f4f5f501859ba822c /libnetutils
parent120b57a3d9703bccba534af335aa94dd3a41be2f (diff)
downloadplatform-system-core-09dd819d2794caf1a17cd03592c100755fb25577.tar.gz
platform-system-core-09dd819d2794caf1a17cd03592c100755fb25577.tar.xz
platform-system-core-09dd819d2794caf1a17cd03592c100755fb25577.zip
Stop using netmask in the framework
This pushes prefixLength down as far as we can. bug:2542681 Change-Id: I94b7cde9d10e97ee2c071d92f25555cff5934f0b
Diffstat (limited to 'libnetutils')
-rw-r--r--libnetutils/dhcpclient.c15
-rw-r--r--libnetutils/ifc_utils.c64
2 files changed, 48 insertions, 31 deletions
diff --git a/libnetutils/dhcpclient.c b/libnetutils/dhcpclient.c
index ff00432b6..5039e26e7 100644
--- a/libnetutils/dhcpclient.c
+++ b/libnetutils/dhcpclient.c
@@ -93,6 +93,8 @@ const char *ipaddr(in_addr_t addr)
93 return inet_ntoa(in_addr); 93 return inet_ntoa(in_addr);
94} 94}
95 95
96extern int ipv4NetmaskToPrefixLength(in_addr_t mask);
97
96typedef struct dhcp_info dhcp_info; 98typedef struct dhcp_info dhcp_info;
97 99
98struct dhcp_info { 100struct dhcp_info {
@@ -100,7 +102,7 @@ struct dhcp_info {
100 102
101 uint32_t ipaddr; 103 uint32_t ipaddr;
102 uint32_t gateway; 104 uint32_t gateway;
103 uint32_t netmask; 105 uint32_t prefixLength;
104 106
105 uint32_t dns1; 107 uint32_t dns1;
106 uint32_t dns2; 108 uint32_t dns2;
@@ -111,13 +113,13 @@ struct dhcp_info {
111 113
112dhcp_info last_good_info; 114dhcp_info last_good_info;
113 115
114void get_dhcp_info(uint32_t *ipaddr, uint32_t *gateway, uint32_t *mask, 116void get_dhcp_info(uint32_t *ipaddr, uint32_t *gateway, uint32_t *prefixLength,
115 uint32_t *dns1, uint32_t *dns2, uint32_t *server, 117 uint32_t *dns1, uint32_t *dns2, uint32_t *server,
116 uint32_t *lease) 118 uint32_t *lease)
117{ 119{
118 *ipaddr = last_good_info.ipaddr; 120 *ipaddr = last_good_info.ipaddr;
119 *gateway = last_good_info.gateway; 121 *gateway = last_good_info.gateway;
120 *mask = last_good_info.netmask; 122 *prefixLength = last_good_info.prefixLength;
121 *dns1 = last_good_info.dns1; 123 *dns1 = last_good_info.dns1;
122 *dns2 = last_good_info.dns2; 124 *dns2 = last_good_info.dns2;
123 *server = last_good_info.serveraddr; 125 *server = last_good_info.serveraddr;
@@ -127,7 +129,7 @@ void get_dhcp_info(uint32_t *ipaddr, uint32_t *gateway, uint32_t *mask,
127static int dhcp_configure(const char *ifname, dhcp_info *info) 129static int dhcp_configure(const char *ifname, dhcp_info *info)
128{ 130{
129 last_good_info = *info; 131 last_good_info = *info;
130 return ifc_configure(ifname, info->ipaddr, info->netmask, info->gateway, 132 return ifc_configure(ifname, info->ipaddr, info->prefixLength, info->gateway,
131 info->dns1, info->dns2); 133 info->dns1, info->dns2);
132} 134}
133 135
@@ -153,8 +155,7 @@ void dump_dhcp_info(dhcp_info *info)
153 dhcp_type_to_name(info->type), info->type); 155 dhcp_type_to_name(info->type), info->type);
154 strcpy(addr, ipaddr(info->ipaddr)); 156 strcpy(addr, ipaddr(info->ipaddr));
155 strcpy(gway, ipaddr(info->gateway)); 157 strcpy(gway, ipaddr(info->gateway));
156 strcpy(mask, ipaddr(info->netmask)); 158 LOGD("ip %s gw %s prefixLength %d", addr, gway, info->prefixLength);
157 LOGD("ip %s gw %s mask %s", addr, gway, mask);
158 if (info->dns1) LOGD("dns1: %s", ipaddr(info->dns1)); 159 if (info->dns1) LOGD("dns1: %s", ipaddr(info->dns1));
159 if (info->dns2) LOGD("dns2: %s", ipaddr(info->dns2)); 160 if (info->dns2) LOGD("dns2: %s", ipaddr(info->dns2));
160 LOGD("server %s, lease %d seconds", 161 LOGD("server %s, lease %d seconds",
@@ -196,7 +197,7 @@ int decode_dhcp_msg(dhcp_msg *msg, int len, dhcp_info *info)
196 } 197 }
197 switch(opt) { 198 switch(opt) {
198 case OPT_SUBNET_MASK: 199 case OPT_SUBNET_MASK:
199 if (optlen >= 4) memcpy(&info->netmask, x, 4); 200 if (optlen >= 4) info->prefixLength = ipv4NetmaskToPrefixLength((int)x);
200 break; 201 break;
201 case OPT_GATEWAY: 202 case OPT_GATEWAY:
202 if (optlen >= 4) memcpy(&info->gateway, x, 4); 203 if (optlen >= 4) memcpy(&info->gateway, x, 4);
diff --git a/libnetutils/ifc_utils.c b/libnetutils/ifc_utils.c
index 6788391ab..e5c58b9b0 100644
--- a/libnetutils/ifc_utils.c
+++ b/libnetutils/ifc_utils.c
@@ -51,6 +51,33 @@ static int ifc_ctl_sock = -1;
51static int ifc_ctl_sock6 = -1; 51static int ifc_ctl_sock6 = -1;
52void printerr(char *fmt, ...); 52void printerr(char *fmt, ...);
53 53
54in_addr_t prefixLengthToIpv4Netmask(int prefix_length)
55{
56 in_addr_t mask = 0;
57
58 // C99 (6.5.7): shifts of 32 bits have undefined results
59 if (prefix_length <= 0 || prefix_length > 32) {
60 return 0;
61 }
62
63 mask = ~mask << (32 - prefix_length);
64 mask = htonl(mask);
65
66 return mask;
67}
68
69int ipv4NetmaskToPrefixLength(in_addr_t mask)
70{
71 mask = ntohl(mask);
72 int prefixLength = 0;
73 uint32_t m = (uint32_t)mask;
74 while (m & 0x80000000) {
75 prefixLength++;
76 m = m << 1;
77 }
78 return prefixLength;
79}
80
54static const char *ipaddr_to_string(in_addr_t addr) 81static const char *ipaddr_to_string(in_addr_t addr)
55{ 82{
56 struct in_addr in_addr; 83 struct in_addr in_addr;
@@ -179,10 +206,13 @@ int ifc_set_hwaddr(const char *name, const void *ptr)
179 return ioctl(ifc_ctl_sock, SIOCSIFHWADDR, &ifr); 206 return ioctl(ifc_ctl_sock, SIOCSIFHWADDR, &ifr);
180} 207}
181 208
182int ifc_set_mask(const char *name, in_addr_t mask) 209int ifc_set_prefixLength(const char *name, int prefixLength)
183{ 210{
184 struct ifreq ifr; 211 struct ifreq ifr;
212 // TODO - support ipv6
213 if (prefixLength > 32 || prefixLength < 0) return -1;
185 214
215 in_addr_t mask = prefixLengthToIpv4Netmask(prefixLength);
186 ifc_init_ifr(name, &ifr); 216 ifc_init_ifr(name, &ifr);
187 init_sockaddr_in(&ifr.ifr_addr, mask); 217 init_sockaddr_in(&ifr.ifr_addr, mask);
188 218
@@ -206,7 +236,7 @@ int ifc_get_addr(const char *name, in_addr_t *addr)
206 return ret; 236 return ret;
207} 237}
208 238
209int ifc_get_info(const char *name, in_addr_t *addr, in_addr_t *mask, unsigned *flags) 239int ifc_get_info(const char *name, in_addr_t *addr, int *prefixLength, unsigned *flags)
210{ 240{
211 struct ifreq ifr; 241 struct ifreq ifr;
212 ifc_init_ifr(name, &ifr); 242 ifc_init_ifr(name, &ifr);
@@ -219,11 +249,12 @@ int ifc_get_info(const char *name, in_addr_t *addr, in_addr_t *mask, unsigned *f
219 } 249 }
220 } 250 }
221 251
222 if (mask != NULL) { 252 if (prefixLength != NULL) {
223 if(ioctl(ifc_ctl_sock, SIOCGIFNETMASK, &ifr) < 0) { 253 if(ioctl(ifc_ctl_sock, SIOCGIFNETMASK, &ifr) < 0) {
224 *mask = 0; 254 *prefixLength = 0;
225 } else { 255 } else {
226 *mask = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr; 256 *prefixLength = ipv4NetmaskToPrefixLength((int)
257 ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr);
227 } 258 }
228 } 259 }
229 260
@@ -238,21 +269,6 @@ int ifc_get_info(const char *name, in_addr_t *addr, in_addr_t *mask, unsigned *f
238 return 0; 269 return 0;
239} 270}
240 271
241in_addr_t get_ipv4_netmask(int prefix_length)
242{
243 in_addr_t mask = 0;
244
245 // C99 (6.5.7): shifts of 32 bits have undefined results
246 if (prefix_length == 0) {
247 return 0;
248 }
249
250 mask = ~mask << (32 - prefix_length);
251 mask = htonl(mask);
252
253 return mask;
254}
255
256int ifc_add_ipv4_route(const char *ifname, struct in_addr dst, int prefix_length, 272int ifc_add_ipv4_route(const char *ifname, struct in_addr dst, int prefix_length,
257 struct in_addr gw) 273 struct in_addr gw)
258{ 274{
@@ -265,7 +281,7 @@ int ifc_add_ipv4_route(const char *ifname, struct in_addr dst, int prefix_length
265 rt.rt_dst.sa_family = AF_INET; 281 rt.rt_dst.sa_family = AF_INET;
266 rt.rt_dev = (void*) ifname; 282 rt.rt_dev = (void*) ifname;
267 283
268 netmask = get_ipv4_netmask(prefix_length); 284 netmask = prefixLengthToIpv4Netmask(prefix_length);
269 init_sockaddr_in(&rt.rt_genmask, netmask); 285 init_sockaddr_in(&rt.rt_genmask, netmask);
270 init_sockaddr_in(&rt.rt_dst, dst.s_addr); 286 init_sockaddr_in(&rt.rt_dst, dst.s_addr);
271 rt.rt_flags = RTF_UP; 287 rt.rt_flags = RTF_UP;
@@ -499,7 +515,7 @@ int ifc_remove_default_route(const char *ifname)
499int 515int
500ifc_configure(const char *ifname, 516ifc_configure(const char *ifname,
501 in_addr_t address, 517 in_addr_t address,
502 in_addr_t netmask, 518 uint32_t prefixLength,
503 in_addr_t gateway, 519 in_addr_t gateway,
504 in_addr_t dns1, 520 in_addr_t dns1,
505 in_addr_t dns2) { 521 in_addr_t dns2) {
@@ -518,8 +534,8 @@ ifc_configure(const char *ifname,
518 ifc_close(); 534 ifc_close();
519 return -1; 535 return -1;
520 } 536 }
521 if (ifc_set_mask(ifname, netmask)) { 537 if (ifc_set_prefixLength(ifname, prefixLength)) {
522 printerr("failed to set netmask %s: %s\n", ipaddr_to_string(netmask), strerror(errno)); 538 printerr("failed to set prefixLength %d: %s\n", prefixLength, strerror(errno));
523 ifc_close(); 539 ifc_close();
524 return -1; 540 return -1;
525 } 541 }