1 /*
2 * $Id$
3 *
4 * Copyright (c) 2008, 2009
5 * Sten Spans <sten@blinkenlights.nl>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 #ifndef _common_h
21 #define _common_h
22
23 #include "config.h"
24 #include <stdarg.h>
25 #include <stddef.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <inttypes.h>
29 #include <limits.h>
30 #include <string.h>
31 #ifndef S_SPLINT_S
32 #include <unistd.h>
33 #endif
34 #include <fcntl.h>
35 #include <signal.h>
36 #include <time.h>
37 #include <errno.h>
38 #include <assert.h>
39 #if defined(HAVE_STRNVIS) && !defined(BROKEN_STRNVIS)
40 #include <vis.h>
41 #endif
42 #if HAVE_NETINET_IN_H
43 #include <netinet/in.h>
44 #endif
45 #include <arpa/inet.h>
46 #include <sys/types.h>
47 #include <sys/socket.h>
48 #include <sys/utsname.h>
49 #include <sys/ioctl.h>
50 #if HAVE_SYS_SYSCTL_H
51 #include <sys/param.h>
52 #include <sys/sysctl.h>
53 #endif
54 #include <sys/stat.h>
55 #include <sys/time.h>
56 #include <sys/uio.h>
57 #include <pwd.h>
58
59 #include <event.h>
60 #if HAVE_EVHTTP_H
61 #include <evhttp.h>
62 #endif /* HAVE_EVHTTP_H */
63
64 #if HAVE_NET_IF_H
65 #include <net/if.h>
66 #define _LINUX_IF_H
67 #define IFF_LOWER_UP 0x10000
68 #endif
69 #if HAVE_NETINET_IF_ETHER_H
70 #include <netinet/if_ether.h>
71 #endif
72
73 #ifndef __noreturn
74 # define __noreturn __attribute__ ((noreturn))
75 #endif
76 #ifndef __packed
77 # define __packed __attribute__ ((packed))
78 #endif
79 #ifndef __nonnull
80 # define __nonnull(x) __attribute__ ((__nonnull__ x))
81 #endif
82 #ifndef __unused
83 # define __unused(x) __attribute__((__unused__)) x
84 #endif
85 #if __GNUC__ >= 3
86 # define likely(x) __builtin_expect (!!(x), 1)
87 # define unlikely(x) __builtin_expect (!!(x), 0)
88 #else
89 # define likely(x) (x)
90 # define unlikely(x) (x)
91 #endif
92
93 #include "ether.h"
94 #include "compat/compat.h"
95
96 #define SLEEPTIME 30
97 #define LADVD_TTL 180
98
99 #ifndef IFDESCRSIZE
100 #define IFDESCRSIZE 64
101 #endif
102
103 #define LLDP_INVENTORY_SIZE 32
104
105 #define NETIF_BONDING_LACP 1
106 #define NETIF_BONDING_FAILOVER 2
107 #define NETIF_BONDING_OTHER 3
108 #define NETIF_CHILD_ACTIVE 1
109 #define NETIF_CHILD_BACKUP 2
110
111 #define NETIF_INDEX_MAX UINT32_MAX
112
113 struct netif {
114 uint32_t index;
115 char name[IFNAMSIZ];
116 char description[IFDESCRSIZE];
117 uint8_t hwaddr[ETHER_ADDR_LEN];
118 uint16_t mtu;
119 int8_t duplex;
120 int8_t autoneg_supported;
121 int8_t autoneg_enabled;
122 uint16_t autoneg_pmd;
123 uint16_t mau;
124
125 uint32_t ipaddr4;
126 uint32_t ipaddr6[4];
127
128 uint8_t argv;
129 int8_t type;
130 uint8_t child;
131 uint8_t bonding_mode;
132 uint8_t lacp_index;
133
134 uint16_t vlan_id;
135 uint32_t vlan_parent;
136
137 uint8_t protos;
138 uint8_t update;
139
140 struct netif *parent;
141 struct netif *subif;
142
143 // should be last
144 TAILQ_ENTRY(netif) entries;
145
146 uint8_t link_event;
147 uint8_t device_identified;
148 char device_name[IFDESCRSIZE];
149 };
150
151 TAILQ_HEAD(nhead, netif);
152
153 struct exclif {
154 char name[IFNAMSIZ];
155 TAILQ_ENTRY(exclif) entries;
156 };
157
158 TAILQ_HEAD(ehead, exclif);
159
160 struct hinv {
161 char hw_revision[LLDP_INVENTORY_SIZE + 1];
162 char fw_revision[LLDP_INVENTORY_SIZE + 1];
163 char sw_revision[LLDP_INVENTORY_SIZE + 1];
164 char serial_number[LLDP_INVENTORY_SIZE + 1];
165 char manufacturer[LLDP_INVENTORY_SIZE + 1];
166 char model_name[LLDP_INVENTORY_SIZE + 1];
167 char asset_id[LLDP_INVENTORY_SIZE + 1];
168 };
169
170 struct my_sysinfo {
171 struct utsname uts;
172 char uts_str[256];
173 uint8_t uts_rel[3];
174 char platform[256];
175 char hostname[256];
176 char country[3];
177 char location[256];
178 uint16_t cap;
179 uint16_t cap_active;
180 uint16_t cap_lldpmed;
181 int8_t lldpmed_devtype;
182 uint8_t hwaddr[ETHER_ADDR_LEN];
183 uint16_t physif_count;
184
185 uint32_t maddr4;
186 uint32_t maddr6[4];
187 const char *mifname;
188 struct netif *mnetif;
189
190 struct hinv hinv;
191 };
192
193 #define CAP_REPEATER (1 << 0)
194 #define CAP_BRIDGE (1 << 1)
195 #define CAP_HOST (1 << 2)
196 #define CAP_ROUTER (1 << 3)
197 #define CAP_SWITCH (1 << 4)
198 #define CAP_WLAN (1 << 5)
199 #define CAP_DOCSIS (1 << 6)
200 #define CAP_PHONE (1 << 7)
201 #define CAP_OTHER (1 << 8)
202 #define CAP_MAX 9
203 #define CAP_STRING "rBHRSWCTO"
204
205 #define NETIF_INVALID INT8_MIN
206 #define NETIF_VLAN -1
207 #define NETIF_REGULAR 0
208 #define NETIF_WIRELESS 1
209 #define NETIF_TAP 2
210 #define NETIF_PARENT 10
211 #define NETIF_TEAMING 11
212 #define NETIF_BONDING 12
213 #define NETIF_BRIDGE 13
214 #define NETIF_OLD INT8_MAX
215
216 #define OPT_DAEMON (1 << 0)
217 #define OPT_SEND (1 << 1)
218 #define OPT_RECV (1 << 2)
219 #define OPT_AUTO (1 << 3)
220 #define OPT_ONCE (1 << 4)
221 #define OPT_ARGV (1 << 5)
222 #define OPT_DEBUG (1 << 6)
223 #define OPT_MNETIF (1 << 7)
224 #define OPT_MADDR (1 << 8)
225 #define OPT_WIRELESS (1 << 9)
226 #define OPT_TAP (1 << 10)
227 #define OPT_IFDESCR (1 << 11)
228 #define OPT_USEDESCR (1 << 12)
229 #define OPT_CHASSIS_IF (1 << 13)
230 #define OPT_CHECK (1 << 31)
231
232 extern uint32_t options;
233
234 struct parent_req {
235 uint8_t op;
236 uint32_t index;
237 char name[IFNAMSIZ];
238 ssize_t len;
239 char buf[512];
240 };
241
242 #define TEAM_NETIF_CNT 32
243 struct parent_team_info {
244 uint8_t mode;
245 uint8_t cnt;
246 uint32_t netifs[TEAM_NETIF_CNT];
247 uint32_t netif_active;
248 };
249
250 #define PARENT_REQ_MIN offsetof(struct parent_req, buf)
251 #define PARENT_REQ_MAX sizeof(struct parent_req)
252 #define PARENT_REQ_LEN(l) PARENT_REQ_MIN + l
253
254 #define DECODE_STR 1
255 #define DECODE_PRINT 2
256
257 #define PEER_HOSTNAME 0
258 #define PEER_PORTNAME 1
259 #define PEER_PORTDESCR 2
260 #define PEER_CAP 3
261 #define PEER_ADDR_INET4 4
262 #define PEER_ADDR_INET6 5
263 #define PEER_ADDR_802 6
264 #define PEER_VLAN_ID 7
265 #define PEER_MAX 8
266 #define PEER_STR(x,y) ((x)?(free(y)):(x = y))
267
268 static inline
peer_free(char * p[])269 void peer_free(char *p[]) {
270 int s;
271 for (s = 0; s < PEER_MAX; s++) {
272 if (!p[s])
273 continue;
274 free(p[s]);
275 p[s] = NULL;
276 }
277 }
278
279 struct parent_msg {
280 uint32_t index;
281 char name[IFNAMSIZ];
282 uint8_t proto;
283 time_t received;
284 ssize_t len;
285 unsigned char msg[ETHER_MAX_LEN];
286
287 uint8_t decode;
288 uint16_t ttl;
289 char *peer[PEER_MAX];
290
291 uint8_t lock;
292
293 // should be last
294 TAILQ_ENTRY(parent_msg) entries;
295 };
296
297 TAILQ_HEAD(mhead, parent_msg);
298
299 #define PARENT_MSG_MIN offsetof(struct parent_msg, msg)
300 #define PARENT_MSG_MAX offsetof(struct parent_msg, decode)
301 #define PARENT_MSG_SIZ sizeof(struct parent_msg)
302 #define PARENT_MSG_LEN(l) PARENT_MSG_MIN + l
303 #define PARENT_OPEN 0
304 #define PARENT_CLOSE 1
305 #define PARENT_DESCR 2
306 #define PARENT_ALIAS 3
307 #define PARENT_DEVICE 4
308 #define PARENT_DEVICE_ID 5
309 #define PARENT_ETHTOOL_GSET 6
310 #define PARENT_ETHTOOL_GDRV 7
311 #define PARENT_TEAMNL 8
312 #define PARENT_MAX 9
313
314 struct proto {
315 uint8_t enabled;
316 const char *name;
317 uint8_t dst_addr[ETHER_ADDR_LEN];
318 uint8_t llc_org[3];
319 uint16_t llc_pid;
320 size_t (* const build) (uint8_t, void *, struct netif *, struct nhead *,
321 struct my_sysinfo *);
322 unsigned char * (* const check) (void *, size_t);
323 size_t (* const decode) (struct parent_msg *);
324 };
325
326 void cli_main(int argc, char *argv[]) __noreturn;
327 void child_init(int reqfd, int msgfd, int ifc, char *ifl[], struct passwd *pwd);
328 void parent_init(int reqfd, int msgfd, pid_t pid);
329 void parent_signal(int fd, short event, void *pid);
330
331 void sysinfo_fetch(struct my_sysinfo *);
332 void netif_init();
333 uint16_t netif_fetch(int ifc, char *ifl[], struct my_sysinfo *, struct nhead *);
334 int netif_media(struct netif *);
335
336 #endif /* _common_h */
337