- add xsendto and use where appropriate; shrink iplink; sanitize libiproute a bit. -916 byte
No binary (build failed)
—
(log yok)
| @@ -298,6 +298,8 @@ int xsocket(int domain, int type, int protocol); | |
| void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen); | |
| void xlisten(int s, int backlog); | |
| void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen); | |
| + | ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to, |
| + | socklen_t tolen); |
| int setsockopt_reuseaddr(int fd); | |
| int setsockopt_broadcast(int fd); | |
| /* NB: returns port in host byte order */ | |
| @@ -557,6 +557,22 @@ void xlisten(int s, int backlog) | |
| if (listen(s, backlog)) bb_perror_msg_and_die("listen"); | |
| } | |
| + | /* Die with an error message if we the sendto failed. |
| + | * Return bytes sent otherwise |
| + | */ |
| + | |
| + | ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to, |
| + | socklen_t tolen) |
| + | { |
| + | ssize_t ret = sendto(s, buf, len, 0, to, tolen); |
| + | if (ret < 0) { |
| + | if (ENABLE_FEATURE_CLEAN_UP) |
| + | close(s); |
| + | bb_perror_msg_and_die("sendto"); |
| + | } |
| + | return ret; |
| + | } |
| + | |
| // xstat() - a stat() which dies on failure with meaningful error message | |
| void xstat(const char *name, struct stat *stat_buf) | |
| { | |
| @@ -199,12 +199,8 @@ int ether_wake_main(int argc, char **argv) | |
| whereto.sa_family = 0; | |
| strcpy(whereto.sa_data, ifname); | |
| #endif | |
| - | |
| - | if (sendto(s, outpack, pktsize, 0, (struct sockaddr *)&whereto, sizeof(whereto)) < 0) |
| - | bb_perror_msg(bb_msg_write_error); |
| - | |
| + | xsendto(s, outpack, pktsize, (struct sockaddr *)&whereto, sizeof(whereto)); |
| close(s); | |
| - | |
| return EXIT_SUCCESS; | |
| } | |
| @@ -486,22 +486,13 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush) | |
| argc--; | |
| } | |
| - | if (rtnl_open(&rth, 0) < 0) |
| - | exit(1); |
| + | xrtnl_open(&rth); |
| - | if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK) < 0) { |
| - | bb_perror_msg_and_die("cannot send dump request"); |
| - | } |
| - | |
| - | if (rtnl_dump_filter(&rth, store_nlmsg, &linfo, NULL, NULL) < 0) { |
| - | bb_error_msg_and_die("dump terminated"); |
| - | } |
| + | xrtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK); |
| + | xrtnl_dump_filter(&rth, store_nlmsg, &linfo); |
| if (filter_dev) { | |
| - | filter.ifindex = ll_name_to_index(filter_dev); |
| - | if (filter.ifindex <= 0) { |
| - | bb_error_msg_and_die("device \"%s\" does not exist", filter_dev); |
| - | } |
| + | filter.ifindex = xll_name_to_index(filter_dev); |
| } | |
| if (flush) { | |
| @@ -513,13 +504,9 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush) | |
| filter.rth = &rth; | |
| for (;;) { | |
| - | if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { |
| - | bb_perror_msg_and_die("cannot send dump request"); |
| - | } |
| + | xrtnl_wilddump_request(&rth, filter.family, RTM_GETADDR); |
| filter.flushed = 0; | |
| - | if (rtnl_dump_filter(&rth, print_addrinfo, stdout, NULL, NULL) < 0) { |
| - | bb_error_msg_and_die("flush terminated"); |
| - | } |
| + | xrtnl_dump_filter(&rth, print_addrinfo, stdout); |
| if (filter.flushed == 0) { | |
| return 0; | |
| } | |
| @@ -529,13 +516,8 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush) | |
| } | |
| if (filter.family != AF_PACKET) { | |
| - | if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { |
| - | bb_perror_msg_and_die("cannot send dump request"); |
| - | } |
| - | |
| - | if (rtnl_dump_filter(&rth, store_nlmsg, &ainfo, NULL, NULL) < 0) { |
| - | bb_error_msg_and_die("dump terminated"); |
| - | } |
| + | xrtnl_wilddump_request(&rth, filter.family, RTM_GETADDR); |
| + | xrtnl_dump_filter(&rth, store_nlmsg, &ainfo); |
| } | |
| @@ -779,15 +761,11 @@ static int ipaddr_modify(int cmd, int argc, char **argv) | |
| if (!scoped && cmd != RTM_DELADDR) | |
| req.ifa.ifa_scope = default_scope(&lcl); | |
| - | if (rtnl_open(&rth, 0) < 0) |
| - | exit(1); |
| + | xrtnl_open(&rth); |
| ll_init_map(&rth); | |
| - | req.ifa.ifa_index = ll_name_to_index(d); |
| - | if (req.ifa.ifa_index == 0) { |
| - | bb_error_msg_and_die("cannot find device \"%s\"", d); |
| - | } |
| + | req.ifa.ifa_index = xll_name_to_index(d); |
| if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) | |
| return 2; | |
| @@ -42,10 +42,7 @@ static int get_ctl_fd(void) | |
| fd = socket(PF_PACKET, SOCK_DGRAM, 0); | |
| if (fd >= 0) | |
| return fd; | |
| - | fd = socket(PF_INET6, SOCK_DGRAM, 0); |
| - | if (fd >= 0) |
| - | return fd; |
| - | bb_perror_msg_and_die("cannot create control socket"); |
| + | return xsocket(PF_INET6, SOCK_DGRAM, 0); |
| } | |
| /* Exits on error */ | |
| @@ -125,10 +122,7 @@ static int get_address(char *dev, int *htype) | |
| socklen_t alen; | |
| int s; | |
| - | s = socket(PF_PACKET, SOCK_DGRAM, 0); |
| - | if (s < 0) { |
| - | bb_perror_msg_and_die("socket(PF_PACKET)"); |
| - | } |
| + | s = xsocket(PF_PACKET, SOCK_DGRAM, 0); |
| memset(&ifr, 0, sizeof(ifr)); | |
| strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); | |
| @@ -140,9 +134,7 @@ static int get_address(char *dev, int *htype) | |
| me.sll_family = AF_PACKET; | |
| me.sll_ifindex = ifr.ifr_ifindex; | |
| me.sll_protocol = htons(ETH_P_LOOP); | |
| - | if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { |
| - | bb_perror_msg_and_die("bind"); |
| - | } |
| + | xbind(s, (struct sockaddr*)&me, sizeof(me)); |
| alen = sizeof(me); | |
| if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { | |
| @@ -195,54 +187,63 @@ static int do_set(int argc, char **argv) | |
| struct ifreq ifr0, ifr1; | |
| char *newname = NULL; | |
| int htype, halen; | |
| + | static const char * const keywords[] = { |
| + | "up", "down", "name", "mtu", "multicast", "arp", "addr", "dev", |
| + | "on", "off", NULL |
| + | }; |
| + | enum { ARG_up = 1, ARG_down, ARG_name, ARG_mtu, ARG_multicast, ARG_arp, |
| + | ARG_addr, ARG_dev, PARM_on, PARM_off }; |
| + | smalluint key; |
| while (argc > 0) { | |
| - | if (strcmp(*argv, "up") == 0) { |
| + | key = index_in_str_array(keywords, *argv) + 1; |
| + | if (key == ARG_up) { |
| mask |= IFF_UP; | |
| flags |= IFF_UP; | |
| - | } else if (strcmp(*argv, "down") == 0) { |
| + | } else if (key == ARG_down) { |
| mask |= IFF_UP; | |
| flags &= ~IFF_UP; | |
| - | } else if (strcmp(*argv, "name") == 0) { |
| + | } else if (key == ARG_name) { |
| NEXT_ARG(); | |
| newname = *argv; | |
| - | } else if (strcmp(*argv, "mtu") == 0) { |
| + | } else if (key == ARG_mtu) { |
| NEXT_ARG(); | |
| if (mtu != -1) | |
| duparg("mtu", *argv); | |
| if (get_integer(&mtu, *argv, 0)) | |
| invarg(*argv, "mtu"); | |
| - | } else if (strcmp(*argv, "multicast") == 0) { |
| + | } else if (key == ARG_multicast) { |
| NEXT_ARG(); | |
| mask |= IFF_MULTICAST; | |
| - | if (strcmp(*argv, "on") == 0) { |
| + | key = index_in_str_array(keywords, *argv) + 1; |
| + | if (key == PARM_on) { |
| flags |= IFF_MULTICAST; | |
| - | } else if (strcmp(*argv, "off") == 0) { |
| + | } else if (key == PARM_off) { |
| flags &= ~IFF_MULTICAST; | |
| } else | |
| on_off("multicast"); | |
| - | } else if (strcmp(*argv, "arp") == 0) { |
| + | } else if (key == ARG_arp) { |
| NEXT_ARG(); | |
| mask |= IFF_NOARP; | |
| - | if (strcmp(*argv, "on") == 0) { |
| + | key = index_in_str_array(keywords, *argv) + 1; |
| + | if (key == PARM_on) { |
| flags &= ~IFF_NOARP; | |
| - | } else if (strcmp(*argv, "off") == 0) { |
| + | } else if (key == PARM_off) { |
| flags |= IFF_NOARP; | |
| } else | |
| - | on_off("noarp"); |
| - | } else if (strcmp(*argv, "addr") == 0) { |
| + | on_off("arp"); |
| + | } else if (key == ARG_addr) { |
| NEXT_ARG(); | |
| newaddr = *argv; | |
| } else { | |
| - | if (strcmp(*argv, "dev") == 0) { |
| + | if (key == ARG_dev) { |
| NEXT_ARG(); | |
| } | |
| if (dev) | |
| duparg2("dev", *argv); | |
| dev = *argv; | |
| } | |
| - | argc--; |
| - | argv++; |
| + | argc--; argv++; |
| } | |
| if (!dev) { | |
| @@ -291,16 +292,18 @@ static int ipaddr_list_link(int argc, char **argv) | |
| /* Return value becomes exitcode. It's okay to not return at all */ | |
| int do_iplink(int argc, char **argv) | |
| { | |
| + | static const char * const keywords[] = { |
| + | "set", "show", "lst", "list", NULL |
| + | }; |
| + | smalluint key; |
| if (argc <= 0) | |
| return ipaddr_list_link(0, NULL); | |
| - | |
| - | if (matches(*argv, "set") == 0) |
| - | return do_set(argc-1, argv+1); |
| - | |
| - | if (matches(*argv, "show") == 0 || |
| - | matches(*argv, "lst") == 0 || |
| - | matches(*argv, "list") == 0) |
| - | return ipaddr_list_link(argc-1, argv+1); |
| - | |
| - | bb_error_msg_and_die("command \"%s\" is unknown", *argv); |
| + | key = index_in_substr_array(keywords, *argv) + 1; |
| + | if (key == 0) |
| + | bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); |
| + | argc--; argv++; |
| + | if (key == 1) /* set */ |
| + | return do_set(argc, argv); |
| + | else /* show, lst, list */ |
| + | return ipaddr_list_link(argc, argv); |
| } | |
| @@ -102,10 +102,8 @@ static int print_route(struct sockaddr_nl *who ATTRIBUTE_UNUSED, | |
| if (filter.flushb && n->nlmsg_type != RTM_NEWROUTE) | |
| return 0; | |
| len -= NLMSG_LENGTH(sizeof(*r)); | |
| - | if (len < 0) { |
| - | bb_error_msg("wrong nlmsg len %d", len); |
| - | return -1; |
| - | } |
| + | if (len < 0) |
| + | bb_error_msg_and_die("wrong nlmsg len %d", len); |
| if (r->rtm_family == AF_INET6) | |
| host_len = 128; | |
| @@ -186,7 +184,7 @@ static int print_route(struct sockaddr_nl *who ATTRIBUTE_UNUSED, | |
| struct nlmsghdr *fn; | |
| if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { | |
| if (flush_update()) | |
| - | return -1; |
| + | bb_error_msg_and_die("flush"); |
| } | |
| fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp)); | |
| memcpy(fn, n, n->nlmsg_len); | |
| @@ -410,9 +408,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) | |
| argc--; argv++; | |
| } | |
| - | if (rtnl_open(&rth, 0) < 0) { |
| - | return 1; |
| - | } |
| + | xrtnl_open(&rth); |
| if (d) { | |
| int idx; | |
| @@ -420,10 +416,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) | |
| ll_init_map(&rth); | |
| if (d) { | |
| - | idx = ll_name_to_index(d); |
| - | if (idx == 0) { |
| - | bb_error_msg_and_die("cannot find device \"%s\"", d); |
| - | } |
| + | idx = xll_name_to_index(d); |
| addattr32(&req.n, sizeof(req), RTA_OIF, idx); | |
| } | |
| } | |
| @@ -478,7 +471,7 @@ static int rtnl_rtcache_request(struct rtnl_handle *rth, int family) | |
| req.rtm.rtm_family = family; | |
| req.rtm.rtm_flags |= RTM_F_CLONED; | |
| - | return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); |
| + | return xsendto(rth->fd, (void*)&req, sizeof(req), (struct sockaddr*)&nladdr, sizeof(nladdr)); |
| } | |
| static void iproute_flush_cache(void) | |
| @@ -592,9 +585,7 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) | |
| do_ipv6 = AF_INET; | |
| } | |
| - | if (rtnl_open(&rth, 0) < 0) { |
| - | return 1; |
| - | } |
| + | xrtnl_open(&rth); |
| ll_init_map(&rth); | |
| @@ -602,18 +593,12 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) | |
| int idx; | |
| if (id) { | |
| - | idx = ll_name_to_index(id); |
| - | if (idx == 0) { |
| - | bb_error_msg_and_die("cannot find device \"%s\"", id); |
| - | } |
| + | idx = xll_name_to_index(id); |
| filter.iif = idx; | |
| filter.iifmask = -1; | |
| } | |
| if (od) { | |
| - | idx = ll_name_to_index(od); |
| - | if (idx == 0) { |
| - | bb_error_msg("cannot find device \"%s\"", od); |
| - | } |
| + | idx = xll_name_to_index(od); |
| filter.oif = idx; | |
| filter.oifmask = -1; | |
| } | |
| @@ -635,13 +620,9 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) | |
| filter.rth = &rth; | |
| for (;;) { | |
| - | if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) { |
| - | bb_perror_msg_and_die("cannot send dump request"); |
| - | } |
| + | xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE); |
| filter.flushed = 0; | |
| - | if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) { |
| - | bb_error_msg_and_die("flush terminated"); |
| - | } |
| + | xrtnl_dump_filter(&rth, print_route, stdout); |
| if (filter.flushed == 0) { | |
| return 0; | |
| } | |
| @@ -651,18 +632,13 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) | |
| } | |
| if (filter.tb != -1) { | |
| - | if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) { |
| - | bb_perror_msg_and_die("cannot send dump request"); |
| - | } |
| + | xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE); |
| } else { | |
| if (rtnl_rtcache_request(&rth, do_ipv6) < 0) { | |
| bb_perror_msg_and_die("cannot send dump request"); | |
| } | |
| } | |
| - | |
| - | if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) { |
| - | bb_error_msg_and_die("dump terminated"); |
| - | } |
| + | xrtnl_dump_filter(&rth, print_route, stdout); |
| return 0; | |
| } | |
| @@ -755,8 +731,7 @@ static int iproute_get(int argc, char **argv) | |
| bb_error_msg_and_die("need at least destination address"); | |
| } | |
| - | if (rtnl_open(&rth, 0) < 0) |
| - | return 1; |
| + | xrtnl_open(&rth); |
| ll_init_map(&rth); | |
| @@ -764,17 +739,11 @@ static int iproute_get(int argc, char **argv) | |
| int idx; | |
| if (idev) { | |
| - | idx = ll_name_to_index(idev); |
| - | if (idx == 0) { |
| - | bb_error_msg_and_die("cannot find device \"%s\"", idev); |
| - | } |
| + | idx = xll_name_to_index(idev); |
| addattr32(&req.n, sizeof(req), RTA_IIF, idx); | |
| } | |
| if (odev) { | |
| - | idx = ll_name_to_index(odev); |
| - | if (idx == 0) { |
| - | bb_error_msg_and_die("cannot find device \"%s\"", odev); |
| - | } |
| + | idx = xll_name_to_index(odev); |
| addattr32(&req.n, sizeof(req), RTA_OIF, idx); | |
| } | |
| } | |
| @@ -792,9 +761,7 @@ static int iproute_get(int argc, char **argv) | |
| int len = req.n.nlmsg_len; | |
| struct rtattr * tb[RTA_MAX+1]; | |
| - | if (print_route(NULL, &req.n, (void*)stdout) < 0) { |
| - | bb_error_msg_and_die("an error :-)"); |
| - | } |
| + | print_route(NULL, &req.n, (void*)stdout); |
| if (req.n.nlmsg_type != RTM_NEWROUTE) { | |
| bb_error_msg_and_die("not a route?"); | |
| @@ -829,12 +796,7 @@ static int iproute_get(int argc, char **argv) | |
| return 2; | |
| } | |
| } | |
| - | |
| - | if (print_route(NULL, &req.n, (void*)stdout) < 0) { |
| - | // how is this useful? |
| - | bb_error_msg_and_die("an error :-)"); |
| - | } |
| - | |
| + | print_route(NULL, &req.n, (void*)stdout); |
| return 0; | |
| } | |
| @@ -175,16 +175,10 @@ static int iprule_list(int argc, char **argv) | |
| return -1; | |
| } | |
| - | if (rtnl_open(&rth, 0) < 0) |
| - | return 1; |
| + | xrtnl_open(&rth); |
| - | if (rtnl_wilddump_request(&rth, af, RTM_GETRULE) < 0) { |
| - | bb_perror_msg_and_die("cannot send dump request"); |
| - | } |
| - | |
| - | if (rtnl_dump_filter(&rth, print_rule, stdout, NULL, NULL) < 0) { |
| - | bb_error_msg_and_die("dump terminated"); |
| - | } |
| + | xrtnl_wilddump_request(&rth, af, RTM_GETRULE); |
| + | xrtnl_dump_filter(&rth, print_rule, stdout); |
| return 0; | |
| } | |
| @@ -296,8 +290,7 @@ static int iprule_modify(int cmd, int argc, char **argv) | |
| if (!table_ok && cmd == RTM_NEWRULE) | |
| req.r.rtm_table = RT_TABLE_MAIN; | |
| - | if (rtnl_open(&rth, 0) < 0) |
| - | return 1; |
| + | xrtnl_open(&rth); |
| if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) | |
| return 2; | |
| @@ -28,44 +28,31 @@ void rtnl_close(struct rtnl_handle *rth) | |
| close(rth->fd); | |
| } | |
| - | int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions) |
| + | int xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/) |
| { | |
| socklen_t addr_len; | |
| memset(rth, 0, sizeof(rth)); | |
| - | rth->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); |
| - | if (rth->fd < 0) { |
| - | bb_perror_msg("cannot open netlink socket"); |
| - | return -1; |
| - | } |
| + | rth->fd = xsocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); |
| memset(&rth->local, 0, sizeof(rth->local)); | |
| rth->local.nl_family = AF_NETLINK; | |
| - | rth->local.nl_groups = subscriptions; |
| + | /*rth->local.nl_groups = subscriptions;*/ |
| - | if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) { |
| - | bb_perror_msg("cannot bind netlink socket"); |
| - | return -1; |
| - | } |
| + | xbind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)); |
| addr_len = sizeof(rth->local); | |
| - | if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) { |
| - | bb_perror_msg("cannot getsockname"); |
| - | return -1; |
| - | } |
| - | if (addr_len != sizeof(rth->local)) { |
| - | bb_error_msg("wrong address length %d", addr_len); |
| - | return -1; |
| - | } |
| - | if (rth->local.nl_family != AF_NETLINK) { |
| - | bb_error_msg("wrong address family %d", rth->local.nl_family); |
| - | return -1; |
| - | } |
| + | if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) |
| + | bb_perror_msg_and_die("cannot getsockname"); |
| + | if (addr_len != sizeof(rth->local)) |
| + | bb_error_msg_and_die("wrong address length %d", addr_len); |
| + | if (rth->local.nl_family != AF_NETLINK) |
| + | bb_error_msg_and_die("wrong address family %d", rth->local.nl_family); |
| rth->seq = time(NULL); | |
| return 0; | |
| } | |
| - | int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) |
| + | int xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) |
| { | |
| struct { | |
| struct nlmsghdr nlh; | |
| @@ -83,7 +70,8 @@ int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) | |
| req.nlh.nlmsg_seq = rth->dump = ++rth->seq; | |
| req.g.rtgen_family = family; | |
| - | return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); |
| + | return xsendto(rth->fd, (void*)&req, sizeof(req), |
| + | (struct sockaddr*)&nladdr, sizeof(nladdr)); |
| } | |
| int rtnl_send(struct rtnl_handle *rth, char *buf, int len) | |
| @@ -93,7 +81,7 @@ int rtnl_send(struct rtnl_handle *rth, char *buf, int len) | |
| memset(&nladdr, 0, sizeof(nladdr)); | |
| nladdr.nl_family = AF_NETLINK; | |
| - | return sendto(rth->fd, buf, len, 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); |
| + | return xsendto(rth->fd, buf, len, (struct sockaddr*)&nladdr, sizeof(nladdr)); |
| } | |
| int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) | |
| @@ -120,11 +108,11 @@ int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) | |
| return sendmsg(rth->fd, &msg, 0); | |
| } | |
| - | int rtnl_dump_filter(struct rtnl_handle *rth, |
| + | static int rtnl_dump_filter(struct rtnl_handle *rth, |
| int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *), | |
| - | void *arg1, |
| + | void *arg1/*, |
| int (*junk)(struct sockaddr_nl *, struct nlmsghdr *n, void *), | |
| - | void *arg2) |
| + | void *arg2*/) |
| { | |
| char buf[8192]; | |
| struct sockaddr_nl nladdr; | |
| @@ -164,12 +152,11 @@ int rtnl_dump_filter(struct rtnl_handle *rth, | |
| if (nladdr.nl_pid != 0 || | |
| h->nlmsg_pid != rth->local.nl_pid || | |
| h->nlmsg_seq != rth->dump) { | |
| - | if (junk) { |
| + | /* if (junk) { |
| err = junk(&nladdr, h, arg2); | |
| - | if (err < 0) { |
| + | if (err < 0) |
| return err; | |
| - | } |
| - | } |
| + | } */ |
| goto skip_it; | |
| } | |
| @@ -187,9 +174,8 @@ int rtnl_dump_filter(struct rtnl_handle *rth, | |
| return -1; | |
| } | |
| err = filter(&nladdr, h, arg1); | |
| - | if (err < 0) { |
| + | if (err < 0) |
| return err; | |
| - | } |
| skip_it: | |
| h = NLMSG_NEXT(h, status); | |
| @@ -204,6 +190,16 @@ skip_it: | |
| } | |
| } | |
| + | int xrtnl_dump_filter(struct rtnl_handle *rth, |
| + | int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *), |
| + | void *arg1) |
| + | { |
| + | int ret = rtnl_dump_filter(rth, filter, arg1/*, NULL, NULL*/); |
| + | if (ret < 0) |
| + | bb_error_msg_and_die("dump terminated"); |
| + | return ret; |
| + | } |
| + | |
| int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, | |
| unsigned groups, struct nlmsghdr *answer, | |
| int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *), | |
| @@ -17,15 +17,13 @@ struct rtnl_handle | |
| uint32_t dump; | |
| }; | |
| - | extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions); |
| + | extern int xrtnl_open(struct rtnl_handle *rth); |
| extern void rtnl_close(struct rtnl_handle *rth); | |
| - | extern int rtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type); |
| + | extern int xrtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type); |
| extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len); | |
| - | extern int rtnl_dump_filter(struct rtnl_handle *rth, |
| + | extern int xrtnl_dump_filter(struct rtnl_handle *rth, |
| int (*filter)(struct sockaddr_nl*, struct nlmsghdr *n, void*), | |
| - | void *arg1, |
| - | int (*junk)(struct sockaddr_nl *, struct nlmsghdr *n, void *), |
| - | void *arg2); |
| + | void *arg1); |
| extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, | |
| unsigned groups, struct nlmsghdr *answer, | |
| int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *), | |
| @@ -128,7 +128,7 @@ unsigned ll_index_to_flags(int idx) | |
| } | |
| // TODO: caching is not warranted - no users which repeatedly call it | |
| - | int ll_name_to_index(char *name) |
| + | int xll_name_to_index(const char * const name) |
| { | |
| static char ncache[16]; | |
| static int icache; | |
| @@ -136,17 +136,21 @@ int ll_name_to_index(char *name) | |
| struct idxmap *im; | |
| int sock_fd; | |
| int i; | |
| + | int ret = 0; |
| if (name == NULL) | |
| - | return 0; |
| - | if (icache && strcmp(name, ncache) == 0) |
| - | return icache; |
| + | goto out; |
| + | if (icache && strcmp(name, ncache) == 0) { |
| + | ret = icache; |
| + | goto out; |
| + | } |
| for (i = 0; i < 16; i++) { | |
| for (im = idxmap[i]; im; im = im->next) { | |
| if (strcmp(im->name, name) == 0) { | |
| icache = im->index; | |
| strcpy(ncache, name); | |
| - | return im->index; |
| + | ret = im->index; |
| + | goto out; |
| } | |
| } | |
| } | |
| @@ -160,29 +164,26 @@ int ll_name_to_index(char *name) | |
| sock_fd = socket(AF_INET, SOCK_DGRAM, 0); | |
| if (sock_fd) { | |
| struct ifreq ifr; | |
| - | int ret; |
| + | int tmp; |
| strncpy(ifr.ifr_name, name, IFNAMSIZ); | |
| ifr.ifr_ifindex = -1; | |
| - | ret = ioctl(sock_fd, SIOCGIFINDEX, &ifr); |
| + | tmp = ioctl(sock_fd, SIOCGIFINDEX, &ifr); |
| close(sock_fd); | |
| - | if (ret >= 0) |
| + | if (tmp >= 0) |
| /* In theory, we should redump the interface list | |
| * to update our cache, this is left as an exercise | |
| * to the reader... Jean II */ | |
| - | return ifr.ifr_ifindex; |
| + | ret = ifr.ifr_ifindex; |
| } | |
| - | |
| - | return 0; |
| + | out: |
| + | if (ret <= 0) |
| + | bb_error_msg_and_die("cannot find device \"%s\"", name); |
| + | return ret; |
| } | |
| int ll_init_map(struct rtnl_handle *rth) | |
| { | |
| - | if (rtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK) < 0) { |
| - | bb_perror_msg_and_die("cannot send dump request"); |
| - | } |
| - | |
| - | if (rtnl_dump_filter(rth, ll_remember_index, &idxmap, NULL, NULL) < 0) { |
| - | bb_error_msg_and_die("dump terminated"); |
| - | } |
| + | xrtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK); |
| + | xrtnl_dump_filter(rth, ll_remember_index, &idxmap); |
| return 0; | |
| } | |
| @@ -4,7 +4,7 @@ | |
| extern int ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); | |
| extern int ll_init_map(struct rtnl_handle *rth); | |
| - | extern int ll_name_to_index(char *name); |
| + | extern int xll_name_to_index(const char * const name); |
| extern const char *ll_index_to_name(int idx); | |
| extern const char *ll_idx_n2a(int idx, char *buf); | |
| extern int ll_index_to_type(int idx); | |
| @@ -78,7 +78,7 @@ extern const char *rt_addr_n2a(int af, int len, void *addr, char *buf, int bufle | |
| void invarg(const char *, const char *) ATTRIBUTE_NORETURN; | |
| void duparg(const char *, const char *) ATTRIBUTE_NORETURN; | |
| void duparg2(const char *, const char *) ATTRIBUTE_NORETURN; | |
| - | int ATTRIBUTE_DEPRECATED matches(const char *arg, const char *pattern); |
| + | int /*ATTRIBUTE_DEPRECATED*/ matches(const char *arg, const char *pattern); |
| int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits); | |
| const char *dnet_ntop(int af, const void *addr, char *str, size_t len); | |
| @@ -101,15 +101,9 @@ static void ping4(len_and_sockaddr *lsa) | |
| pkt->icmp_type = ICMP_ECHO; | |
| pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet)); | |
| - | c = sendto(pingsock, packet, DEFDATALEN + ICMP_MINLEN, 0, |
| + | c = xsendto(pingsock, packet, DEFDATALEN + ICMP_MINLEN, |
| (struct sockaddr *) &pingaddr, sizeof(pingaddr)); | |
| - | if (c < 0) { |
| - | if (ENABLE_FEATURE_CLEAN_UP) |
| - | close(pingsock); |
| - | bb_perror_msg_and_die("sendto"); |
| - | } |
| - | |
| /* listen for replies */ | |
| while (1) { | |
| struct sockaddr_in from; | |
| @@ -153,15 +147,9 @@ static void ping6(len_and_sockaddr *lsa) | |
| sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); | |
| setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM, &sockopt, sizeof(sockopt)); | |
| - | c = sendto(pingsock, packet, DEFDATALEN + sizeof (struct icmp6_hdr), 0, |
| + | c = xsendto(pingsock, packet, DEFDATALEN + sizeof (struct icmp6_hdr), |
| (struct sockaddr *) &pingaddr, sizeof(pingaddr)); | |
| - | if (c < 0) { |
| - | if (ENABLE_FEATURE_CLEAN_UP) |
| - | close(pingsock); |
| - | bb_perror_msg_and_die("sendto"); |
| - | } |
| - | |
| /* listen for replies */ | |
| while (1) { | |
| struct sockaddr_in6 from; | |
| @@ -306,15 +294,12 @@ static void sendping_tail(void (*sp)(int), const void *pkt, int size_pkt) | |
| /* sizeof(pingaddr) can be larger than real sa size, but I think | |
| * it doesn't matter */ | |
| - | sz = sendto(pingsock, pkt, size_pkt, 0, &pingaddr.sa, sizeof(pingaddr)); |
| - | if (sz < 0) |
| - | bb_perror_msg_and_die("sendto"); |
| + | sz = xsendto(pingsock, pkt, size_pkt, &pingaddr.sa, sizeof(pingaddr)); |
| if (sz != size_pkt) | |
| - | bb_error_msg_and_die("ping wrote %d chars; %d expected", sz, |
| - | size_pkt); |
| + | bb_error_msg_and_die(bb_msg_write_error); |
| signal(SIGALRM, sp); | |
| - | if (pingcount == 0 || ntransmitted < pingcount) { /* schedule next in 1s */ |
| + | if (pingcount == 0 || ntransmitted < pingcount) { /* schedule next in 1s */ |
| alarm(PINGINTERVAL); | |
| } else { /* done, wait for the last ping to come back */ | |
| /* todo, don't necessarily need to wait so long... */ | |
| @@ -257,12 +257,7 @@ static int tftp( | |
| fprintf(stderr, "%02x ", (unsigned char) *cp); | |
| fprintf(stderr, "\n"); | |
| #endif | |
| - | if (sendto(socketfd, xbuf, len, 0, |
| - | &peer_lsa->sa, peer_lsa->len) < 0) { |
| - | bb_perror_msg("send"); |
| - | len = -1; |
| - | break; |
| - | } |
| + | xsendto(socketfd, xbuf, len, &peer_lsa->sa, peer_lsa->len); |
| if (finished && (opcode == TFTP_ACK)) { | |
| break; | |
| @@ -695,14 +695,11 @@ send_probe(int seq, int ttl, struct timeval *tp) | |
| } | |
| #endif | |
| - | cc = sendto(sndsock, (char *)outip, |
| - | packlen, 0, (struct sockaddr *)&whereto, sizeof(whereto)); |
| - | if (cc < 0 || cc != packlen) { |
| - | if (cc < 0) |
| - | bb_perror_msg_and_die("sendto"); |
| - | printf("%s: wrote %s %d chars, ret=%d\n", |
| - | applet_name, hostname, packlen, cc); |
| - | (void)fflush(stdout); |
| + | cc = xsendto(sndsock, (char *)outip, |
| + | packlen, (struct sockaddr *)&whereto, sizeof(whereto)); |
| + | if (cc != packlen) { |
| + | bb_info_msg("wrote %s %d chars, ret=%d", hostname, packlen, cc); |
| + | // (void)fflush(stdout); |
| } | |
| } | |
| @@ -114,10 +114,8 @@ static void arp(int fd, struct sockaddr *saddr, int op, | |
| memcpy(&p.arp.arp_tpa, &target_ip, sizeof(p.arp.arp_tpa)); | |
| // send it | |
| - | if (sendto(fd, &p, sizeof(p), 0, saddr, sizeof(*saddr)) < 0) { |
| - | bb_perror_msg("sendto"); |
| - | //return -errno; |
| - | } |
| + | xsendto(fd, &p, sizeof(p), saddr, sizeof(*saddr)); |
| + | |
| // Currently all callers ignore errors, that's why returns are | |
| // commented out... | |
| //return 0; | |