diff options
Diffstat (limited to 'networking/nameif.c')
-rw-r--r-- | networking/nameif.c | 115 |
1 files changed, 103 insertions, 12 deletions
diff --git a/networking/nameif.c b/networking/nameif.c index d02c2c11b..78719edac 100644 --- a/networking/nameif.c +++ b/networking/nameif.c | |||
@@ -10,6 +10,66 @@ | |||
10 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 10 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | //config:config NAMEIF | ||
14 | //config: bool "nameif" | ||
15 | //config: default y | ||
16 | //config: select PLATFORM_LINUX | ||
17 | //config: select FEATURE_SYSLOG | ||
18 | //config: help | ||
19 | //config: nameif is used to rename network interface by its MAC address. | ||
20 | //config: Renamed interfaces MUST be in the down state. | ||
21 | //config: It is possible to use a file (default: /etc/mactab) | ||
22 | //config: with list of new interface names and MACs. | ||
23 | //config: Maximum interface name length: IFNAMSIZ = 16 | ||
24 | //config: File fields are separated by space or tab. | ||
25 | //config: File format: | ||
26 | //config: # Comment | ||
27 | //config: new_interface_name XX:XX:XX:XX:XX:XX | ||
28 | //config: | ||
29 | //config:config FEATURE_NAMEIF_EXTENDED | ||
30 | //config: bool "Extended nameif" | ||
31 | //config: default y | ||
32 | //config: depends on NAMEIF | ||
33 | //config: help | ||
34 | //config: This extends the nameif syntax to support the bus_info, driver, | ||
35 | //config: phyaddr selectors. The syntax is compatible to the normal nameif. | ||
36 | //config: File format: | ||
37 | //config: new_interface_name driver=asix bus=usb-0000:00:08.2-3 | ||
38 | //config: new_interface_name bus=usb-0000:00:08.2-3 00:80:C8:38:91:B5 | ||
39 | //config: new_interface_name phy_address=2 00:80:C8:38:91:B5 | ||
40 | //config: new_interface_name mac=00:80:C8:38:91:B5 | ||
41 | //config: new_interface_name 00:80:C8:38:91:B5 | ||
42 | |||
43 | //usage:#define nameif_trivial_usage | ||
44 | //usage: IF_NOT_FEATURE_NAMEIF_EXTENDED( | ||
45 | //usage: "[-s] [-c FILE] [IFNAME HWADDR]..." | ||
46 | //usage: ) | ||
47 | //usage: IF_FEATURE_NAMEIF_EXTENDED( | ||
48 | //usage: "[-s] [-c FILE] [IFNAME SELECTOR]..." | ||
49 | //usage: ) | ||
50 | //usage:#define nameif_full_usage "\n\n" | ||
51 | //usage: "Rename network interface while it in the down state." | ||
52 | //usage: IF_NOT_FEATURE_NAMEIF_EXTENDED( | ||
53 | //usage: "\nThe device with address HWADDR is renamed to IFACE." | ||
54 | //usage: ) | ||
55 | //usage: IF_FEATURE_NAMEIF_EXTENDED( | ||
56 | //usage: "\nThe device matched by SELECTOR is renamed to IFACE." | ||
57 | //usage: "\nSELECTOR can be a combination of:" | ||
58 | //usage: "\n driver=STRING" | ||
59 | //usage: "\n bus=STRING" | ||
60 | //usage: "\n phy_address=NUM" | ||
61 | //usage: "\n [mac=]XX:XX:XX:XX:XX:XX" | ||
62 | //usage: ) | ||
63 | //usage: "\n" | ||
64 | //usage: "\nOptions:" | ||
65 | //usage: "\n -c FILE Configuration file (default: /etc/mactab)" | ||
66 | //usage: "\n -s Log to syslog" | ||
67 | //usage: | ||
68 | //usage:#define nameif_example_usage | ||
69 | //usage: "$ nameif -s dmz0 00:A0:C9:8C:F6:3F\n" | ||
70 | //usage: " or\n" | ||
71 | //usage: "$ nameif -c /etc/my_mactab_file\n" | ||
72 | |||
13 | #include "libbb.h" | 73 | #include "libbb.h" |
14 | #include <syslog.h> | 74 | #include <syslog.h> |
15 | #include <net/if.h> | 75 | #include <net/if.h> |
@@ -38,6 +98,7 @@ typedef struct ethtable_s { | |||
38 | #if ENABLE_FEATURE_NAMEIF_EXTENDED | 98 | #if ENABLE_FEATURE_NAMEIF_EXTENDED |
39 | char *bus_info; | 99 | char *bus_info; |
40 | char *driver; | 100 | char *driver; |
101 | int32_t phy_address; | ||
41 | #endif | 102 | #endif |
42 | } ethtable_t; | 103 | } ethtable_t; |
43 | 104 | ||
@@ -59,6 +120,25 @@ struct ethtool_drvinfo { | |||
59 | uint32_t eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */ | 120 | uint32_t eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */ |
60 | uint32_t regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */ | 121 | uint32_t regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */ |
61 | }; | 122 | }; |
123 | |||
124 | struct ethtool_cmd { | ||
125 | __u32 cmd; | ||
126 | __u32 supported; /* Features this interface supports */ | ||
127 | __u32 advertising; /* Features this interface advertises */ | ||
128 | __u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */ | ||
129 | __u8 duplex; /* Duplex, half or full */ | ||
130 | __u8 port; /* Which connector port */ | ||
131 | __u8 phy_address; | ||
132 | __u8 transceiver; /* Which transceiver to use */ | ||
133 | __u8 autoneg; /* Enable or disable autonegotiation */ | ||
134 | __u32 maxtxpkt; /* Tx pkts before generating tx int */ | ||
135 | __u32 maxrxpkt; /* Rx pkts before generating rx int */ | ||
136 | __u16 speed_hi; | ||
137 | __u16 reserved2; | ||
138 | __u32 reserved[3]; | ||
139 | }; | ||
140 | |||
141 | #define ETHTOOL_GSET 0x00000001 /* Get settings. */ | ||
62 | #define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */ | 142 | #define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */ |
63 | #endif | 143 | #endif |
64 | 144 | ||
@@ -74,6 +154,7 @@ static void nameif_parse_selector(ethtable_t *ch, char *selector) | |||
74 | #endif | 154 | #endif |
75 | selector = skip_whitespace(selector); | 155 | selector = skip_whitespace(selector); |
76 | #if ENABLE_FEATURE_NAMEIF_EXTENDED | 156 | #if ENABLE_FEATURE_NAMEIF_EXTENDED |
157 | ch->phy_address = -1; | ||
77 | if (*selector == '\0') | 158 | if (*selector == '\0') |
78 | break; | 159 | break; |
79 | /* Search for the end .... */ | 160 | /* Search for the end .... */ |
@@ -87,6 +168,9 @@ static void nameif_parse_selector(ethtable_t *ch, char *selector) | |||
87 | } else if (strncmp(selector, "driver=", 7) == 0) { | 168 | } else if (strncmp(selector, "driver=", 7) == 0) { |
88 | ch->driver = xstrdup(selector + 7); | 169 | ch->driver = xstrdup(selector + 7); |
89 | found_selector++; | 170 | found_selector++; |
171 | } else if (strncmp(selector, "phyaddr=", 8) == 0) { | ||
172 | ch->phy_address = xatoi_positive(selector + 8); | ||
173 | found_selector++; | ||
90 | } else { | 174 | } else { |
91 | #endif | 175 | #endif |
92 | lmac = xmalloc(ETH_ALEN); | 176 | lmac = xmalloc(ETH_ALEN); |
@@ -133,7 +217,7 @@ void delete_eth_table(ethtable_t *ch); | |||
133 | #endif | 217 | #endif |
134 | 218 | ||
135 | int nameif_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 219 | int nameif_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
136 | int nameif_main(int argc, char **argv) | 220 | int nameif_main(int argc UNUSED_PARAM, char **argv) |
137 | { | 221 | { |
138 | ethtable_t *clist = NULL; | 222 | ethtable_t *clist = NULL; |
139 | const char *fname = "/etc/mactab"; | 223 | const char *fname = "/etc/mactab"; |
@@ -148,17 +232,15 @@ int nameif_main(int argc, char **argv) | |||
148 | * can't hurt. 2>/dev/null if you don't like it: */ | 232 | * can't hurt. 2>/dev/null if you don't like it: */ |
149 | logmode |= LOGMODE_SYSLOG; | 233 | logmode |= LOGMODE_SYSLOG; |
150 | } | 234 | } |
151 | argc -= optind; | ||
152 | argv += optind; | 235 | argv += optind; |
153 | 236 | ||
154 | if (argc & 1) | 237 | if (argv[0]) { |
155 | bb_show_usage(); | 238 | do { |
156 | 239 | if (!argv[1]) | |
157 | if (argc) { | 240 | bb_show_usage(); |
158 | while (*argv) { | 241 | prepend_new_eth_table(&clist, argv[0], argv[1]); |
159 | char *ifname = xstrdup(*argv++); | 242 | argv += 2; |
160 | prepend_new_eth_table(&clist, ifname, *argv++); | 243 | } while (*argv); |
161 | } | ||
162 | } else { | 244 | } else { |
163 | parser = config_open(fname); | 245 | parser = config_open(fname); |
164 | while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) | 246 | while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) |
@@ -173,8 +255,9 @@ int nameif_main(int argc, char **argv) | |||
173 | struct ifreq ifr; | 255 | struct ifreq ifr; |
174 | #if ENABLE_FEATURE_NAMEIF_EXTENDED | 256 | #if ENABLE_FEATURE_NAMEIF_EXTENDED |
175 | struct ethtool_drvinfo drvinfo; | 257 | struct ethtool_drvinfo drvinfo; |
258 | struct ethtool_cmd eth_settings; | ||
176 | #endif | 259 | #endif |
177 | if (parser->lineno < 2) | 260 | if (parser->lineno <= 2) |
178 | continue; /* Skip the first two lines */ | 261 | continue; /* Skip the first two lines */ |
179 | 262 | ||
180 | /* Find the current interface name and copy it to ifr.ifr_name */ | 263 | /* Find the current interface name and copy it to ifr.ifr_name */ |
@@ -182,8 +265,14 @@ int nameif_main(int argc, char **argv) | |||
182 | strncpy_IFNAMSIZ(ifr.ifr_name, token[0]); | 265 | strncpy_IFNAMSIZ(ifr.ifr_name, token[0]); |
183 | 266 | ||
184 | #if ENABLE_FEATURE_NAMEIF_EXTENDED | 267 | #if ENABLE_FEATURE_NAMEIF_EXTENDED |
268 | /* Check for phy address */ | ||
269 | memset(ð_settings, 0, sizeof(eth_settings)); | ||
270 | eth_settings.cmd = ETHTOOL_GSET; | ||
271 | ifr.ifr_data = (caddr_t) ð_settings; | ||
272 | ioctl(ctl_sk, SIOCETHTOOL, &ifr); | ||
273 | |||
185 | /* Check for driver etc. */ | 274 | /* Check for driver etc. */ |
186 | memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo)); | 275 | memset(&drvinfo, 0, sizeof(drvinfo)); |
187 | drvinfo.cmd = ETHTOOL_GDRVINFO; | 276 | drvinfo.cmd = ETHTOOL_GDRVINFO; |
188 | ifr.ifr_data = (caddr_t) &drvinfo; | 277 | ifr.ifr_data = (caddr_t) &drvinfo; |
189 | /* Get driver and businfo first, so we have it in drvinfo */ | 278 | /* Get driver and businfo first, so we have it in drvinfo */ |
@@ -198,6 +287,8 @@ int nameif_main(int argc, char **argv) | |||
198 | continue; | 287 | continue; |
199 | if (ch->driver && strcmp(ch->driver, drvinfo.driver) != 0) | 288 | if (ch->driver && strcmp(ch->driver, drvinfo.driver) != 0) |
200 | continue; | 289 | continue; |
290 | if (ch->phy_address != -1 && ch->phy_address != eth_settings.phy_address) | ||
291 | continue; | ||
201 | #endif | 292 | #endif |
202 | if (ch->mac && memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN) != 0) | 293 | if (ch->mac && memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN) != 0) |
203 | continue; | 294 | continue; |