From f96419f48349766eb12da81e00c715bec6d837fb Mon Sep 17 00:00:00 2001 From: Antonio Huete Jimenez Date: Thu, 2 Aug 2012 19:39:08 +0200 Subject: [PATCH] dhclient - Add 'egress' command-line option. - It can be used to refetch a lease without remembering which interface dhclient was actually active on. Taken-from: OpenBSD --- sbin/dhclient/dhclient.c | 50 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index 64d80bbeed..a9ba6704ea 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: src/sbin/dhclient/dhclient.c,v 1.133 2010/03/25 18:37:36 stevesk Exp $ */ +/* $OpenBSD: src/sbin/dhclient/dhclient.c,v 1.136 2010/09/24 13:44:14 claudio Exp $ */ /* * Copyright 2004 Henning Brauer @@ -52,6 +52,7 @@ * the shell script can invoke the native tools to accomplish the same * purpose. */ +#include #include #include @@ -95,7 +96,7 @@ int ipv4addrs(char * buf); int res_hnok(const char *dn); char *option_as_string(unsigned int code, unsigned char *data, int len); int fork_privchld(int, int); - +void get_ifname(char *, char *); #define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) @@ -315,8 +316,7 @@ main(int argc, char *argv[]) if (config == NULL) error("config calloc"); - if (strlcpy(ifi->name, argv[0], IFNAMSIZ) >= IFNAMSIZ) - error("Interface name too long"); + get_ifname(ifi->name, argv[0]); if (path_dhclient_db == NULL && asprintf(&path_dhclient_db, "%s.%s", _PATH_DHCLIENT_DB, ifi->name) == -1) error("asprintf"); @@ -2185,3 +2185,45 @@ fork_privchld(int fd, int fd2) dispatch_imsg(fd); } } + +void +get_ifname(char *ifname, char *arg) +{ + struct ifgroupreq ifgr; + struct ifg_req *ifg; + int s, len; + + if (!strcmp(arg, "egress")) { + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s == -1) + error("socket error"); + bzero(&ifgr, sizeof(ifgr)); + strlcpy(ifgr.ifgr_name, "egress", sizeof(ifgr.ifgr_name)); + if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) { + if (errno == ENOENT) + error("no interface in group egress found"); + error("ioctl SIOCGIFGMEMB: %m"); + } + len = ifgr.ifgr_len; + if ((ifgr.ifgr_groups = calloc(1, len)) == NULL) + error("get_ifname"); + if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) + error("ioctl SIOCGIFGMEMB: %m"); + + arg = NULL; + for (ifg = ifgr.ifgr_groups; + ifg && len >= sizeof(struct ifg_req); ifg++) { + len -= sizeof(struct ifg_req); + if (arg) + error("too many interfaces in group egress"); + arg = ifg->ifgrq_member; + } + + if (strlcpy(ifi->name, arg, IFNAMSIZ) >= IFNAMSIZ) + error("Interface name too long: %m"); + + free(ifgr.ifgr_groups); + close(s); + } else if (strlcpy(ifi->name, arg, IFNAMSIZ) >= IFNAMSIZ) + error("Interface name too long"); +} -- 2.41.0