- add xsendto and use where appropriate; shrink iplink; sanitize libiproute a bit.
-916 byte
This commit is contained in:
parent
51742f4bb0
commit
b290889f02
@ -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,12 +294,9 @@ 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 */
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user