source: MondoRescue/branches/2.2.5/mindi-busybox/networking/nameif.c@ 1765

Last change on this file since 1765 was 1765, checked in by Bruno Cornec, 16 years ago

Update to busybox 1.7.2

File size: 3.8 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * nameif.c - Naming Interfaces based on MAC address for busybox.
4 *
5 * Written 2000 by Andi Kleen.
6 * Busybox port 2002 by Nick Fedchik <nick@fedchik.org.ua>
7 * Glenn McGrath <bug1@iinet.net.au>
8 *
9 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
10 */
11
12#include "libbb.h"
13#include <syslog.h>
14#include <net/if.h>
15#include <netinet/ether.h>
16
17
18/* Older versions of net/if.h do not appear to define IF_NAMESIZE. */
19#ifndef IF_NAMESIZE
20# ifdef IFNAMSIZ
21# define IF_NAMESIZE IFNAMSIZ
22# else
23# define IF_NAMESIZE 16
24# endif
25#endif
26
27/* take from linux/sockios.h */
28#define SIOCSIFNAME 0x8923 /* set interface name */
29
30/* Octets in one Ethernet addr, from <linux/if_ether.h> */
31#define ETH_ALEN 6
32
33#ifndef ifr_newname
34#define ifr_newname ifr_ifru.ifru_slave
35#endif
36
37typedef struct mactable_s {
38 struct mactable_s *next;
39 struct mactable_s *prev;
40 char *ifname;
41 struct ether_addr *mac;
42} mactable_t;
43
44/* Check ascii str_macaddr, convert and copy to *mac */
45static struct ether_addr *cc_macaddr(const char *str_macaddr)
46{
47 struct ether_addr *lmac, *mac;
48
49 lmac = ether_aton(str_macaddr);
50 if (lmac == NULL)
51 bb_error_msg_and_die("cannot parse MAC %s", str_macaddr);
52 mac = xmalloc(ETH_ALEN);
53 memcpy(mac, lmac, ETH_ALEN);
54
55 return mac;
56}
57
58int nameif_main(int argc, char **argv);
59int nameif_main(int argc, char **argv)
60{
61 mactable_t *clist = NULL;
62 FILE *ifh;
63 const char *fname = "/etc/mactab";
64 char *line;
65 int ctl_sk;
66 int if_index = 1;
67 mactable_t *ch;
68
69 if (1 & getopt32(argv, "sc:", &fname)) {
70 openlog(applet_name, 0, LOG_LOCAL0);
71 logmode = LOGMODE_SYSLOG;
72 }
73
74 if ((argc - optind) & 1)
75 bb_show_usage();
76
77 if (optind < argc) {
78 char **a = argv + optind;
79
80 while (*a) {
81 if (strlen(*a) > IF_NAMESIZE)
82 bb_error_msg_and_die("interface name '%s' "
83 "too long", *a);
84 ch = xzalloc(sizeof(mactable_t));
85 ch->ifname = xstrdup(*a++);
86 ch->mac = cc_macaddr(*a++);
87 if (clist)
88 clist->prev = ch;
89 ch->next = clist;
90 clist = ch;
91 }
92 } else {
93 ifh = xfopen(fname, "r");
94
95 while ((line = xmalloc_fgets(ifh)) != NULL) {
96 char *line_ptr;
97 size_t name_length;
98
99 line_ptr = line + strspn(line, " \t");
100 if ((line_ptr[0] == '#') || (line_ptr[0] == '\n')) {
101 free(line);
102 continue;
103 }
104 name_length = strcspn(line_ptr, " \t");
105 ch = xzalloc(sizeof(mactable_t));
106 ch->ifname = xstrndup(line_ptr, name_length);
107 if (name_length > IF_NAMESIZE)
108 bb_error_msg_and_die("interface name '%s' "
109 "too long", ch->ifname);
110 line_ptr += name_length;
111 line_ptr += strspn(line_ptr, " \t");
112 name_length = strspn(line_ptr, "0123456789ABCDEFabcdef:");
113 line_ptr[name_length] = '\0';
114 ch->mac = cc_macaddr(line_ptr);
115 if (clist)
116 clist->prev = ch;
117 ch->next = clist;
118 clist = ch;
119 free(line);
120 }
121 fclose(ifh);
122 }
123
124 ctl_sk = xsocket(PF_INET, SOCK_DGRAM, 0);
125
126 while (clist) {
127 struct ifreq ifr;
128
129 memset(&ifr, 0, sizeof(struct ifreq));
130 if_index++;
131 ifr.ifr_ifindex = if_index;
132
133 /* Get ifname by index or die */
134 if (ioctl(ctl_sk, SIOCGIFNAME, &ifr))
135 break;
136
137 /* Has this device hwaddr? */
138 if (ioctl(ctl_sk, SIOCGIFHWADDR, &ifr))
139 continue;
140
141 /* Search for mac like in ifr.ifr_hwaddr.sa_data */
142 for (ch = clist; ch; ch = ch->next)
143 if (!memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN))
144 break;
145
146 /* Nothing found for current ifr.ifr_hwaddr.sa_data */
147 if (ch == NULL)
148 continue;
149
150 strcpy(ifr.ifr_newname, ch->ifname);
151 ioctl_or_perror_and_die(ctl_sk, SIOCSIFNAME, &ifr,
152 "cannot change ifname %s to %s",
153 ifr.ifr_name, ch->ifname);
154
155 /* Remove list entry of renamed interface */
156 if (ch->prev != NULL) {
157 (ch->prev)->next = ch->next;
158 } else {
159 clist = ch->next;
160 }
161 if (ch->next != NULL)
162 (ch->next)->prev = ch->prev;
163 if (ENABLE_FEATURE_CLEAN_UP) {
164 free(ch->ifname);
165 free(ch->mac);
166 free(ch);
167 }
168 }
169
170 return 0;
171}
Note: See TracBrowser for help on using the repository browser.