telnet: move winsize detection closer to I/O loop, delete non-functioning debug code
[oweals/busybox.git] / networking / libiproute / ll_map.c
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 #include <net/if.h>  /* struct ifreq and co. */
11
12 #include "libbb.h"
13 #include "libnetlink.h"
14 #include "ll_map.h"
15
16 struct idxmap {
17         struct idxmap *next;
18         int            index;
19         int            type;
20         int            alen;
21         unsigned       flags;
22         unsigned char  addr[8];
23         char           name[16];
24 };
25
26 static struct idxmap **idxmap; /* treat as *idxmap[16] */
27
28 static struct idxmap *find_by_index(int idx)
29 {
30         struct idxmap *im;
31
32         if (idxmap)
33                 for (im = idxmap[idx & 0xF]; im; im = im->next)
34                         if (im->index == idx)
35                                 return im;
36         return NULL;
37 }
38
39 int FAST_FUNC ll_remember_index(const struct sockaddr_nl *who UNUSED_PARAM,
40                 struct nlmsghdr *n,
41                 void *arg UNUSED_PARAM)
42 {
43         int h;
44         struct ifinfomsg *ifi = NLMSG_DATA(n);
45         struct idxmap *im, **imp;
46         struct rtattr *tb[IFLA_MAX+1];
47
48         if (n->nlmsg_type != RTM_NEWLINK)
49                 return 0;
50
51         if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
52                 return -1;
53
54         //memset(tb, 0, sizeof(tb)); - parse_rtattr does this
55         parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n));
56         if (tb[IFLA_IFNAME] == NULL)
57                 return 0;
58
59         if (!idxmap)
60                 idxmap = xzalloc(sizeof(idxmap[0]) * 16);
61
62         h = ifi->ifi_index & 0xF;
63         for (imp = &idxmap[h]; (im = *imp) != NULL; imp = &im->next)
64                 if (im->index == ifi->ifi_index)
65                         goto found;
66
67         im = xmalloc(sizeof(*im));
68         im->next = *imp;
69         im->index = ifi->ifi_index;
70         *imp = im;
71  found:
72         im->type = ifi->ifi_type;
73         im->flags = ifi->ifi_flags;
74         if (tb[IFLA_ADDRESS]) {
75                 int alen;
76                 im->alen = alen = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
77                 if (alen > (int)sizeof(im->addr))
78                         alen = sizeof(im->addr);
79                 memcpy(im->addr, RTA_DATA(tb[IFLA_ADDRESS]), alen);
80         } else {
81                 im->alen = 0;
82                 memset(im->addr, 0, sizeof(im->addr));
83         }
84         strcpy(im->name, RTA_DATA(tb[IFLA_IFNAME]));
85         return 0;
86 }
87
88 static
89 const char FAST_FUNC *ll_idx_n2a(int idx/*, char *buf*/)
90 {
91         struct idxmap *im;
92
93         if (idx == 0)
94                 return "*";
95         im = find_by_index(idx);
96         if (im)
97                 return im->name;
98         //snprintf(buf, 16, "if%d", idx);
99         //return buf;
100         return auto_string(xasprintf("if%d", idx));
101 }
102
103 const char FAST_FUNC *ll_index_to_name(int idx)
104 {
105         //static char nbuf[16];
106         return ll_idx_n2a(idx/*, nbuf*/);
107 }
108
109 #ifdef UNUSED
110 int ll_index_to_type(int idx)
111 {
112         struct idxmap *im;
113
114         if (idx == 0)
115                 return -1;
116         im = find_by_index(idx);
117         if (im)
118                 return im->type;
119         return -1;
120 }
121 #endif
122
123 unsigned FAST_FUNC ll_index_to_flags(int idx)
124 {
125         struct idxmap *im;
126
127         if (idx == 0)
128                 return 0;
129         im = find_by_index(idx);
130         if (im)
131                 return im->flags;
132         return 0;
133 }
134
135 int FAST_FUNC xll_name_to_index(const char *name)
136 {
137         int ret = 0;
138
139 /* caching is not warranted - no users which repeatedly call it */
140 #ifdef UNUSED
141         static char ncache[16];
142         static int icache;
143
144         struct idxmap *im;
145         int i;
146
147         if (name == NULL)
148                 goto out;
149         if (icache && strcmp(name, ncache) == 0) {
150                 ret = icache;
151                 goto out;
152         }
153         if (idxmap) {
154                 for (i = 0; i < 16; i++) {
155                         for (im = idxmap[i]; im; im = im->next) {
156                                 if (strcmp(im->name, name) == 0) {
157                                         icache = im->index;
158                                         strcpy(ncache, name);
159                                         ret = im->index;
160                                         goto out;
161                                 }
162                         }
163                 }
164         }
165 #endif
166         ret = if_nametoindex(name);
167 /* out:*/
168         if (ret <= 0)
169                 bb_error_msg_and_die("can't find device '%s'", name);
170         return ret;
171 }
172
173 int FAST_FUNC ll_init_map(struct rtnl_handle *rth)
174 {
175         xrtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK);
176         xrtnl_dump_filter(rth, ll_remember_index, NULL);
177         return 0;
178 }