Header cleanup: don't #include headers that libbb.h already includes.
[oweals/busybox.git] / networking / libiproute / ll_map.c
1 /*
2  * ll_map.c
3  *
4  *              This program is free software; you can redistribute it and/or
5  *              modify it under the terms of the GNU General Public License
6  *              as published by the Free Software Foundation; either version
7  *              2 of the License, or (at your option) any later version.
8  *
9  * Authors:     Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10  *
11  */
12
13 #include "libbb.h"
14 #include <string.h>
15
16 #include "libnetlink.h"
17 #include "ll_map.h"
18
19 struct idxmap
20 {
21         struct idxmap * next;
22         int             index;
23         int             type;
24         int             alen;
25         unsigned        flags;
26         unsigned char   addr[8];
27         char            name[16];
28 };
29
30 static struct idxmap *idxmap[16];
31
32 int ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
33 {
34         int h;
35         struct ifinfomsg *ifi = NLMSG_DATA(n);
36         struct idxmap *im, **imp;
37         struct rtattr *tb[IFLA_MAX+1];
38
39         if (n->nlmsg_type != RTM_NEWLINK)
40                 return 0;
41
42         if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
43                 return -1;
44
45
46         memset(tb, 0, sizeof(tb));
47         parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n));
48         if (tb[IFLA_IFNAME] == NULL)
49                 return 0;
50
51         h = ifi->ifi_index&0xF;
52
53         for (imp=&idxmap[h]; (im=*imp)!=NULL; imp = &im->next)
54                 if (im->index == ifi->ifi_index)
55                         break;
56
57         if (im == NULL) {
58                 im = xmalloc(sizeof(*im));
59                 im->next = *imp;
60                 im->index = ifi->ifi_index;
61                 *imp = im;
62         }
63
64         im->type = ifi->ifi_type;
65         im->flags = ifi->ifi_flags;
66         if (tb[IFLA_ADDRESS]) {
67                 int alen;
68                 im->alen = alen = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
69                 if (alen > sizeof(im->addr))
70                         alen = sizeof(im->addr);
71                 memcpy(im->addr, RTA_DATA(tb[IFLA_ADDRESS]), alen);
72         } else {
73                 im->alen = 0;
74                 memset(im->addr, 0, sizeof(im->addr));
75         }
76         strcpy(im->name, RTA_DATA(tb[IFLA_IFNAME]));
77         return 0;
78 }
79
80 const char *ll_idx_n2a(int idx, char *buf)
81 {
82         struct idxmap *im;
83
84         if (idx == 0)
85                 return "*";
86         for (im = idxmap[idx&0xF]; im; im = im->next)
87                 if (im->index == idx)
88                         return im->name;
89         snprintf(buf, 16, "if%d", idx);
90         return buf;
91 }
92
93
94 const char *ll_index_to_name(int idx)
95 {
96         static char nbuf[16];
97
98         return ll_idx_n2a(idx, nbuf);
99 }
100
101 int ll_index_to_type(int idx)
102 {
103         struct idxmap *im;
104
105         if (idx == 0)
106                 return -1;
107         for (im = idxmap[idx&0xF]; im; im = im->next)
108                 if (im->index == idx)
109                         return im->type;
110         return -1;
111 }
112
113 unsigned ll_index_to_flags(int idx)
114 {
115         struct idxmap *im;
116
117         if (idx == 0)
118                 return 0;
119
120         for (im = idxmap[idx&0xF]; im; im = im->next)
121                 if (im->index == idx)
122                         return im->flags;
123         return 0;
124 }
125
126 int ll_name_to_index(char *name)
127 {
128         static char ncache[16];
129         static int icache;
130         struct idxmap *im;
131         int i;
132
133         if (name == NULL)
134                 return 0;
135         if (icache && strcmp(name, ncache) == 0)
136                 return icache;
137         for (i=0; i<16; i++) {
138                 for (im = idxmap[i]; im; im = im->next) {
139                         if (strcmp(im->name, name) == 0) {
140                                 icache = im->index;
141                                 strcpy(ncache, name);
142                                 return im->index;
143                         }
144                 }
145         }
146         return 0;
147 }
148
149 int ll_init_map(struct rtnl_handle *rth)
150 {
151         if (rtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK) < 0) {
152                 perror("Cannot send dump request");
153                 exit(1);
154         }
155
156         if (rtnl_dump_filter(rth, ll_remember_index, &idxmap, NULL, NULL) < 0) {
157                 fprintf(stderr, "Dump terminated\n");
158                 exit(1);
159         }
160         return 0;
161 }