Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/networking/libiproute/libnetlink.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/networking/libiproute/libnetlink.c
r1765 r2725 1 1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 * libnetlink.c RTnetlink service routines. 3 * This program is free software; you can redistribute it and/or 4 * modify it under the terms of the GNU General Public License 5 * as published by the Free Software Foundation; either version 6 * 2 of the License, or (at your option) any later version. 4 7 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 8 * 2 of the License, or (at your option) any later version. 9 * 10 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 11 * 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 12 9 */ 13 10 … … 18 15 #include "libnetlink.h" 19 16 20 void rtnl_close(struct rtnl_handle *rth) 21 { 22 close(rth->fd); 23 } 24 25 int xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/) 17 void FAST_FUNC xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/) 26 18 { 27 19 socklen_t addr_len; 28 20 29 memset(rth, 0, sizeof(rth)); 30 21 memset(rth, 0, sizeof(*rth)); 31 22 rth->fd = xsocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 32 33 memset(&rth->local, 0, sizeof(rth->local));34 23 rth->local.nl_family = AF_NETLINK; 35 24 /*rth->local.nl_groups = subscriptions;*/ … … 37 26 xbind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)); 38 27 addr_len = sizeof(rth->local); 28 getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len); 29 30 /* too much paranoia 39 31 if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) 40 bb_perror_msg_and_die(" cannotgetsockname");32 bb_perror_msg_and_die("getsockname"); 41 33 if (addr_len != sizeof(rth->local)) 42 34 bb_error_msg_and_die("wrong address length %d", addr_len); 43 35 if (rth->local.nl_family != AF_NETLINK) 44 36 bb_error_msg_and_die("wrong address family %d", rth->local.nl_family); 37 */ 45 38 rth->seq = time(NULL); 46 return 0; 47 } 48 49 int xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) 39 } 40 41 int FAST_FUNC xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) 50 42 { 51 43 struct { … … 53 45 struct rtgenmsg g; 54 46 } req; 55 struct sockaddr_nl nladdr;56 57 memset(&nladdr, 0, sizeof(nladdr));58 nladdr.nl_family = AF_NETLINK;59 47 60 48 req.nlh.nlmsg_len = sizeof(req); … … 65 53 req.g.rtgen_family = family; 66 54 67 return xsendto(rth->fd, (void*)&req, sizeof(req), 68 (struct sockaddr*)&nladdr, sizeof(nladdr)); 69 } 70 71 int rtnl_send(struct rtnl_handle *rth, char *buf, int len) 55 return rtnl_send(rth, (void*)&req, sizeof(req)); 56 } 57 58 int FAST_FUNC rtnl_send(struct rtnl_handle *rth, char *buf, int len) 72 59 { 73 60 struct sockaddr_nl nladdr; … … 79 66 } 80 67 81 int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len)68 int FAST_FUNC rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) 82 69 { 83 70 struct nlmsghdr nlh; … … 86 73 struct msghdr msg = { 87 74 (void*)&nladdr, sizeof(nladdr), 88 iov, 89 NULL, 75 iov, 2, 76 NULL, 0, 90 77 0 91 78 }; … … 104 91 105 92 static int rtnl_dump_filter(struct rtnl_handle *rth, 106 int (*filter)( struct sockaddr_nl *, struct nlmsghdr *n, void *),93 int (*filter)(const struct sockaddr_nl *, struct nlmsghdr *n, void *) FAST_FUNC, 107 94 void *arg1/*, 108 95 int (*junk)(struct sockaddr_nl *, struct nlmsghdr *n, void *), 109 96 void *arg2*/) 110 97 { 111 char buf[8192]; 98 int retval = -1; 99 char *buf = xmalloc(8*1024); /* avoid big stack buffer */ 112 100 struct sockaddr_nl nladdr; 113 struct iovec iov = { buf, sizeof(buf)};101 struct iovec iov = { buf, 8*1024 }; 114 102 115 103 while (1) { … … 119 107 struct msghdr msg = { 120 108 (void*)&nladdr, sizeof(nladdr), 121 &iov, 122 NULL, 109 &iov, 1, 110 NULL, 0, 123 111 0 124 112 }; … … 134 122 if (status == 0) { 135 123 bb_error_msg("EOF on netlink"); 136 return -1;124 goto ret; 137 125 } 138 126 if (msg.msg_namelen != sizeof(nladdr)) { … … 146 134 if (nladdr.nl_pid != 0 || 147 135 h->nlmsg_pid != rth->local.nl_pid || 148 h->nlmsg_seq != rth->dump) { 149 /* if (junk) { 150 err = junk(&nladdr, h, arg2); 151 if (err < 0) 152 return err; 153 } */ 136 h->nlmsg_seq != rth->dump 137 ) { 138 // if (junk) { 139 // err = junk(&nladdr, h, arg2); 140 // if (err < 0) { 141 // retval = err; 142 // goto ret; 143 // } 144 // } 154 145 goto skip_it; 155 146 } 156 147 157 148 if (h->nlmsg_type == NLMSG_DONE) { 158 return0;149 goto ret_0; 159 150 } 160 151 if (h->nlmsg_type == NLMSG_ERROR) { … … 166 157 bb_perror_msg("RTNETLINK answers"); 167 158 } 168 return -1;159 goto ret; 169 160 } 170 161 err = filter(&nladdr, h, arg1); 171 if (err < 0) 172 return err; 173 174 skip_it: 162 if (err < 0) { 163 retval = err; 164 goto ret; 165 } 166 167 skip_it: 175 168 h = NLMSG_NEXT(h, status); 176 169 } … … 182 175 bb_error_msg_and_die("remnant of size %d!", status); 183 176 } 184 } 185 } 186 187 int xrtnl_dump_filter(struct rtnl_handle *rth, 188 int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *), 177 } /* while (1) */ 178 ret_0: 179 retval++; /* = 0 */ 180 ret: 181 free(buf); 182 return retval; 183 } 184 185 int FAST_FUNC xrtnl_dump_filter(struct rtnl_handle *rth, 186 int (*filter)(const struct sockaddr_nl *, struct nlmsghdr *, void *) FAST_FUNC, 189 187 void *arg1) 190 188 { … … 195 193 } 196 194 197 int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, 198 unsigned groups, struct nlmsghdr *answer, 199 int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *), 200 void *jarg) 201 { 195 int FAST_FUNC rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, 196 pid_t peer, unsigned groups, 197 struct nlmsghdr *answer, 198 int (*junk)(struct sockaddr_nl *, struct nlmsghdr *, void *), 199 void *jarg) 200 { 201 /* bbox doesn't use parameters no. 3, 4, 6, 7, they are stubbed out */ 202 #define peer 0 203 #define groups 0 204 #define junk NULL 205 #define jarg NULL 206 int retval = -1; 202 207 int status; 203 208 unsigned seq; … … 205 210 struct sockaddr_nl nladdr; 206 211 struct iovec iov = { (void*)n, n->nlmsg_len }; 207 char buf[8192];212 char *buf = xmalloc(8*1024); /* avoid big stack buffer */ 208 213 struct msghdr msg = { 209 214 (void*)&nladdr, sizeof(nladdr), 210 &iov, 211 NULL, 215 &iov, 1, 216 NULL, 0, 212 217 0 213 218 }; … … 215 220 memset(&nladdr, 0, sizeof(nladdr)); 216 221 nladdr.nl_family = AF_NETLINK; 217 nladdr.nl_pid = peer;218 nladdr.nl_groups = groups;222 // nladdr.nl_pid = peer; 223 // nladdr.nl_groups = groups; 219 224 220 225 n->nlmsg_seq = seq = ++rtnl->seq; … … 225 230 226 231 if (status < 0) { 227 bb_perror_msg("can not talk to rtnetlink");228 return -1;232 bb_perror_msg("can't talk to rtnetlink"); 233 goto ret; 229 234 } 230 235 … … 232 237 233 238 while (1) { 234 iov.iov_len = sizeof(buf);239 iov.iov_len = 8*1024; 235 240 status = recvmsg(rtnl->fd, &msg, 0); 236 241 … … 244 249 if (status == 0) { 245 250 bb_error_msg("EOF on netlink"); 246 return -1;251 goto ret; 247 252 } 248 253 if (msg.msg_namelen != sizeof(nladdr)) { 249 254 bb_error_msg_and_die("sender address length == %d", msg.msg_namelen); 250 255 } 251 for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) {252 int l_err;256 for (h = (struct nlmsghdr*)buf; status >= (int)sizeof(*h); ) { 257 // int l_err; 253 258 int len = h->nlmsg_len; 254 259 int l = len - sizeof(*h); 255 260 256 if (l <0 || len>status) {261 if (l < 0 || len > status) { 257 262 if (msg.msg_flags & MSG_TRUNC) { 258 263 bb_error_msg("truncated message"); 259 return -1;264 goto ret; 260 265 } 261 266 bb_error_msg_and_die("malformed message: len=%d!", len); … … 264 269 if (nladdr.nl_pid != peer || 265 270 h->nlmsg_pid != rtnl->local.nl_pid || 266 h->nlmsg_seq != seq) { 267 if (junk) { 268 l_err = junk(&nladdr, h, jarg); 269 if (l_err < 0) { 270 return l_err; 271 } 272 } 271 h->nlmsg_seq != seq 272 ) { 273 // if (junk) { 274 // l_err = junk(&nladdr, h, jarg); 275 // if (l_err < 0) { 276 // retval = l_err; 277 // goto ret; 278 // } 279 // } 273 280 continue; 274 281 } … … 276 283 if (h->nlmsg_type == NLMSG_ERROR) { 277 284 struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); 278 if (l < sizeof(struct nlmsgerr)) {285 if (l < (int)sizeof(struct nlmsgerr)) { 279 286 bb_error_msg("ERROR truncated"); 280 287 } else { 281 errno = - err->error;288 errno = - err->error; 282 289 if (errno == 0) { 283 290 if (answer) { 284 291 memcpy(answer, h, h->nlmsg_len); 285 292 } 286 return0;293 goto ret_0; 287 294 } 288 295 bb_perror_msg("RTNETLINK answers"); 289 296 } 290 return -1;297 goto ret; 291 298 } 292 299 if (answer) { 293 300 memcpy(answer, h, h->nlmsg_len); 294 return0;301 goto ret_0; 295 302 } 296 303 … … 307 314 bb_error_msg_and_die("remnant of size %d!", status); 308 315 } 309 } 310 } 311 312 int addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data) 316 } /* while (1) */ 317 ret_0: 318 retval++; /* = 0 */ 319 ret: 320 free(buf); 321 return retval; 322 } 323 324 int FAST_FUNC addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data) 313 325 { 314 326 int len = RTA_LENGTH(4); 315 327 struct rtattr *rta; 316 if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) 328 329 if ((int)(NLMSG_ALIGN(n->nlmsg_len) + len) > maxlen) { 317 330 return -1; 331 } 318 332 rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len)); 319 333 rta->rta_type = type; 320 334 rta->rta_len = len; 321 m emcpy(RTA_DATA(rta), &data, 4);335 move_to_unaligned32(RTA_DATA(rta), data); 322 336 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len; 323 337 return 0; 324 338 } 325 339 326 int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen)340 int FAST_FUNC addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen) 327 341 { 328 342 int len = RTA_LENGTH(alen); 329 343 struct rtattr *rta; 330 344 331 if ( NLMSG_ALIGN(n->nlmsg_len) + len > maxlen)345 if ((int)(NLMSG_ALIGN(n->nlmsg_len) + len) > maxlen) { 332 346 return -1; 347 } 333 348 rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len)); 334 349 rta->rta_type = type; … … 339 354 } 340 355 341 int rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data)356 int FAST_FUNC rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data) 342 357 { 343 358 int len = RTA_LENGTH(4); … … 350 365 subrta->rta_type = type; 351 366 subrta->rta_len = len; 352 m emcpy(RTA_DATA(subrta), &data, 4);367 move_to_unaligned32(RTA_DATA(subrta), data); 353 368 rta->rta_len = NLMSG_ALIGN(rta->rta_len) + len; 354 369 return 0; 355 370 } 356 371 357 int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen)372 int FAST_FUNC rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen) 358 373 { 359 374 struct rtattr *subrta; … … 372 387 373 388 374 intparse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)389 void FAST_FUNC parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) 375 390 { 376 391 while (RTA_OK(rta, len)) { … … 383 398 bb_error_msg("deficit %d, rta_len=%d!", len, rta->rta_len); 384 399 } 385 return 0; 386 } 400 }
Note:
See TracChangeset
for help on using the changeset viewer.