diff options
author | Robert Greenwalt | 2011-02-01 17:21:21 -0600 |
---|---|---|
committer | Robert Greenwalt | 2011-02-02 16:18:44 -0600 |
commit | 09dd819d2794caf1a17cd03592c100755fb25577 (patch) | |
tree | 9bf2c60804977ff55db33a1f4f5f501859ba822c /libnetutils | |
parent | 120b57a3d9703bccba534af335aa94dd3a41be2f (diff) | |
download | platform-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.c | 15 | ||||
-rw-r--r-- | libnetutils/ifc_utils.c | 64 |
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 | ||
96 | extern int ipv4NetmaskToPrefixLength(in_addr_t mask); | ||
97 | |||
96 | typedef struct dhcp_info dhcp_info; | 98 | typedef struct dhcp_info dhcp_info; |
97 | 99 | ||
98 | struct dhcp_info { | 100 | struct 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 | ||
112 | dhcp_info last_good_info; | 114 | dhcp_info last_good_info; |
113 | 115 | ||
114 | void get_dhcp_info(uint32_t *ipaddr, uint32_t *gateway, uint32_t *mask, | 116 | void 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, | |||
127 | static int dhcp_configure(const char *ifname, dhcp_info *info) | 129 | static 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; | |||
51 | static int ifc_ctl_sock6 = -1; | 51 | static int ifc_ctl_sock6 = -1; |
52 | void printerr(char *fmt, ...); | 52 | void printerr(char *fmt, ...); |
53 | 53 | ||
54 | in_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 | |||
69 | int 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 | |||
54 | static const char *ipaddr_to_string(in_addr_t addr) | 81 | static 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 | ||
182 | int ifc_set_mask(const char *name, in_addr_t mask) | 209 | int 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 | ||
209 | int ifc_get_info(const char *name, in_addr_t *addr, in_addr_t *mask, unsigned *flags) | 239 | int 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 | ||
241 | in_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 | |||
256 | int ifc_add_ipv4_route(const char *ifname, struct in_addr dst, int prefix_length, | 272 | int 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) | |||
499 | int | 515 | int |
500 | ifc_configure(const char *ifname, | 516 | ifc_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 | } |