OLD | NEW |
1 /* | 1 /* |
2 * dhcpcd - DHCP client daemon | 2 * dhcpcd - DHCP client daemon |
3 * Copyright (c) 2006-2009 Roy Marples <roy@marples.name> | 3 * Copyright (c) 2006-2009 Roy Marples <roy@marples.name> |
4 * All rights reserved | 4 * All rights reserved |
5 | 5 |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 return -1; | 144 return -1; |
145 } | 145 } |
146 err = (struct nlmsgerr *)NLMSG_DATA(nlm); | 146 err = (struct nlmsgerr *)NLMSG_DATA(nlm); |
147 if (err->error == 0) | 147 if (err->error == 0) |
148 return l; | 148 return l; |
149 errno = -err->error; | 149 errno = -err->error; |
150 return -1; | 150 return -1; |
151 } | 151 } |
152 | 152 |
153 static int | 153 static int |
154 link_route(struct nlmsghdr *nlm) | |
155 { | |
156 int len, idx, metric; | |
157 struct rtattr *rta; | |
158 struct rtmsg *rtm; | |
159 struct rt rt; | |
160 char ifn[IF_NAMESIZE + 1]; | |
161 | |
162 if (nlm->nlmsg_type != RTM_DELROUTE) | |
163 return 0; | |
164 | |
165 len = nlm->nlmsg_len - sizeof(*nlm); | |
166 if ((size_t)len < sizeof(*rtm)) { | |
167 errno = EBADMSG; | |
168 return -1; | |
169 } | |
170 rtm = NLMSG_DATA(nlm); | |
171 if (rtm->rtm_type != RTN_UNICAST || | |
172 rtm->rtm_table != RT_TABLE_MAIN || | |
173 rtm->rtm_family != AF_INET || | |
174 nlm->nlmsg_pid == (uint32_t)getpid()) | |
175 return 1; | |
176 rta = (struct rtattr *) ((char *)rtm + NLMSG_ALIGN(sizeof(*rtm))); | |
177 len = NLMSG_PAYLOAD(nlm, sizeof(*rtm)); | |
178 rt.iface = NULL; | |
179 rt.dest.s_addr = INADDR_ANY; | |
180 rt.net.s_addr = INADDR_ANY; | |
181 rt.gate.s_addr = INADDR_ANY; | |
182 rt.next = NULL; | |
183 metric = 0; | |
184 while (RTA_OK(rta, len)) { | |
185 switch (rta->rta_type) { | |
186 case RTA_DST: | |
187 memcpy(&rt.dest.s_addr, RTA_DATA(rta), | |
188 sizeof(rt.dest.s_addr)); | |
189 break; | |
190 case RTA_GATEWAY: | |
191 memcpy(&rt.gate.s_addr, RTA_DATA(rta), | |
192 sizeof(rt.gate.s_addr)); | |
193 break; | |
194 case RTA_OIF: | |
195 idx = *(int *)RTA_DATA(rta); | |
196 if (if_indextoname(idx, ifn)) | |
197 rt.iface = find_interface(ifn); | |
198 break; | |
199 case RTA_PRIORITY: | |
200 metric = *(int *)RTA_DATA(rta); | |
201 break; | |
202 } | |
203 rta = RTA_NEXT(rta, len); | |
204 } | |
205 if (rt.iface != NULL) { | |
206 if (metric == rt.iface->metric) { | |
207 inet_cidrtoaddr(rtm->rtm_dst_len, &rt.net); | |
208 route_deleted(&rt); | |
209 } | |
210 } | |
211 return 1; | |
212 } | |
213 | |
214 static int | |
215 link_addr(struct nlmsghdr *nlm) | 154 link_addr(struct nlmsghdr *nlm) |
216 { | 155 { |
217 int len; | 156 int len; |
218 struct rtattr *rta; | 157 struct rtattr *rta; |
219 struct ifaddrmsg *ifa; | 158 struct ifaddrmsg *ifa; |
220 struct in_addr addr, net, dest; | 159 struct in_addr addr, net, dest; |
221 char ifn[IF_NAMESIZE + 1]; | 160 char ifn[IF_NAMESIZE + 1]; |
222 struct interface *iface; | 161 struct interface *iface; |
223 | 162 |
224 if (nlm->nlmsg_type != RTM_DELADDR && nlm->nlmsg_type != RTM_NEWADDR) | 163 if (nlm->nlmsg_type != RTM_DELADDR && nlm->nlmsg_type != RTM_NEWADDR) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 } | 201 } |
263 | 202 |
264 static int | 203 static int |
265 link_netlink(struct nlmsghdr *nlm) | 204 link_netlink(struct nlmsghdr *nlm) |
266 { | 205 { |
267 int len; | 206 int len; |
268 struct rtattr *rta; | 207 struct rtattr *rta; |
269 struct ifinfomsg *ifi; | 208 struct ifinfomsg *ifi; |
270 char ifn[IF_NAMESIZE + 1]; | 209 char ifn[IF_NAMESIZE + 1]; |
271 | 210 |
272 len = link_route(nlm); | |
273 if (len != 0) | |
274 return len; | |
275 len = link_addr(nlm); | 211 len = link_addr(nlm); |
276 if (len != 0) | 212 if (len != 0) |
277 return len; | 213 return len; |
278 | 214 |
279 if (nlm->nlmsg_type != RTM_NEWLINK && nlm->nlmsg_type != RTM_DELLINK) | 215 if (nlm->nlmsg_type != RTM_NEWLINK && nlm->nlmsg_type != RTM_DELLINK) |
280 return 0; | 216 return 0; |
281 len = nlm->nlmsg_len - sizeof(*nlm); | 217 len = nlm->nlmsg_len - sizeof(*nlm); |
282 if ((size_t)len < sizeof(*ifi)) { | 218 if ((size_t)len < sizeof(*ifi)) { |
283 errno = EBADMSG; | 219 errno = EBADMSG; |
284 return -1; | 220 return -1; |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 &gateway->s_addr, sizeof(gateway->s_addr)); | 437 &gateway->s_addr, sizeof(gateway->s_addr)); |
502 | 438 |
503 add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_OIF, ifindex); | 439 add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_OIF, ifindex); |
504 add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_PRIORITY, metric); | 440 add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_PRIORITY, metric); |
505 | 441 |
506 if (send_netlink(&nlm->hdr) == -1) | 442 if (send_netlink(&nlm->hdr) == -1) |
507 retval = -1; | 443 retval = -1; |
508 free(nlm); | 444 free(nlm); |
509 return retval; | 445 return retval; |
510 } | 446 } |
OLD | NEW |