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

@ -65,7 +65,7 @@ int main(int argc, char **argv)
i = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0666); i = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0666);
if (i < 0) if (i < 0)
return 1; return 1;
dup2(i, 1); dup2(i, 1);
/* Keep in sync with include/busybox.h! */ /* Keep in sync with include/busybox.h! */

View File

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

View File

@ -293,6 +293,6 @@ int echo_main(int argc, char **argv)
} }
ret: ret:
/* TODO: implement and use full_writev? */ /* TODO: implement and use full_writev? */
return writev(1, io, (cur_io - io)) >= 0; return writev(1, io, (cur_io - io)) >= 0;
} }
#endif #endif

View File

@ -182,7 +182,7 @@ int tr_main(int argc, char **argv)
ssize_t read_chars = 0; ssize_t read_chars = 0;
size_t in_index = 0, out_index = 0; size_t in_index = 0, out_index = 0;
unsigned last = UCHAR_MAX + 1; /* not equal to any char */ unsigned last = UCHAR_MAX + 1; /* not equal to any char */
unsigned char coded, c; unsigned char coded, c;
unsigned char *output = xmalloc(BUFSIZ); unsigned char *output = xmalloc(BUFSIZ);
char *vector = xzalloc((ASCII+1) * 3); char *vector = xzalloc((ASCII+1) * 3);
char *invec = vector + (ASCII+1); char *invec = vector + (ASCII+1);

View File

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

View File

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

View File

@ -120,7 +120,7 @@ instead of resuming at the top of the script.</p></dd>
<dt><b>N</b> [<em>address1</em>[,<em>address2</em>]]<b>N</b></dt> <dt><b>N</b> [<em>address1</em>[,<em>address2</em>]]<b>N</b></dt>
<dd>Append next input line to contents of pattern space; the new line is <dd>Append next input line to contents of pattern space; the new line is
separated from the previous contents of the pattern space by a newline. separated from the previous contents of the pattern space by a newline.
(This command is designed to allow pattern matches across two (This command is designed to allow pattern matches across two
lines. Using \n to match the embedded newline, you can match lines. Using \n to match the embedded newline, you can match
patterns across multiple lines.)</p></dd> patterns across multiple lines.)</p></dd>

View File

@ -76,7 +76,7 @@ The following steps will create a root file system.
- Make device files in /dev: - 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. details, you can read the script.
- Make necessary files in /etc: - 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 UNREGISTER ^radio0$ EXECUTE /bin/rm -f radio
# ALSA stuff # ALSA stuff
#LOOKUP snd MODLOAD ACTION snd #LOOKUP snd MODLOAD ACTION snd
# Uncomment this to let PAM manage devfs # Uncomment this to let PAM manage devfs
# Not supported by busybox # Not supported by busybox

View File

@ -2,7 +2,7 @@
# The start and end of the IP lease block # 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 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 #default: (no script)
#notify_file dumpleases # <--- useful for debugging #notify_file dumpleases # <--- useful for debugging
# The following are bootp specific options, setable by udhcpd. # The following are bootp specific options, setable by udhcpd.

View File

@ -136,7 +136,7 @@ static struct statics *const ptr_to_statics __attribute__ ((section (".data")));
#define command_ps (S.command_ps ) #define command_ps (S.command_ps )
#define cmdedit_prompt (S.cmdedit_prompt ) #define cmdedit_prompt (S.cmdedit_prompt )
#define num_ok_lines (S.num_ok_lines ) #define num_ok_lines (S.num_ok_lines )
#define user_buf (S.user_buf ) #define user_buf (S.user_buf )
#define home_pwd_buf (S.home_pwd_buf ) #define home_pwd_buf (S.home_pwd_buf )
#define matches (S.matches ) #define matches (S.matches )
#define num_matches (S.num_matches ) #define num_matches (S.num_matches )

View File

@ -549,6 +549,19 @@ config NAMEIF
# Comment # Comment
new_interface_name XX:XX:XX:XX:XX:XX 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 config NC
bool "nc" bool "nc"
default n default n

View File

@ -13,7 +13,7 @@
#include <syslog.h> #include <syslog.h>
#include <net/if.h> #include <net/if.h>
#include <netinet/ether.h> #include <netinet/ether.h>
#include <linux/sockios.h>
/* Older versions of net/if.h do not appear to define IF_NAMESIZE. */ /* Older versions of net/if.h do not appear to define IF_NAMESIZE. */
#ifndef IF_NAMESIZE #ifndef IF_NAMESIZE
@ -34,138 +34,214 @@
#define ifr_newname ifr_ifru.ifru_slave #define ifr_newname ifr_ifru.ifru_slave
#endif #endif
typedef struct mactable_s { typedef struct ethtable_s {
struct mactable_s *next; struct ethtable_s *next;
struct mactable_s *prev; struct ethtable_s *prev;
char *ifname; char *ifname;
struct ether_addr *mac; 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 */ #if ENABLE_FEATURE_NAMEIF_EXTENDED
static struct ether_addr *cc_macaddr(const char *str_macaddr) /* 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); while (*selector) {
if (lmac == NULL) char *next;
bb_error_msg_and_die("cannot parse MAC %s", str_macaddr); #endif
mac = xmalloc(ETH_ALEN); selector = skip_whitespace(selector);
memcpy(mac, lmac, ETH_ALEN); #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) MAIN_EXTERNALLY_VISIBLE;
int nameif_main(int argc, char **argv) int nameif_main(int argc, char **argv)
{ {
mactable_t *clist = NULL; ethtable_t *clist = NULL;
FILE *ifh; FILE *ifh;
const char *fname = "/etc/mactab"; const char *fname = "/etc/mactab";
char *line; char *line;
char *line_ptr;
int linenum;
int ctl_sk; int ctl_sk;
int if_index = 1; ethtable_t *ch;
mactable_t *ch;
if (1 & getopt32(argv, "sc:", &fname)) { if (1 & getopt32(argv, "sc:", &fname)) {
openlog(applet_name, 0, LOG_LOCAL0); openlog(applet_name, 0, LOG_LOCAL0);
logmode = LOGMODE_SYSLOG; logmode = LOGMODE_SYSLOG;
} }
argc -= optind;
argv += optind;
if ((argc - optind) & 1) if (argc & 1)
bb_show_usage(); bb_show_usage();
if (optind < argc) { if (argc) {
char **a = argv + optind; while (*argv) {
char *ifname = xstrdup(*argv++);
while (*a) { prepend_new_eth_table(&clist, ifname, *argv++);
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;
} }
} else { } else {
ifh = xfopen(fname, "r"); ifh = xfopen(fname, "r");
while ((line = xmalloc_fgets(ifh)) != NULL) { while ((line = xmalloc_fgets(ifh)) != NULL) {
char *line_ptr; char *next;
size_t name_length;
line_ptr = line + strspn(line, " \t"); line_ptr = skip_whitespace(line);
if ((line_ptr[0] == '#') || (line_ptr[0] == '\n')) { if ((line_ptr[0] == '#') || (line_ptr[0] == '\n')) {
free(line); free(line);
continue; continue;
} }
name_length = strcspn(line_ptr, " \t"); next = skip_non_whitespace(line_ptr);
ch = xzalloc(sizeof(mactable_t)); if (*next)
ch->ifname = xstrndup(line_ptr, name_length); *next++ = '\0';
if (name_length > IF_NAMESIZE) prepend_new_eth_table(&clist, line_ptr, next);
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;
free(line); free(line);
} }
fclose(ifh); fclose(ifh);
} }
ctl_sk = xsocket(PF_INET, SOCK_DGRAM, 0); ctl_sk = xsocket(PF_INET, SOCK_DGRAM, 0);
ifh = xfopen("/proc/net/dev", "r");
linenum = 0;
while (clist) { while (clist) {
struct ifreq ifr; 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)); memset(&ifr, 0, sizeof(struct ifreq));
if_index++; strncpy(ifr.ifr_name, line_ptr, sizeof(ifr.ifr_name));
ifr.ifr_ifindex = if_index;
/* Get ifname by index or die */ #if ENABLE_FEATURE_NAMEIF_EXTENDED
if (ioctl(ctl_sk, SIOCGIFNAME, &ifr)) /* Check for driver etc. */
break; 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? */ /* Search the list for a matching device */
if (ioctl(ctl_sk, SIOCGIFHWADDR, &ifr)) for (ch = clist; ch; ch = ch->next) {
continue; #if ENABLE_FEATURE_NAMEIF_EXTENDED
if (ch->bus_info && strcmp(ch->bus_info, drvinfo.bus_info) != 0)
/* Search for mac like in ifr.ifr_hwaddr.sa_data */ continue;
for (ch = clist; ch; ch = ch->next) if (ch->driver && strcmp(ch->driver, drvinfo.driver) != 0)
if (!memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN)) continue;
break; #endif
if (ch->mac && memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN) != 0)
/* Nothing found for current ifr.ifr_hwaddr.sa_data */ continue;
if (ch == NULL) /* if we came here, all selectors have matched */
continue; goto found;
}
strcpy(ifr.ifr_newname, ch->ifname); /* Nothing found for current interface */
ioctl_or_perror_and_die(ctl_sk, SIOCSIFNAME, &ifr, 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", "cannot change ifname %s to %s",
ifr.ifr_name, ch->ifname); 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) if (ch->next != NULL)
(ch->next)->prev = ch->prev; ch->next->prev = ch->prev;
if (ENABLE_FEATURE_CLEAN_UP) { if (ENABLE_FEATURE_CLEAN_UP) {
free(ch->ifname); free(ch->ifname);
free(ch->mac); free(ch->mac);
free(ch); free(ch);
} }
next_line:
free(line);
} }
if (ENABLE_FEATURE_CLEAN_UP) {
fclose(ifh);
};
return 0; return 0;
} }

View File

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