nameif: extended matching (Nico Erfurth <masta@perlgolf.de>)

*: whitespace fixes

function                                             old     new   delta
prepend_new_eth_table                                  -     304    +304
nameif_main                                          620     684     +64
cc_macaddr                                            51       -     -51
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 1/0 up/down: 368/-51)           Total: 317 bytes
This commit is contained in:
Denis Vlasenko 2007-12-24 14:09:19 +00:00
parent fcfb5c04bb
commit f7be20e70c
14 changed files with 180 additions and 91 deletions

View File

@ -66,7 +66,7 @@ typedef union {
struct BUG_zip_header_must_be_26_bytes {
char BUG_zip_header_must_be_26_bytes[
offsetof(zip_header_t, formatted.extra_len) + 2 ==
ZIP_HEADER_LEN ? 1 : -1];
ZIP_HEADER_LEN ? 1 : -1];
};
#define FIX_ENDIANNESS(zip_header) do { \

View File

@ -161,7 +161,7 @@ void usage(char *prog)
int main(int argc, char **argv)
{
blkid_dev_iterate iter;
blkid_cache cache = NULL;
blkid_cache cache = NULL;
blkid_dev dev;
int c, ret;
char *tmp;

View File

@ -364,7 +364,7 @@ void usage(char *prog)
int main(int argc, char **argv)
{
blkid_tag_iterate iter;
blkid_cache cache = NULL;
blkid_cache cache = NULL;
blkid_dev dev;
int c, ret, found;
int flags = BLKID_DEV_FIND;

View File

@ -76,7 +76,7 @@ The following steps will create a root file system.
- Make device files in /dev:
This can be done by running the 'mkdevs.sh' script. If you want the gory
This can be done by running the 'mkdevs.sh' script. If you want the gory
details, you can read the script.
- Make necessary files in /etc:

View File

@ -78,7 +78,7 @@ REGISTER ^radio0$ EXECUTE /bin/ln -sf radio0 radio
UNREGISTER ^radio0$ EXECUTE /bin/rm -f radio
# ALSA stuff
#LOOKUP snd MODLOAD ACTION snd
#LOOKUP snd MODLOAD ACTION snd
# Uncomment this to let PAM manage devfs
# Not supported by busybox

View File

@ -2,7 +2,7 @@
# The start and end of the IP lease block
start 192.168.0.20 #default: 192.168.0.20
start 192.168.0.20 #default: 192.168.0.20
end 192.168.0.254 #default: 192.168.0.254
@ -67,7 +67,7 @@ interface eth0 #default: eth0
#notify_file #default: (no script)
#notify_file dumpleases # <--- useful for debugging
#notify_file dumpleases # <--- useful for debugging
# The following are bootp specific options, setable by udhcpd.

View File

@ -549,6 +549,19 @@ config NAMEIF
# Comment
new_interface_name XX:XX:XX:XX:XX:XX
config FEATURE_NAMEIF_EXTENDED
bool "Extended nameif"
default n
depends on NAMEIF
help
This extends the nameif syntax to support the bus_info and driver
checks. The syntax is compatible to the normal nameif.
File format:
new_interface_name driver=asix bus=usb-0000:00:08.2-3
new_interface_name bus=usb-0000:00:08.2-3 00:80:C8:38:91:B5
new_interface_name mac=00:80:C8:38:91:B5
new_interface_name 00:80:C8:38:91:B5
config NC
bool "nc"
default n

View File

@ -13,7 +13,7 @@
#include <syslog.h>
#include <net/if.h>
#include <netinet/ether.h>
#include <linux/sockios.h>
/* Older versions of net/if.h do not appear to define IF_NAMESIZE. */
#ifndef IF_NAMESIZE
@ -34,138 +34,214 @@
#define ifr_newname ifr_ifru.ifru_slave
#endif
typedef struct mactable_s {
struct mactable_s *next;
struct mactable_s *prev;
typedef struct ethtable_s {
struct ethtable_s *next;
struct ethtable_s *prev;
char *ifname;
struct ether_addr *mac;
} mactable_t;
#if ENABLE_FEATURE_NAMEIF_EXTENDED
char *bus_info;
char *driver;
#endif
} ethtable_t;
/* Check ascii str_macaddr, convert and copy to *mac */
static struct ether_addr *cc_macaddr(const char *str_macaddr)
#if ENABLE_FEATURE_NAMEIF_EXTENDED
/* Cut'n'paste from ethtool.h */
#define ETHTOOL_BUSINFO_LEN 32
/* these strings are set to whatever the driver author decides... */
struct ethtool_drvinfo {
__u32 cmd;
char driver[32]; /* driver short name, "tulip", "eepro100" */
char version[32]; /* driver version string */
char fw_version[32]; /* firmware version string, if applicable */
char bus_info[ETHTOOL_BUSINFO_LEN]; /* Bus info for this IF. */
/* For PCI devices, use pci_dev->slot_name. */
char reserved1[32];
char reserved2[16];
__u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */
__u32 testinfo_len;
__u32 eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */
__u32 regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */
};
#define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */
#endif
static void nameif_parse_selector(ethtable_t *ch, char *selector)
{
struct ether_addr *lmac, *mac;
struct ether_addr *lmac;
#if ENABLE_FEATURE_NAMEIF_EXTENDED
int found_selector = 0;
lmac = ether_aton(str_macaddr);
if (lmac == NULL)
bb_error_msg_and_die("cannot parse MAC %s", str_macaddr);
mac = xmalloc(ETH_ALEN);
memcpy(mac, lmac, ETH_ALEN);
while (*selector) {
char *next;
#endif
selector = skip_whitespace(selector);
#if ENABLE_FEATURE_NAMEIF_EXTENDED
if (*selector == '\0')
break;
/* Search for the end .... */
next = skip_non_whitespace(selector);
if (*next)
*next++ = '\0';
/* Check for selectors, mac= is assumed */
if (strncmp(selector, "bus=", 4) == 0) {
ch->bus_info = xstrdup(selector + 4);
found_selector++;
} else if (strncmp(selector, "driver=", 7) == 0) {
ch->driver = xstrdup(selector + 7);
found_selector++;
} else {
#endif
lmac = ether_aton(selector + (strncmp(selector, "mac=", 4) == 0 ? 4 : 0));
/* Check ascii selector, convert and copy to *mac */
if (lmac == NULL)
bb_error_msg_and_die("cannot parse %s", selector);
ch->mac = xmalloc(ETH_ALEN);
memcpy(ch->mac, lmac, ETH_ALEN);
#if ENABLE_FEATURE_NAMEIF_EXTENDED
found_selector++;
};
selector = next;
}
if (found_selector == 0)
bb_error_msg_and_die("no selectors found for %s", ch->ifname);
#endif
}
return mac;
static void prepend_new_eth_table(ethtable_t **clist, char *ifname, char *selector)
{
ethtable_t *ch;
if (strlen(ifname) >= IF_NAMESIZE)
bb_error_msg_and_die("interface name '%s' too long", ifname);
ch = xzalloc(sizeof(*ch));
ch->ifname = ifname;
nameif_parse_selector(ch, selector);
ch->next = *clist;
if (*clist)
(*clist)->prev = ch;
*clist = ch;
}
int nameif_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int nameif_main(int argc, char **argv)
{
mactable_t *clist = NULL;
ethtable_t *clist = NULL;
FILE *ifh;
const char *fname = "/etc/mactab";
char *line;
char *line_ptr;
int linenum;
int ctl_sk;
int if_index = 1;
mactable_t *ch;
ethtable_t *ch;
if (1 & getopt32(argv, "sc:", &fname)) {
openlog(applet_name, 0, LOG_LOCAL0);
logmode = LOGMODE_SYSLOG;
}
argc -= optind;
argv += optind;
if ((argc - optind) & 1)
if (argc & 1)
bb_show_usage();
if (optind < argc) {
char **a = argv + optind;
while (*a) {
if (strlen(*a) > IF_NAMESIZE)
bb_error_msg_and_die("interface name '%s' "
"too long", *a);
ch = xzalloc(sizeof(mactable_t));
ch->ifname = xstrdup(*a++);
ch->mac = cc_macaddr(*a++);
if (clist)
clist->prev = ch;
ch->next = clist;
clist = ch;
if (argc) {
while (*argv) {
char *ifname = xstrdup(*argv++);
prepend_new_eth_table(&clist, ifname, *argv++);
}
} else {
ifh = xfopen(fname, "r");
while ((line = xmalloc_fgets(ifh)) != NULL) {
char *line_ptr;
size_t name_length;
char *next;
line_ptr = line + strspn(line, " \t");
line_ptr = skip_whitespace(line);
if ((line_ptr[0] == '#') || (line_ptr[0] == '\n')) {
free(line);
continue;
}
name_length = strcspn(line_ptr, " \t");
ch = xzalloc(sizeof(mactable_t));
ch->ifname = xstrndup(line_ptr, name_length);
if (name_length > IF_NAMESIZE)
bb_error_msg_and_die("interface name '%s' "
"too long", ch->ifname);
line_ptr += name_length;
line_ptr += strspn(line_ptr, " \t");
name_length = strspn(line_ptr, "0123456789ABCDEFabcdef:");
line_ptr[name_length] = '\0';
ch->mac = cc_macaddr(line_ptr);
if (clist)
clist->prev = ch;
ch->next = clist;
clist = ch;
next = skip_non_whitespace(line_ptr);
if (*next)
*next++ = '\0';
prepend_new_eth_table(&clist, line_ptr, next);
free(line);
}
fclose(ifh);
}
ctl_sk = xsocket(PF_INET, SOCK_DGRAM, 0);
ifh = xfopen("/proc/net/dev", "r");
linenum = 0;
while (clist) {
struct ifreq ifr;
#if ENABLE_FEATURE_NAMEIF_EXTENDED
struct ethtool_drvinfo drvinfo;
#endif
line = xmalloc_fgets(ifh);
if (line == NULL)
break; /* Seems like we're done */
if (linenum++ < 2 )
goto next_line; /* Skip the first two lines */
/* Find the current interface name and copy it to ifr.ifr_name */
line_ptr = skip_whitespace(line);
*skip_non_whitespace(line_ptr) = '\0';
memset(&ifr, 0, sizeof(struct ifreq));
if_index++;
ifr.ifr_ifindex = if_index;
strncpy(ifr.ifr_name, line_ptr, sizeof(ifr.ifr_name));
/* Get ifname by index or die */
if (ioctl(ctl_sk, SIOCGIFNAME, &ifr))
break;
#if ENABLE_FEATURE_NAMEIF_EXTENDED
/* Check for driver etc. */
memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo));
drvinfo.cmd = ETHTOOL_GDRVINFO;
ifr.ifr_data = (caddr_t) &drvinfo;
/* Get driver and businfo first, so we have it in drvinfo */
ioctl(ctl_sk, SIOCETHTOOL, &ifr);
#endif
ioctl(ctl_sk, SIOCGIFHWADDR, &ifr);
/* Has this device hwaddr? */
if (ioctl(ctl_sk, SIOCGIFHWADDR, &ifr))
continue;
/* Search for mac like in ifr.ifr_hwaddr.sa_data */
for (ch = clist; ch; ch = ch->next)
if (!memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN))
break;
/* Nothing found for current ifr.ifr_hwaddr.sa_data */
if (ch == NULL)
continue;
strcpy(ifr.ifr_newname, ch->ifname);
ioctl_or_perror_and_die(ctl_sk, SIOCSIFNAME, &ifr,
/* Search the list for a matching device */
for (ch = clist; ch; ch = ch->next) {
#if ENABLE_FEATURE_NAMEIF_EXTENDED
if (ch->bus_info && strcmp(ch->bus_info, drvinfo.bus_info) != 0)
continue;
if (ch->driver && strcmp(ch->driver, drvinfo.driver) != 0)
continue;
#endif
if (ch->mac && memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN) != 0)
continue;
/* if we came here, all selectors have matched */
goto found;
}
/* Nothing found for current interface */
goto next_line;
found:
if (strcmp(ifr.ifr_name, ch->ifname) != 0) {
strcpy(ifr.ifr_newname, ch->ifname);
ioctl_or_perror_and_die(ctl_sk, SIOCSIFNAME, &ifr,
"cannot change ifname %s to %s",
ifr.ifr_name, ch->ifname);
/* Remove list entry of renamed interface */
if (ch->prev != NULL) {
(ch->prev)->next = ch->next;
} else {
clist = ch->next;
}
/* Remove list entry of renamed interface */
if (ch->prev != NULL)
ch->prev->next = ch->next;
else
clist = ch->next;
if (ch->next != NULL)
(ch->next)->prev = ch->prev;
ch->next->prev = ch->prev;
if (ENABLE_FEATURE_CLEAN_UP) {
free(ch->ifname);
free(ch->mac);
free(ch);
}
next_line:
free(line);
}
if (ENABLE_FEATURE_CLEAN_UP) {
fclose(ifh);
};
return 0;
}

View File

@ -165,7 +165,7 @@ int more_main(int argc, char **argv)
if (c == '\t') {
spaces = CONVERTED_TAB_SIZE - 1;
c = ' ';
}
}
/*
* There are two input streams to worry about here: