source: MondoRescue/branches/3.3/mindi-busybox/networking/libiproute/ll_map.c@ 3803

Last change on this file since 3803 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 3.5 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License
5 * as published by the Free Software Foundation; either version
6 * 2 of the License, or (at your option) any later version.
7 *
8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
9 */
10
11#include <net/if.h> /* struct ifreq and co. */
12
13#include "libbb.h"
14#include "libnetlink.h"
15#include "ll_map.h"
16
17struct idxmap {
18 struct idxmap *next;
19 int index;
20 int type;
21 int alen;
22 unsigned flags;
23 unsigned char addr[8];
24 char name[16];
25};
26
27static struct idxmap **idxmap; /* treat as *idxmap[16] */
28
29static struct idxmap *find_by_index(int idx)
30{
31 struct idxmap *im;
32
33 if (idxmap)
34 for (im = idxmap[idx & 0xF]; im; im = im->next)
35 if (im->index == idx)
36 return im;
37 return NULL;
38}
39
40int FAST_FUNC ll_remember_index(const struct sockaddr_nl *who UNUSED_PARAM,
41 struct nlmsghdr *n,
42 void *arg UNUSED_PARAM)
43{
44 int h;
45 struct ifinfomsg *ifi = NLMSG_DATA(n);
46 struct idxmap *im, **imp;
47 struct rtattr *tb[IFLA_MAX+1];
48
49 if (n->nlmsg_type != RTM_NEWLINK)
50 return 0;
51
52 if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
53 return -1;
54
55 memset(tb, 0, sizeof(tb));
56 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n));
57 if (tb[IFLA_IFNAME] == NULL)
58 return 0;
59
60 if (!idxmap)
61 idxmap = xzalloc(sizeof(idxmap[0]) * 16);
62
63 h = ifi->ifi_index & 0xF;
64 for (imp = &idxmap[h]; (im = *imp) != NULL; imp = &im->next)
65 if (im->index == ifi->ifi_index)
66 goto found;
67
68 im = xmalloc(sizeof(*im));
69 im->next = *imp;
70 im->index = ifi->ifi_index;
71 *imp = im;
72 found:
73 im->type = ifi->ifi_type;
74 im->flags = ifi->ifi_flags;
75 if (tb[IFLA_ADDRESS]) {
76 int alen;
77 im->alen = alen = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
78 if (alen > (int)sizeof(im->addr))
79 alen = sizeof(im->addr);
80 memcpy(im->addr, RTA_DATA(tb[IFLA_ADDRESS]), alen);
81 } else {
82 im->alen = 0;
83 memset(im->addr, 0, sizeof(im->addr));
84 }
85 strcpy(im->name, RTA_DATA(tb[IFLA_IFNAME]));
86 return 0;
87}
88
89static
90const char FAST_FUNC *ll_idx_n2a(int idx/*, char *buf*/)
91{
92 struct idxmap *im;
93
94 if (idx == 0)
95 return "*";
96 im = find_by_index(idx);
97 if (im)
98 return im->name;
99 //snprintf(buf, 16, "if%d", idx);
100 //return buf;
101 return auto_string(xasprintf("if%d", idx));
102}
103
104const char FAST_FUNC *ll_index_to_name(int idx)
105{
106 //static char nbuf[16];
107 return ll_idx_n2a(idx/*, nbuf*/);
108}
109
110#ifdef UNUSED
111int ll_index_to_type(int idx)
112{
113 struct idxmap *im;
114
115 if (idx == 0)
116 return -1;
117 im = find_by_index(idx);
118 if (im)
119 return im->type;
120 return -1;
121}
122#endif
123
124unsigned FAST_FUNC ll_index_to_flags(int idx)
125{
126 struct idxmap *im;
127
128 if (idx == 0)
129 return 0;
130 im = find_by_index(idx);
131 if (im)
132 return im->flags;
133 return 0;
134}
135
136int FAST_FUNC xll_name_to_index(const char *name)
137{
138 int ret = 0;
139
140/* caching is not warranted - no users which repeatedly call it */
141#ifdef UNUSED
142 static char ncache[16];
143 static int icache;
144
145 struct idxmap *im;
146 int i;
147
148 if (name == NULL)
149 goto out;
150 if (icache && strcmp(name, ncache) == 0) {
151 ret = icache;
152 goto out;
153 }
154 if (idxmap) {
155 for (i = 0; i < 16; i++) {
156 for (im = idxmap[i]; im; im = im->next) {
157 if (strcmp(im->name, name) == 0) {
158 icache = im->index;
159 strcpy(ncache, name);
160 ret = im->index;
161 goto out;
162 }
163 }
164 }
165 }
166#endif
167 ret = if_nametoindex(name);
168/* out:*/
169 if (ret <= 0)
170 bb_error_msg_and_die("can't find device '%s'", name);
171 return ret;
172}
173
174int FAST_FUNC ll_init_map(struct rtnl_handle *rth)
175{
176 xrtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK);
177 xrtnl_dump_filter(rth, ll_remember_index, NULL);
178 return 0;
179}
Note: See TracBrowser for help on using the repository browser.