aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networking/nameif.c132
1 files changed, 68 insertions, 64 deletions
diff --git a/networking/nameif.c b/networking/nameif.c
index 4b2d090ca..a9d422110 100644
--- a/networking/nameif.c
+++ b/networking/nameif.c
@@ -22,21 +22,20 @@
22 * 22 *
23 */ 23 */
24 24
25
25#include <sys/syslog.h> 26#include <sys/syslog.h>
26#include <sys/socket.h> 27#include <sys/socket.h>
27#include <sys/ioctl.h> 28#include <sys/ioctl.h>
28
29#include <errno.h> 29#include <errno.h>
30#include <getopt.h> 30#include <getopt.h>
31#include <stdlib.h> 31#include <stdlib.h>
32#include <string.h> 32#include <string.h>
33#include <net/if.h> 33#include <net/if.h>
34#include <netinet/ether.h> 34#include <netinet/ether.h>
35#include <linux/sockios.h>
35 36
36#include "busybox.h" 37#include "busybox.h"
37 38
38/* set interface name, from <linux/sockios.h> */
39#define SIOCSIFNAME 0x8923
40/* Octets in one ethernet addr, from <linux/if_ether.h> */ 39/* Octets in one ethernet addr, from <linux/if_ether.h> */
41#define ETH_ALEN 6 40#define ETH_ALEN 6
42 41
@@ -46,12 +45,12 @@
46 45
47typedef struct mactable_s { 46typedef struct mactable_s {
48 struct mactable_s *next; 47 struct mactable_s *next;
49 struct mactable_s **pprev; 48 struct mactable_s *prev;
50 char *ifname; 49 char *ifname;
51 struct ether_addr *mac; 50 struct ether_addr *mac;
52} mactable_t; 51} mactable_t;
53 52
54static void serror_msg_and_die(const char use_syslog, const char *s, ...) 53static void serror(const char use_syslog, const char *s, ...)
55{ 54{
56 va_list ap; 55 va_list ap;
57 56
@@ -67,20 +66,35 @@ static void serror_msg_and_die(const char use_syslog, const char *s, ...)
67 } 66 }
68 67
69 va_end(ap); 68 va_end(ap);
70 69
71 exit(EXIT_FAILURE); 70 exit(EXIT_FAILURE);
72} 71}
73 72
73/* Check ascii str_macaddr, convert and copy to *mac */
74struct ether_addr *cc_macaddr(char *str_macaddr, unsigned char use_syslog)
75{
76 struct ether_addr *lmac, *mac;
77
78 lmac = ether_aton(str_macaddr);
79 if (lmac == NULL)
80 serror(use_syslog, "cannot parse MAC %s", str_macaddr);
81 mac = xcalloc(1, ETH_ALEN);
82 memcpy(mac, lmac, ETH_ALEN);
83
84 return mac;
85}
86
74int nameif_main(int argc, char **argv) 87int nameif_main(int argc, char **argv)
75{ 88{
76 mactable_t *clist = NULL; 89 mactable_t *clist = NULL;
77 FILE *ifh; 90 FILE *ifh;
78 char *fname = "/etc/mactab"; 91 char *fname = "/etc/mactab";
79 char *line; 92 char *line;
80 unsigned short linenum = 0;
81 unsigned char use_syslog = 0; 93 unsigned char use_syslog = 0;
82 int ctl_sk = -1; 94 int ctl_sk = -1;
83 int opt; 95 int opt;
96 int if_index = 1;
97 mactable_t *ch = NULL;
84 98
85 static struct option opts[] = { 99 static struct option opts[] = {
86 {"syslog", 0, NULL, 's'}, 100 {"syslog", 0, NULL, 's'},
@@ -101,40 +115,33 @@ int nameif_main(int argc, char **argv)
101 } 115 }
102 } 116 }
103 117
104 if ((argc - optind) & 1) { 118 if ((argc - optind) & 1)
105 show_usage(); 119 show_usage();
106 }
107 120
108 if (optind < argc) { 121 if (optind < argc) {
109 while (optind < argc) { 122 while (optind < argc) {
110 struct ether_addr *mac;
111 mactable_t *ch;
112 123
113 if (strlen(argv[optind]) > IF_NAMESIZE) { 124 if (strlen(argv[optind]) > IF_NAMESIZE)
114 serror_msg_and_die(use_syslog, "interface name `%s' too long", argv[optind]); 125 serror(use_syslog, "interface name `%s' too long",
115 } 126 argv[optind]);
116 optind++; 127 optind++;
117 mac = ether_aton(argv[optind]); 128
118 if (mac == NULL) {
119 serror_msg_and_die(use_syslog, "cannot parse MAC %s", argv[optind]);
120 }
121 ch = xcalloc(1, sizeof(mactable_t)); 129 ch = xcalloc(1, sizeof(mactable_t));
130 ch->next = NULL;
131 ch->prev = NULL;
122 ch->ifname = strdup(argv[optind - 1]); 132 ch->ifname = strdup(argv[optind - 1]);
123 ch->mac = xcalloc(1, ETH_ALEN); 133 ch->mac = cc_macaddr(argv[optind], use_syslog);
124 memcpy(ch->mac, mac, ETH_ALEN);
125 optind++; 134 optind++;
126 if (clist) 135 if (clist)
127 clist->pprev = &ch->next; 136 clist->prev = ch->next;
128 ch->next = clist; 137 ch->next = clist;
129 ch->pprev = &clist; 138 ch->prev = clist;
130 clist = ch; 139 clist = ch;
131 } 140 }
132 } else { 141 } else {
133 ifh = xfopen(fname, "r"); 142 ifh = xfopen(fname, "r");
134 143
135 while ((line = get_line_from_file(ifh)) != NULL) { 144 while ((line = get_line_from_file(ifh)) != NULL) {
136 struct ether_addr *mac;
137 mactable_t *ch;
138 char *line_ptr; 145 char *line_ptr;
139 unsigned short name_length; 146 unsigned short name_length;
140 147
@@ -142,74 +149,71 @@ int nameif_main(int argc, char **argv)
142 if ((line_ptr[0] == '#') || (line_ptr[0] == '\n')) 149 if ((line_ptr[0] == '#') || (line_ptr[0] == '\n'))
143 continue; 150 continue;
144 name_length = strcspn(line_ptr, " \t"); 151 name_length = strcspn(line_ptr, " \t");
145 if (name_length > IF_NAMESIZE) { 152 if (name_length > IF_NAMESIZE)
146 serror_msg_and_die(use_syslog, "interface name `%s' too long", argv[optind]); 153 serror(use_syslog, "interface name `%s' too long",
147 } 154 argv[optind]);
148 ch = xcalloc(1, sizeof(mactable_t)); 155 ch = xcalloc(1, sizeof(mactable_t));
156 ch->next = NULL;
157 ch->prev = NULL;
149 ch->ifname = strndup(line_ptr, name_length); 158 ch->ifname = strndup(line_ptr, name_length);
150 line_ptr += name_length; 159 line_ptr += name_length;
151 line_ptr += strspn(line_ptr, " \t"); 160 line_ptr += strspn(line_ptr, " \t");
152 name_length = strspn(line_ptr, "0123456789ABCDEFabcdef:"); 161 name_length = strspn(line_ptr, "0123456789ABCDEFabcdef:");
153 line_ptr[name_length] = '\0'; 162 line_ptr[name_length] = '\0';
154 mac = ether_aton(line_ptr); 163 ch->mac = cc_macaddr(line_ptr, use_syslog);
155 if (mac == NULL) {
156 serror_msg_and_die(use_syslog, "cannot parse MAC %s", argv[optind]);
157 }
158 ch->mac = xcalloc(1, ETH_ALEN);
159 memcpy(ch->mac, mac, ETH_ALEN);
160 if (clist) 164 if (clist)
161 clist->pprev = &ch->next; 165 clist->prev = ch;
162 ch->next = clist; 166 ch->next = clist;
163 ch->pprev = &clist;
164 clist = ch; 167 clist = ch;
165 free(line); 168 free(line);
166 } 169 }
167 fclose(ifh); 170 fclose(ifh);
168 } 171 }
169 172
170 ifh = xfopen("/proc/net/dev", "r"); 173 if ((ctl_sk = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
171 while ((line = get_line_from_file(ifh)) != NULL) { 174 serror(use_syslog, "socket: %s", strerror(errno));
172 char *line_ptr; 175
173 unsigned short iface_name_length; 176 while (clist) {
174 struct ifreq ifr; 177 struct ifreq ifr;
175 mactable_t *ch = NULL;
176 178
177 linenum++; 179 bzero(&ifr, sizeof(struct ifreq));
178 if (linenum < 3) 180 if_index++;
179 continue; 181 ifr.ifr_ifindex = if_index;
180 line_ptr = line + strspn(line, " \t"); 182
181 if (line_ptr[0] == '\n') 183 /* Get ifname by index or die */
182 continue; 184 if (ioctl(ctl_sk, SIOCGIFNAME, &ifr))
183 iface_name_length = strcspn(line_ptr, ":"); 185 break;
184 if (ctl_sk < 0) 186
185 ctl_sk = socket(PF_INET, SOCK_DGRAM, 0); 187 /* Has this device hwaddr? */
186 memset(&ifr, 0, sizeof(struct ifreq)); 188 if (ioctl(ctl_sk, SIOCGIFHWADDR, &ifr))
187 strncpy(ifr.ifr_name, line_ptr, iface_name_length);
188 if (ioctl(ctl_sk, SIOCGIFHWADDR, &ifr) < 0) {
189// serror_msg(use_syslog, "cannot read hardware address of %s: %s", ifr.ifr_name, strerror(errno));
190 continue; 189 continue;
191 } 190
191 /* Search for mac like in ifr.ifr_hwaddr.sa_data */
192 for (ch = clist; ch; ch = ch->next) 192 for (ch = clist; ch; ch = ch->next)
193 if (!memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN)) 193 if (!memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN))
194 break; 194 break;
195 if (ch == NULL) { 195
196 /* Nothing found for current ifr.ifr_hwaddr.sa_data */
197 if (ch == NULL)
196 continue; 198 continue;
197 }
198 199
199 strcpy(ifr.ifr_newname, ch->ifname); 200 strcpy(ifr.ifr_newname, ch->ifname);
200 201 if (ioctl(ctl_sk, SIOCSIFNAME, &ifr) < 0)
201 if (ioctl(ctl_sk, SIOCSIFNAME, &ifr) < 0) {; 202 serror(use_syslog, "cannot change ifname %s to %s: %s",
202 serror_msg_and_die(use_syslog, "cannot change name of %s to %s: %s", ifr.ifr_name, ch->ifname, strerror(errno)); 203 ifr.ifr_name, ch->ifname, strerror(errno));
204
205 /* Remove list entry of renamed interface */
206 if (ch->prev != NULL) {
207 (ch->prev)->next = ch->next;
208 } else {
209 clist = ch->next;
203 } 210 }
204 *ch->pprev = ch->next; 211 if (ch->next != NULL)
212 (ch->next)->prev = ch->prev;
205 free(ch); 213 free(ch);
206 free(line);
207 } 214 }
208 fclose(ifh);
209 215
210 while (clist) { 216 while (clist) {
211 mactable_t *ch;
212
213 ch = clist; 217 ch = clist;
214 clist = clist->next; 218 clist = clist->next;
215 free(ch); 219 free(ch);