1 /* -*- mode: c; c-file-style: "openbsd" -*- */
2 /*
3  * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx>
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include "lldpd.h"
19 #include "trace.h"
20 
21 #include <stdio.h>
22 #include <unistd.h>
23 #include <errno.h>
24 #include <limits.h>
25 #include <signal.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <time.h>
29 #include <libgen.h>
30 #include <assert.h>
31 #include <sys/utsname.h>
32 #include <sys/types.h>
33 #include <sys/wait.h>
34 #include <sys/socket.h>
35 #include <sys/select.h>
36 #include <sys/time.h>
37 #include <sys/ioctl.h>
38 #include <arpa/inet.h>
39 #include <netinet/if_ether.h>
40 #include <pwd.h>
41 #include <grp.h>
42 
43 #if HAVE_VFORK_H
44 # include <vfork.h>
45 #endif
46 #if HAVE_WORKING_FORK
47 # define vfork fork
48 #endif
49 
50 static void		 usage(void);
51 
52 static struct protocol protos[] =
53 {
54 	{ LLDPD_MODE_LLDP, 1, "LLDP", 'l', lldp_send, lldp_decode, NULL,
55 	  LLDP_ADDR_NEAREST_BRIDGE,
56 	  LLDP_ADDR_NEAREST_NONTPMR_BRIDGE,
57 	  LLDP_ADDR_NEAREST_CUSTOMER_BRIDGE },
58 #ifdef ENABLE_CDP
59 	{ LLDPD_MODE_CDPV1, 0, "CDPv1", 'c', cdpv1_send, cdp_decode, cdpv1_guess,
60 	  CDP_MULTICAST_ADDR },
61 	{ LLDPD_MODE_CDPV2, 0, "CDPv2", 'c', cdpv2_send, cdp_decode, cdpv2_guess,
62 	  CDP_MULTICAST_ADDR },
63 #endif
64 #ifdef ENABLE_SONMP
65 	{ LLDPD_MODE_SONMP, 0, "SONMP", 's', sonmp_send, sonmp_decode, NULL,
66 	  SONMP_MULTICAST_ADDR },
67 #endif
68 #ifdef ENABLE_EDP
69 	{ LLDPD_MODE_EDP, 0, "EDP", 'e', edp_send, edp_decode, NULL,
70 	  EDP_MULTICAST_ADDR },
71 #endif
72 #ifdef ENABLE_FDP
73 	{ LLDPD_MODE_FDP, 0, "FDP", 'f', fdp_send, cdp_decode, NULL,
74 	  FDP_MULTICAST_ADDR },
75 #endif
76 	{ 0, 0, "any", ' ', NULL, NULL, NULL,
77 	  {0,0,0,0,0,0} }
78 };
79 
80 static char		**saved_argv;
81 #ifdef HAVE___PROGNAME
82 extern const char	*__progname;
83 #else
84 # define __progname "lldpd"
85 #endif
86 
87 static void
usage(void)88 usage(void)
89 {
90 	fprintf(stderr, "Usage:   %s [OPTIONS ...]\n", __progname);
91 	fprintf(stderr, "Version: %s\n", PACKAGE_STRING);
92 
93 	fprintf(stderr, "\n");
94 
95 	fprintf(stderr, "-d       Do not daemonize.\n");
96 	fprintf(stderr, "-r       Receive-only mode\n");
97 	fprintf(stderr, "-i       Disable LLDP-MED inventory TLV transmission.\n");
98 	fprintf(stderr, "-k       Disable advertising of kernel release, version, machine.\n");
99 	fprintf(stderr, "-S descr Override the default system description.\n");
100 	fprintf(stderr, "-P name  Override the default hardware platform.\n");
101 	fprintf(stderr, "-m IP    Specify the IP management addresses of this system.\n");
102 	fprintf(stderr, "-u file  Specify the Unix-domain socket used for communication with lldpctl(8).\n");
103 	fprintf(stderr, "-H mode  Specify the behaviour when detecting multiple neighbors.\n");
104 	fprintf(stderr, "-I iface Limit interfaces to use.\n");
105 	fprintf(stderr, "-C iface Limit interfaces to use for computing chassis ID.\n");
106 	fprintf(stderr, "-L path  Override path for lldpcli command.\n");
107 	fprintf(stderr, "-O file  Override default configuration locations processed by lldpcli(8) at start.\n");
108 #ifdef ENABLE_LLDPMED
109 	fprintf(stderr, "-M class Enable emission of LLDP-MED frame. 'class' should be one of:\n");
110 	fprintf(stderr, "             1 Generic Endpoint (Class I)\n");
111 	fprintf(stderr, "             2 Media Endpoint (Class II)\n");
112 	fprintf(stderr, "             3 Communication Device Endpoints (Class III)\n");
113 	fprintf(stderr, "             4 Network Connectivity Device\n");
114 #endif
115 #ifdef USE_SNMP
116 	fprintf(stderr, "-x       Enable SNMP subagent.\n");
117 	fprintf(stderr, "-X sock  Specify the SNMP subagent socket.\n");
118 #endif
119 	fprintf(stderr, "\n");
120 
121 #if defined ENABLE_CDP || defined ENABLE_EDP || defined ENABLE_FDP || defined ENABLE_SONMP
122 	fprintf(stderr, "Additional protocol support.\n");
123 #ifdef ENABLE_CDP
124 	fprintf(stderr, "-c       Enable the support of CDP protocol. (Cisco)\n");
125 #endif
126 #ifdef ENABLE_EDP
127 	fprintf(stderr, "-e       Enable the support of EDP protocol. (Extreme)\n");
128 #endif
129 #ifdef ENABLE_FDP
130 	fprintf(stderr, "-f       Enable the support of FDP protocol. (Foundry)\n");
131 #endif
132 #ifdef ENABLE_SONMP
133 	fprintf(stderr, "-s       Enable the support of SONMP protocol. (Nortel)\n");
134 #endif
135 
136 	fprintf(stderr, "\n");
137 #endif
138 
139 	fprintf(stderr, "see manual page lldpd(8) for more information\n");
140 	exit(1);
141 }
142 
143 struct lldpd_hardware *
lldpd_get_hardware(struct lldpd * cfg,char * name,int index)144 lldpd_get_hardware(struct lldpd *cfg, char *name, int index)
145 {
146 	struct lldpd_hardware *hardware;
147 	TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) {
148 		if (strcmp(hardware->h_ifname, name) == 0) {
149 			if (hardware->h_flags == 0) {
150 				hardware->h_ifindex = index;
151 				break;
152 			}
153 			if (hardware->h_ifindex == index)
154 				break;
155 		}
156 	}
157 	return hardware;
158 }
159 
160 /**
161  * Allocate the default local port. This port will be cloned each time we need a
162  * new local port.
163  */
164 static void
lldpd_alloc_default_local_port(struct lldpd * cfg)165 lldpd_alloc_default_local_port(struct lldpd *cfg)
166 {
167 	struct lldpd_port *port;
168 
169 	if ((port = (struct lldpd_port *)
170 		calloc(1, sizeof(struct lldpd_port))) == NULL)
171 		fatal("main", NULL);
172 
173 #ifdef ENABLE_DOT1
174 	TAILQ_INIT(&port->p_vlans);
175 	TAILQ_INIT(&port->p_ppvids);
176 	TAILQ_INIT(&port->p_pids);
177 #endif
178 #ifdef ENABLE_CUSTOM
179 	TAILQ_INIT(&port->p_custom_list);
180 #endif
181 	cfg->g_default_local_port = port;
182 }
183 
184 /**
185  * Clone a given port. The destination needs to be already allocated.
186  */
187 static int
lldpd_clone_port(struct lldpd_port * destination,struct lldpd_port * source)188 lldpd_clone_port(struct lldpd_port *destination, struct lldpd_port *source)
189 {
190 
191 	u_int8_t *output = NULL;
192 	ssize_t output_len;
193 	struct lldpd_port *cloned = NULL;
194 	output_len = lldpd_port_serialize(source, (void**)&output);
195 	if (output_len == -1 ||
196 	    lldpd_port_unserialize(output, output_len, &cloned) <= 0) {
197 		log_warnx("alloc", "unable to clone default port");
198 		free(output);
199 		return -1;
200 	}
201 	memcpy(destination, cloned, sizeof(struct lldpd_port));
202 	free(cloned);
203 	free(output);
204 #ifdef ENABLE_DOT1
205 	marshal_repair_tailq(lldpd_vlan, &destination->p_vlans, v_entries);
206 	marshal_repair_tailq(lldpd_ppvid, &destination->p_ppvids, p_entries);
207 	marshal_repair_tailq(lldpd_pi, &destination->p_pids, p_entries);
208 #endif
209 #ifdef ENABLE_CUSTOM
210 	marshal_repair_tailq(lldpd_custom, &destination->p_custom_list, next);
211 #endif
212 	return 0;
213 }
214 
215 struct lldpd_hardware *
lldpd_alloc_hardware(struct lldpd * cfg,char * name,int index)216 lldpd_alloc_hardware(struct lldpd *cfg, char *name, int index)
217 {
218 	struct lldpd_hardware *hardware;
219 
220 	log_debug("alloc", "allocate a new local port (%s)", name);
221 
222 	if ((hardware = (struct lldpd_hardware *)
223 		calloc(1, sizeof(struct lldpd_hardware))) == NULL)
224 		return NULL;
225 
226 	/* Clone default local port */
227 	if (lldpd_clone_port(&hardware->h_lport, cfg->g_default_local_port) == -1) {
228 		log_warnx("alloc", "unable to clone default port");
229 		free(hardware);
230 		return NULL;
231 	}
232 
233 	hardware->h_cfg = cfg;
234 	strlcpy(hardware->h_ifname, name, sizeof(hardware->h_ifname));
235 	hardware->h_ifindex = index;
236 	hardware->h_lport.p_chassis = LOCAL_CHASSIS(cfg);
237 	hardware->h_lport.p_chassis->c_refcount++;
238 	TAILQ_INIT(&hardware->h_rports);
239 
240 #ifdef ENABLE_LLDPMED
241 	if (LOCAL_CHASSIS(cfg)->c_med_cap_available) {
242 		hardware->h_lport.p_med_cap_enabled = LLDP_MED_CAP_CAP;
243 		if (!cfg->g_config.c_noinventory)
244 			hardware->h_lport.p_med_cap_enabled |= LLDP_MED_CAP_IV;
245 	}
246 #endif
247 
248 	levent_hardware_init(hardware);
249 	return hardware;
250 }
251 
252 struct lldpd_mgmt *
lldpd_alloc_mgmt(int family,void * addrptr,size_t addrsize,u_int32_t iface)253 lldpd_alloc_mgmt(int family, void *addrptr, size_t addrsize, u_int32_t iface)
254 {
255 	struct lldpd_mgmt *mgmt;
256 
257 	log_debug("alloc", "allocate a new management address (family: %d)", family);
258 
259 	if (family <= LLDPD_AF_UNSPEC || family >= LLDPD_AF_LAST) {
260 		errno = EAFNOSUPPORT;
261 		return NULL;
262 	}
263 	if (addrsize > LLDPD_MGMT_MAXADDRSIZE) {
264 		errno = EOVERFLOW;
265 		return NULL;
266 	}
267 	mgmt = calloc(1, sizeof(struct lldpd_mgmt));
268 	if (mgmt == NULL) {
269 		errno = ENOMEM;
270 		return NULL;
271 	}
272 	mgmt->m_family = family;
273 	memcpy(&mgmt->m_addr, addrptr, addrsize);
274 	mgmt->m_addrsize = addrsize;
275 	mgmt->m_iface = iface;
276 	return mgmt;
277 }
278 
279 void
lldpd_hardware_cleanup(struct lldpd * cfg,struct lldpd_hardware * hardware)280 lldpd_hardware_cleanup(struct lldpd *cfg, struct lldpd_hardware *hardware)
281 {
282 	log_debug("alloc", "cleanup hardware port %s", hardware->h_ifname);
283 
284 	free(hardware->h_lport_previous);
285 	free(hardware->h_lchassis_previous_id);
286 	free(hardware->h_lport_previous_id);
287 	lldpd_port_cleanup(&hardware->h_lport, 1);
288 	if (hardware->h_ops && hardware->h_ops->cleanup)
289 		hardware->h_ops->cleanup(cfg, hardware);
290 	levent_hardware_release(hardware);
291 	free(hardware);
292 }
293 
294 static void
lldpd_display_neighbors(struct lldpd * cfg)295 lldpd_display_neighbors(struct lldpd *cfg)
296 {
297 	if (!cfg->g_config.c_set_ifdescr) return;
298 	struct lldpd_hardware *hardware;
299 	TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) {
300 		struct lldpd_port *port;
301 		char *description;
302 		const char *neighbor = NULL;
303 		unsigned neighbors = 0;
304 		TAILQ_FOREACH(port, &hardware->h_rports, p_entries) {
305 			if (SMART_HIDDEN(port)) continue;
306 			neighbors++;
307 			neighbor = port->p_chassis->c_name;
308 		}
309 		if (neighbors == 0)
310 			priv_iface_description(hardware->h_ifname,
311 			    "");
312 		else if (neighbors == 1 && neighbor && *neighbor != '\0') {
313 			if (asprintf(&description, "%s",
314 				neighbor) != -1) {
315 				priv_iface_description(hardware->h_ifname, description);
316 				free(description);
317 			}
318 		} else {
319 			if (asprintf(&description, "%d neighbor%s",
320 				neighbors, (neighbors > 1)?"s":"") != -1) {
321 				priv_iface_description(hardware->h_ifname,
322 				    description);
323 				free(description);
324 			}
325 		}
326 	}
327 }
328 
329 static void
lldpd_count_neighbors(struct lldpd * cfg)330 lldpd_count_neighbors(struct lldpd *cfg)
331 {
332 #if HAVE_SETPROCTITLE
333 	struct lldpd_chassis *chassis;
334 	const char *neighbor;
335 	unsigned neighbors = 0;
336 	TAILQ_FOREACH(chassis, &cfg->g_chassis, c_entries) {
337 		neighbors++;
338 		neighbor = chassis->c_name;
339 	}
340 	neighbors--;
341 	if (neighbors == 0)
342 		setproctitle("no neighbor.");
343 	else if (neighbors == 1 && neighbor && *neighbor != '\0')
344 		setproctitle("connected to %s.", neighbor);
345 	else
346 		setproctitle("%d neighbor%s.", neighbors,
347 		    (neighbors > 1)?"s":"");
348 #endif
349 	lldpd_display_neighbors(cfg);
350 }
351 
352 static void
notify_clients_deletion(struct lldpd_hardware * hardware,struct lldpd_port * rport)353 notify_clients_deletion(struct lldpd_hardware *hardware,
354     struct lldpd_port *rport)
355 {
356 	TRACE(LLDPD_NEIGHBOR_DELETE(hardware->h_ifname,
357 		rport->p_chassis->c_name,
358 		rport->p_descr));
359 	levent_ctl_notify(hardware->h_ifname, NEIGHBOR_CHANGE_DELETED,
360 	    rport);
361 #ifdef USE_SNMP
362 	agent_notify(hardware, NEIGHBOR_CHANGE_DELETED, rport);
363 #endif
364 }
365 
366 static void
lldpd_reset_timer(struct lldpd * cfg)367 lldpd_reset_timer(struct lldpd *cfg)
368 {
369 	/* Reset timer for ports that have been changed. */
370 	struct lldpd_hardware *hardware;
371 	TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) {
372 		/* We keep a flat copy of the local port to see if there is any
373 		 * change. To do this, we zero out fields that are not
374 		 * significant, marshal the port, then restore. */
375 		struct lldpd_port *port = &hardware->h_lport;
376 		/* Take the current flags into account to detect a change. */
377 		port->_p_hardware_flags = hardware->h_flags;
378 		u_int8_t *output = NULL;
379 		ssize_t output_len;
380 		char save[LLDPD_PORT_START_MARKER];
381 		memcpy(save, port, sizeof(save));
382 		/* coverity[suspicious_sizeof]
383 		   We intentionally partially memset port */
384 		memset(port, 0, sizeof(save));
385 		output_len = lldpd_port_serialize(port, (void**)&output);
386 		memcpy(port, save, sizeof(save));
387 		if (output_len == -1) {
388 			log_warnx("localchassis",
389 			    "unable to serialize local port %s to check for differences",
390 			    hardware->h_ifname);
391 			continue;
392 		}
393 
394 		/* Compare with the previous value */
395 		if (hardware->h_lport_previous &&
396 		    output_len == hardware->h_lport_previous_len &&
397 		    !memcmp(output, hardware->h_lport_previous, output_len)) {
398 			log_debug("localchassis",
399 			    "no change detected for port %s",
400 			    hardware->h_ifname);
401 		} else {
402 			log_debug("localchassis",
403 			    "change detected for port %s, resetting its timer",
404 			    hardware->h_ifname);
405 			levent_schedule_pdu(hardware);
406 		}
407 
408 		/* Update the value */
409 		free(hardware->h_lport_previous);
410 		hardware->h_lport_previous = output;
411 		hardware->h_lport_previous_len = output_len;
412 	}
413 }
414 
415 static void
lldpd_all_chassis_cleanup(struct lldpd * cfg)416 lldpd_all_chassis_cleanup(struct lldpd *cfg)
417 {
418 	struct lldpd_chassis *chassis, *chassis_next;
419 	log_debug("localchassis", "cleanup all chassis");
420 
421 	for (chassis = TAILQ_FIRST(&cfg->g_chassis); chassis;
422 	     chassis = chassis_next) {
423 		chassis_next = TAILQ_NEXT(chassis, c_entries);
424 		if (chassis->c_refcount == 0) {
425 			TAILQ_REMOVE(&cfg->g_chassis, chassis, c_entries);
426 			lldpd_chassis_cleanup(chassis, 1);
427 		}
428 	}
429 }
430 
431 void
lldpd_cleanup(struct lldpd * cfg)432 lldpd_cleanup(struct lldpd *cfg)
433 {
434 	struct lldpd_hardware *hardware, *hardware_next;
435 
436 	log_debug("localchassis", "cleanup all ports");
437 
438 	for (hardware = TAILQ_FIRST(&cfg->g_hardware); hardware != NULL;
439 	     hardware = hardware_next) {
440 		hardware_next = TAILQ_NEXT(hardware, h_entries);
441 		if (!hardware->h_flags) {
442 			int m = cfg->g_config.c_perm_ifaces?
443 			    pattern_match(hardware->h_ifname, cfg->g_config.c_perm_ifaces, 0):
444 			    0;
445 			switch (m) {
446 			case 0:
447 				log_debug("localchassis", "delete non-permanent interface %s",
448 				    hardware->h_ifname);
449 				TRACE(LLDPD_INTERFACES_DELETE(hardware->h_ifname));
450 				TAILQ_REMOVE(&cfg->g_hardware, hardware, h_entries);
451 				lldpd_remote_cleanup(hardware, notify_clients_deletion, 1);
452 				lldpd_hardware_cleanup(cfg, hardware);
453 				break;
454 			case 1:
455 			case 2:
456 				log_debug("localchassis", "do not delete %s, permanent",
457 				    hardware->h_ifname);
458 				break;
459 			}
460 		} else {
461 			lldpd_remote_cleanup(hardware, notify_clients_deletion,
462 			    !(hardware->h_flags & IFF_RUNNING));
463 		}
464 	}
465 
466 	levent_schedule_cleanup(cfg);
467 	lldpd_all_chassis_cleanup(cfg);
468 	lldpd_count_neighbors(cfg);
469 }
470 
471 /* Update chassis `ochassis' with values from `chassis'. The later one is not
472    expected to be part of a list! It will also be wiped from memory. */
473 static void
lldpd_move_chassis(struct lldpd_chassis * ochassis,struct lldpd_chassis * chassis)474 lldpd_move_chassis(struct lldpd_chassis *ochassis,
475     struct lldpd_chassis *chassis) {
476 	struct lldpd_mgmt *mgmt, *mgmt_next;
477 
478 	/* We want to keep refcount, index and list stuff from the current
479 	 * chassis */
480 	TAILQ_ENTRY(lldpd_chassis) entries;
481 	int refcount = ochassis->c_refcount;
482 	int index = ochassis->c_index;
483 	memcpy(&entries, &ochassis->c_entries,
484 	    sizeof(entries));
485 	lldpd_chassis_cleanup(ochassis, 0);
486 
487 	/* Make the copy. */
488 	/* WARNING: this is a kludgy hack, we need in-place copy and cannot use
489 	 * marshaling. */
490 	memcpy(ochassis, chassis, sizeof(struct lldpd_chassis));
491 	TAILQ_INIT(&ochassis->c_mgmt);
492 
493 	/* Copy of management addresses */
494 	for (mgmt = TAILQ_FIRST(&chassis->c_mgmt);
495 	     mgmt != NULL;
496 	     mgmt = mgmt_next) {
497 		mgmt_next = TAILQ_NEXT(mgmt, m_entries);
498 		TAILQ_REMOVE(&chassis->c_mgmt, mgmt, m_entries);
499 		TAILQ_INSERT_TAIL(&ochassis->c_mgmt, mgmt, m_entries);
500 	}
501 
502 	/* Restore saved values */
503 	ochassis->c_refcount = refcount;
504 	ochassis->c_index = index;
505 	memcpy(&ochassis->c_entries, &entries, sizeof(entries));
506 
507 	/* Get rid of the new chassis */
508 	free(chassis);
509 }
510 
511 static int
lldpd_guess_type(struct lldpd * cfg,char * frame,int s)512 lldpd_guess_type(struct lldpd *cfg, char *frame, int s)
513 {
514 	int i;
515 	if (s < ETHER_ADDR_LEN)
516 		return -1;
517 	for (i=0; cfg->g_protocols[i].mode != 0; i++) {
518 		if (!cfg->g_protocols[i].enabled)
519 			continue;
520 		if (cfg->g_protocols[i].guess == NULL) {
521 			if (memcmp(frame, cfg->g_protocols[i].mac1, ETHER_ADDR_LEN) == 0 ||
522 			    memcmp(frame, cfg->g_protocols[i].mac2, ETHER_ADDR_LEN) == 0 ||
523 			    memcmp(frame, cfg->g_protocols[i].mac3, ETHER_ADDR_LEN) == 0) {
524 				log_debug("decode", "guessed protocol is %s (from MAC address)",
525 				    cfg->g_protocols[i].name);
526 				return cfg->g_protocols[i].mode;
527 			}
528 		} else {
529 			if (cfg->g_protocols[i].guess(frame, s)) {
530 				log_debug("decode", "guessed protocol is %s (from detector function)",
531 				    cfg->g_protocols[i].name);
532 				return cfg->g_protocols[i].mode;
533 			}
534 		}
535 	}
536 	return -1;
537 }
538 
539 static void
lldpd_decode(struct lldpd * cfg,char * frame,int s,struct lldpd_hardware * hardware)540 lldpd_decode(struct lldpd *cfg, char *frame, int s,
541     struct lldpd_hardware *hardware)
542 {
543 	int i;
544 	struct lldpd_chassis *chassis, *ochassis = NULL;
545 	struct lldpd_port *port, *oport = NULL, *aport;
546 	int guess = LLDPD_MODE_LLDP;
547 
548 	log_debug("decode", "decode a received frame on %s",
549 	    hardware->h_ifname);
550 
551 	if (s < sizeof(struct ether_header) + 4) {
552 		/* Too short, just discard it */
553 		hardware->h_rx_discarded_cnt++;
554 		return;
555 	}
556 
557 	/* Decapsulate VLAN frames */
558 	struct ether_header eheader;
559 	memcpy(&eheader, frame, sizeof(struct ether_header));
560 	if (eheader.ether_type == htons(ETHERTYPE_VLAN)) {
561 		/* VLAN decapsulation means to shift 4 bytes left the frame from
562 		 * offset 2*ETHER_ADDR_LEN */
563 		memmove(frame + 2*ETHER_ADDR_LEN, frame + 2*ETHER_ADDR_LEN + 4, s - 2*ETHER_ADDR_LEN);
564 		s -= 4;
565 	}
566 
567 	TAILQ_FOREACH(oport, &hardware->h_rports, p_entries) {
568 		if ((oport->p_lastframe != NULL) &&
569 		    (oport->p_lastframe->size == s) &&
570 		    (memcmp(oport->p_lastframe->frame, frame, s) == 0)) {
571 			/* Already received the same frame */
572 			log_debug("decode", "duplicate frame, no need to decode");
573 			oport->p_lastupdate = time(NULL);
574 			return;
575 		}
576 	}
577 
578 	guess = lldpd_guess_type(cfg, frame, s);
579 	for (i=0; cfg->g_protocols[i].mode != 0; i++) {
580 		if (!cfg->g_protocols[i].enabled)
581 			continue;
582 		if (cfg->g_protocols[i].mode == guess) {
583 			log_debug("decode", "using decode function for %s protocol",
584 			    cfg->g_protocols[i].name);
585 			if (cfg->g_protocols[i].decode(cfg, frame,
586 				s, hardware, &chassis, &port) == -1) {
587 				log_debug("decode", "function for %s protocol did not decode this frame",
588 				    cfg->g_protocols[i].name);
589 				hardware->h_rx_discarded_cnt++;
590 				return;
591 			}
592 			chassis->c_protocol = port->p_protocol =
593 			    cfg->g_protocols[i].mode;
594 			break;
595 			}
596 	}
597 	if (cfg->g_protocols[i].mode == 0) {
598 		log_debug("decode", "unable to guess frame type on %s",
599 		    hardware->h_ifname);
600 		return;
601 	}
602 	TRACE(LLDPD_FRAME_DECODED(
603 		    hardware->h_ifname,
604 		    cfg->g_protocols[i].name,
605 		    chassis->c_name,
606 		    port->p_descr));
607 
608 	/* Do we already have the same MSAP somewhere? */
609 	int count = 0;
610 	log_debug("decode", "search for the same MSAP");
611 	TAILQ_FOREACH(oport, &hardware->h_rports, p_entries) {
612 		if (port->p_protocol == oport->p_protocol) {
613 			count++;
614 			if ((port->p_id_subtype == oport->p_id_subtype) &&
615 			    (port->p_id_len == oport->p_id_len) &&
616 			    (memcmp(port->p_id, oport->p_id, port->p_id_len) == 0) &&
617 			    (chassis->c_id_subtype == oport->p_chassis->c_id_subtype) &&
618 			    (chassis->c_id_len == oport->p_chassis->c_id_len) &&
619 			    (memcmp(chassis->c_id, oport->p_chassis->c_id,
620 				chassis->c_id_len) == 0)) {
621 				ochassis = oport->p_chassis;
622 				log_debug("decode", "MSAP is already known");
623 				break;
624 			}
625 		}
626 	}
627 	/* Do we have room for a new MSAP? */
628 	if (!oport && cfg->g_config.c_max_neighbors) {
629 	    if (count == (cfg->g_config.c_max_neighbors - 1)) {
630 		log_debug("decode",
631 		    "max neighbors %d reached for port %s, "
632 		    "dropping any new ones silently",
633 		    cfg->g_config.c_max_neighbors,
634 		    hardware->h_ifname);
635 	    } else if (count > cfg->g_config.c_max_neighbors - 1) {
636 		log_debug("decode",
637 		    "too many neighbors for port %s, drop this new one",
638 		    hardware->h_ifname);
639 		lldpd_port_cleanup(port, 1);
640 		lldpd_chassis_cleanup(chassis, 1);
641 		free(port);
642 		return;
643 	    }
644 	}
645 	/* No, but do we already know the system? */
646 	if (!oport) {
647 		log_debug("decode", "MSAP is unknown, search for the chassis");
648 		TAILQ_FOREACH(ochassis, &cfg->g_chassis, c_entries) {
649 			if ((chassis->c_protocol == ochassis->c_protocol) &&
650 			    (chassis->c_id_subtype == ochassis->c_id_subtype) &&
651 			    (chassis->c_id_len == ochassis->c_id_len) &&
652 			    (memcmp(chassis->c_id, ochassis->c_id,
653 				chassis->c_id_len) == 0))
654 			break;
655 		}
656 	}
657 
658 	if (oport) {
659 		/* The port is known, remove it before adding it back */
660 		TAILQ_REMOVE(&hardware->h_rports, oport, p_entries);
661 		lldpd_port_cleanup(oport, 1);
662 		free(oport);
663 	}
664 	if (ochassis) {
665 		if (port->p_ttl == 0) {
666 			/* Shutdown LLDPDU is special. We do not want to replace
667 			 * the chassis. Free the new chassis (which is mostly empty) */
668 			log_debug("decode", "received a shutdown LLDPDU");
669 			lldpd_chassis_cleanup(chassis, 1);
670 		} else {
671 			lldpd_move_chassis(ochassis, chassis);
672 		}
673 		chassis = ochassis;
674 	} else {
675 		/* Chassis not known, add it */
676 		log_debug("decode", "unknown chassis, add it to the list");
677 		chassis->c_index = ++cfg->g_lastrid;
678 		chassis->c_refcount = 0;
679 		TAILQ_INSERT_TAIL(&cfg->g_chassis, chassis, c_entries);
680 		i = 0; TAILQ_FOREACH(ochassis, &cfg->g_chassis, c_entries) i++;
681 		log_debug("decode", "%d different systems are known", i);
682 	}
683 	/* Add port */
684 	port->p_lastchange = port->p_lastupdate = time(NULL);
685 	if ((port->p_lastframe = (struct lldpd_frame *)malloc(s +
686 		    sizeof(struct lldpd_frame))) != NULL) {
687 		port->p_lastframe->size = s;
688 		memcpy(port->p_lastframe->frame, frame, s);
689 	}
690 	TAILQ_INSERT_TAIL(&hardware->h_rports, port, p_entries);
691 	port->p_chassis = chassis;
692 	port->p_chassis->c_refcount++;
693 	/* Several cases are possible :
694 	     1. chassis is new, its refcount was 0. It is now attached
695 	        to this port, its refcount is 1.
696 	     2. chassis already exists and was attached to another
697 	        port, we increase its refcount accordingly.
698 	     3. chassis already exists and was attached to the same
699 	        port, its refcount was decreased with
700 	        lldpd_port_cleanup() and is now increased again.
701 
702 	   In all cases, if the port already existed, it has been
703 	   freed with lldpd_port_cleanup() and therefore, the refcount
704 	   of the chassis that was attached to it is decreased.
705 	*/
706 	/* coverity[use_after_free]
707 	   TAILQ_REMOVE does the right thing */
708 	i = 0; TAILQ_FOREACH(aport, &hardware->h_rports, p_entries)
709 		i++;
710 	log_debug("decode", "%d neighbors for %s", i,
711 	    hardware->h_ifname);
712 
713 	if (!oport) hardware->h_insert_cnt++;
714 
715 	/* Notify */
716 	log_debug("decode", "send notifications for changes on %s",
717 	    hardware->h_ifname);
718 	if (oport) {
719 		TRACE(LLDPD_NEIGHBOR_UPDATE(hardware->h_ifname,
720 			chassis->c_name,
721 			port->p_descr,
722 			i));
723 		levent_ctl_notify(hardware->h_ifname, NEIGHBOR_CHANGE_UPDATED, port);
724 #ifdef USE_SNMP
725 		agent_notify(hardware, NEIGHBOR_CHANGE_UPDATED, port);
726 #endif
727 	} else {
728 		TRACE(LLDPD_NEIGHBOR_NEW(hardware->h_ifname,
729 			chassis->c_name,
730 			port->p_descr,
731 			i));
732 		levent_ctl_notify(hardware->h_ifname, NEIGHBOR_CHANGE_ADDED, port);
733 #ifdef USE_SNMP
734 		agent_notify(hardware, NEIGHBOR_CHANGE_ADDED, port);
735 #endif
736 	}
737 
738 #ifdef ENABLE_LLDPMED
739 	if (!oport && port->p_chassis->c_med_type) {
740 		/* New neighbor, fast start */
741 		if (hardware->h_cfg->g_config.c_enable_fast_start &&
742 		    !hardware->h_tx_fast) {
743 			log_debug("decode", "%s: entering fast start due to "
744 			    "new neighbor", hardware->h_ifname);
745 			hardware->h_tx_fast = hardware->h_cfg->g_config.c_tx_fast_init;
746 		}
747 
748 		levent_schedule_pdu(hardware);
749 	}
750 #endif
751 
752 	return;
753 }
754 
755 /* Get the output of lsb_release -s -d.  This is a slow function. It should be
756    called once. It return NULL if any problem happens. Otherwise, this is a
757    statically allocated buffer. The result includes the trailing \n  */
758 static char *
lldpd_get_lsb_release()759 lldpd_get_lsb_release() {
760 	static char release[1024];
761 	char *const command[] = { "lsb_release", "-s", "-d", NULL };
762 	int pid, status, devnull, count;
763 	int pipefd[2];
764 
765 	log_debug("localchassis", "grab LSB release");
766 
767 	if (pipe(pipefd)) {
768 		log_warn("localchassis", "unable to get a pair of pipes");
769 		return NULL;
770 	}
771 
772 	pid = vfork();
773 	switch (pid) {
774 	case -1:
775 		log_warn("localchassis", "unable to fork");
776 		return NULL;
777 	case 0:
778 		/* Child, exec lsb_release */
779 		close(pipefd[0]);
780 		if ((devnull = open("/dev/null", O_RDWR, 0)) != -1) {
781 			dup2(devnull, STDIN_FILENO);
782 			dup2(devnull, STDERR_FILENO);
783 			dup2(pipefd[1], STDOUT_FILENO);
784 			if (devnull > 2) close(devnull);
785 			if (pipefd[1] > 2) close(pipefd[1]);
786 			execvp("lsb_release", command);
787 		}
788 		_exit(127);
789 		break;
790 	default:
791 		/* Father, read the output from the children */
792 		close(pipefd[1]);
793 		count = 0;
794 		do {
795 			status = read(pipefd[0], release+count, sizeof(release)-count);
796 			if ((status == -1) && (errno == EINTR)) continue;
797 			if (status > 0)
798 				count += status;
799 		} while (count < sizeof(release) && (status > 0));
800 		if (status < 0) {
801 			log_info("localchassis", "unable to read from lsb_release");
802 			close(pipefd[0]);
803 			waitpid(pid, &status, 0);
804 			return NULL;
805 		}
806 		close(pipefd[0]);
807 		if (count >= sizeof(release)) {
808 			log_info("localchassis", "output of lsb_release is too large");
809 			waitpid(pid, &status, 0);
810 			return NULL;
811 		}
812 		status = -1;
813 		if (waitpid(pid, &status, 0) != pid)
814 			return NULL;
815 		if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) {
816 			log_info("localchassis", "lsb_release information not available");
817 			return NULL;
818 		}
819 		if (!count) {
820 			log_info("localchassis", "lsb_release returned an empty string");
821 			return NULL;
822 		}
823 		release[count] = '\0';
824 		return release;
825 	}
826 	/* Should not be here */
827 	return NULL;
828 }
829 
830 /* Same like lldpd_get_lsb_release but reads /etc/os-release for PRETTY_NAME=. */
831 static char *
lldpd_get_os_release()832 lldpd_get_os_release() {
833 	static char release[1024];
834 	char line[1024];
835 	char *key, *val;
836 	char *ptr1 = release;
837 
838 	log_debug("localchassis", "grab OS release");
839 	FILE *fp = fopen("/etc/os-release", "r");
840 	if (!fp) {
841 		log_debug("localchassis", "could not open /etc/os-release");
842 		fp = fopen("/usr/lib/os-release", "r");
843 	}
844 	if (!fp) {
845 		log_info("localchassis",
846 		    "could not open either /etc/os-release or /usr/lib/os-release");
847 		return NULL;
848 	}
849 
850 	while ((fgets(line, sizeof(line), fp) != NULL)) {
851 		key = strtok(line, "=");
852 		val = strtok(NULL, "=");
853 
854 		if (strncmp(key, "PRETTY_NAME", sizeof(line)) == 0) {
855 			strlcpy(release, val, sizeof(line));
856 			break;
857 		}
858 	}
859 	fclose(fp);
860 
861 	/* Remove trailing newline and all " in the string. */
862 	ptr1 = release + strlen(release) - 1;
863 	while (ptr1 != release &&
864 	    ((*ptr1 == '"') || (*ptr1 == '\n'))) {
865 		*ptr1 = '\0';
866 		ptr1--;
867 	}
868 	if (release[0] == '"')
869 		return release+1;
870 	return release;
871 }
872 
873 static void
lldpd_hide_ports(struct lldpd * cfg,struct lldpd_hardware * hardware,int mask)874 lldpd_hide_ports(struct lldpd *cfg, struct lldpd_hardware *hardware, int mask) {
875 	struct lldpd_port *port;
876 	int protocols[LLDPD_MODE_MAX+1];
877 	char buffer[256];
878 	int i, j, k, found;
879 	unsigned int min;
880 
881 	log_debug("smartfilter", "apply smart filter for port %s",
882 		hardware->h_ifname);
883 
884 	/* Compute the number of occurrences of each protocol */
885 	for (i = 0; i <= LLDPD_MODE_MAX; i++) protocols[i] = 0;
886 	TAILQ_FOREACH(port, &hardware->h_rports, p_entries)
887 		protocols[port->p_protocol]++;
888 
889 	/* Turn the protocols[] array into an array of
890 	   enabled/disabled protocols. 1 means enabled, 0
891 	   means disabled. */
892 	min = (unsigned int)-1;
893 	for (i = 0; i <= LLDPD_MODE_MAX; i++)
894 		if (protocols[i] && (protocols[i] < min))
895 			min = protocols[i];
896 	found = 0;
897 	for (i = 0; i <= LLDPD_MODE_MAX; i++)
898 		if ((protocols[i] == min) && !found) {
899 			/* If we need a tie breaker, we take
900 			   the first protocol only */
901 			if (cfg->g_config.c_smart & mask &
902 			    (SMART_OUTGOING_ONE_PROTO | SMART_INCOMING_ONE_PROTO))
903 				found = 1;
904 			protocols[i] = 1;
905 		} else protocols[i] = 0;
906 
907 	/* We set the p_hidden flag to 1 if the protocol is disabled */
908 	TAILQ_FOREACH(port, &hardware->h_rports, p_entries) {
909 		if (mask == SMART_OUTGOING)
910 			port->p_hidden_out = protocols[port->p_protocol]?0:1;
911 		else
912 			port->p_hidden_in = protocols[port->p_protocol]?0:1;
913 	}
914 
915 	/* If we want only one neighbor, we take the first one */
916 	if (cfg->g_config.c_smart & mask &
917 	    (SMART_OUTGOING_ONE_NEIGH | SMART_INCOMING_ONE_NEIGH)) {
918 		found = 0;
919 		TAILQ_FOREACH(port, &hardware->h_rports, p_entries) {
920 			if (mask == SMART_OUTGOING) {
921 				if (found) port->p_hidden_out = 1;
922 				if (!port->p_hidden_out)
923 					found = 1;
924 			}
925 			if (mask == SMART_INCOMING) {
926 				if (found) port->p_hidden_in = 1;
927 				if (!port->p_hidden_in)
928 					found = 1;
929 			}
930 		}
931 	}
932 
933 	/* Print a debug message summarizing the operation */
934 	for (i = 0; i <= LLDPD_MODE_MAX; i++) protocols[i] = 0;
935 	k = j = 0;
936 	TAILQ_FOREACH(port, &hardware->h_rports, p_entries) {
937 		if (!(((mask == SMART_OUTGOING) && port->p_hidden_out) ||
938 		      ((mask == SMART_INCOMING) && port->p_hidden_in))) {
939 			k++;
940 			protocols[port->p_protocol] = 1;
941 		}
942 		j++;
943 	}
944 	buffer[0] = '\0';
945 	for (i=0; cfg->g_protocols[i].mode != 0; i++) {
946 		if (cfg->g_protocols[i].enabled && protocols[cfg->g_protocols[i].mode]) {
947 			if (strlen(buffer) +
948 			    strlen(cfg->g_protocols[i].name) + 3 > sizeof(buffer)) {
949 				/* Unlikely, our buffer is too small */
950 				memcpy(buffer + sizeof(buffer) - 4, "...", 4);
951 				break;
952 			}
953 			if (buffer[0])
954 				strncat(buffer, ", ", 2);
955 			strncat(buffer, cfg->g_protocols[i].name, strlen(cfg->g_protocols[i].name));
956 		}
957 	}
958 	log_debug("smartfilter", "%s: %s: %d visible neighbors (out of %d)",
959 	    hardware->h_ifname,
960 	    (mask == SMART_OUTGOING)?"out filter":"in filter",
961 	    k, j);
962 	log_debug("smartfilter", "%s: protocols: %s",
963 	    hardware->h_ifname, buffer[0]?buffer:"(none)");
964 }
965 
966 /* Hide unwanted ports depending on smart mode set by the user */
967 static void
lldpd_hide_all(struct lldpd * cfg)968 lldpd_hide_all(struct lldpd *cfg)
969 {
970 	struct lldpd_hardware *hardware;
971 
972 	if (!cfg->g_config.c_smart)
973 		return;
974 	log_debug("smartfilter", "apply smart filter results on all ports");
975 	TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) {
976 		if (cfg->g_config.c_smart & SMART_INCOMING_FILTER)
977 			lldpd_hide_ports(cfg, hardware, SMART_INCOMING);
978 		if (cfg->g_config.c_smart & SMART_OUTGOING_FILTER)
979 			lldpd_hide_ports(cfg, hardware, SMART_OUTGOING);
980 	}
981 }
982 
983 /* If PD device and PSE allocated power, echo back this change. If we have
984  * several LLDP neighbors, we use the latest updated. */
985 static void
lldpd_dot3_power_pd_pse(struct lldpd_hardware * hardware)986 lldpd_dot3_power_pd_pse(struct lldpd_hardware *hardware)
987 {
988 #ifdef ENABLE_DOT3
989 	struct lldpd_port *port, *selected_port = NULL;
990 	/* Are we a PD device? */
991 	if (hardware->h_lport.p_power.devicetype != LLDP_DOT3_POWER_PD)
992 		return;
993 	TAILQ_FOREACH(port, &hardware->h_rports, p_entries) {
994 		if (port->p_hidden_in)
995 			continue;
996 
997 		if (port->p_protocol != LLDPD_MODE_LLDP && port->p_protocol != LLDPD_MODE_CDPV2)
998 			continue;
999 
1000 		if (port->p_power.devicetype != LLDP_DOT3_POWER_PSE)
1001 			continue;
1002 		if (!selected_port || port->p_lastupdate > selected_port->p_lastupdate)
1003 			selected_port = port;
1004 	}
1005 	if (selected_port && selected_port->p_power.allocated != hardware->h_lport.p_power.allocated) {
1006 		log_info("receive", "for %s, PSE told us allocated is now %d instead of %d",
1007 		    hardware->h_ifname,
1008 		    selected_port->p_power.allocated,
1009 		    hardware->h_lport.p_power.allocated);
1010 		hardware->h_lport.p_power.allocated = selected_port->p_power.allocated;
1011 		hardware->h_lport.p_power.allocated_a = selected_port->p_power.allocated_a;
1012 		hardware->h_lport.p_power.allocated_b = selected_port->p_power.allocated_b;
1013 		levent_schedule_pdu(hardware);
1014 	}
1015 
1016 #ifdef ENABLE_CDP
1017 	if (selected_port && selected_port->p_cdp_power.management_id != hardware->h_lport.p_cdp_power.management_id) {
1018 		hardware->h_lport.p_cdp_power.management_id = selected_port->p_cdp_power.management_id;
1019 	}
1020 #endif
1021 
1022 #endif
1023 }
1024 
1025 void
lldpd_recv(struct lldpd * cfg,struct lldpd_hardware * hardware,int fd)1026 lldpd_recv(struct lldpd *cfg, struct lldpd_hardware *hardware, int fd)
1027 {
1028 	char *buffer = NULL;
1029 	int n;
1030 	log_debug("receive", "receive a frame on %s",
1031 	    hardware->h_ifname);
1032 	if ((buffer = (char *)malloc(hardware->h_mtu)) == NULL) {
1033 		log_warn("receive", "failed to alloc reception buffer");
1034 		return;
1035 	}
1036 	if ((n = hardware->h_ops->recv(cfg, hardware,
1037 		    fd, buffer,
1038 		    hardware->h_mtu)) == -1) {
1039 		log_debug("receive", "discard frame received on %s",
1040 		    hardware->h_ifname);
1041 		free(buffer);
1042 		return;
1043 	}
1044 	if (hardware->h_lport.p_disable_rx) {
1045 		log_debug("receive", "RX disabled, ignore the frame on %s",
1046 		    hardware->h_ifname);
1047 		free(buffer);
1048 		return;
1049 	}
1050 	if (cfg->g_config.c_paused) {
1051 		log_debug("receive", "paused, ignore the frame on %s",
1052 			hardware->h_ifname);
1053 		free(buffer);
1054 		return;
1055 	}
1056 	hardware->h_rx_cnt++;
1057 	log_debug("receive", "decode received frame on %s",
1058 	    hardware->h_ifname);
1059 	TRACE(LLDPD_FRAME_RECEIVED(hardware->h_ifname, buffer, (size_t)n));
1060 	lldpd_decode(cfg, buffer, n, hardware);
1061 	lldpd_hide_all(cfg); /* Immediatly hide */
1062 	lldpd_dot3_power_pd_pse(hardware);
1063 	lldpd_count_neighbors(cfg);
1064 	free(buffer);
1065 }
1066 
1067 static void
lldpd_send_shutdown(struct lldpd_hardware * hardware)1068 lldpd_send_shutdown(struct lldpd_hardware *hardware)
1069 {
1070 	struct lldpd *cfg = hardware->h_cfg;
1071 	if (cfg->g_config.c_receiveonly || cfg->g_config.c_paused) return;
1072 	if (hardware->h_lport.p_disable_tx) return;
1073 	if ((hardware->h_flags & IFF_RUNNING) == 0)
1074 		return;
1075 
1076 	/* It's safe to call `lldp_send_shutdown()` because shutdown LLDPU will
1077 	 * only be emitted if LLDP was sent on that port. */
1078 	if (lldp_send_shutdown(hardware->h_cfg, hardware) != 0)
1079 		log_warnx("send", "unable to send shutdown LLDPDU on %s",
1080 		    hardware->h_ifname);
1081 }
1082 
1083 void
lldpd_send(struct lldpd_hardware * hardware)1084 lldpd_send(struct lldpd_hardware *hardware)
1085 {
1086 	struct lldpd *cfg = hardware->h_cfg;
1087 	struct lldpd_port *port;
1088 	int i, sent;
1089 
1090 	if (cfg->g_config.c_receiveonly || cfg->g_config.c_paused) return;
1091 	if (hardware->h_lport.p_disable_tx) return;
1092 	if ((hardware->h_flags & IFF_RUNNING) == 0)
1093 		return;
1094 
1095 	log_debug("send", "send PDU on %s", hardware->h_ifname);
1096 	sent = 0;
1097 	for (i=0; cfg->g_protocols[i].mode != 0; i++) {
1098 		if (!cfg->g_protocols[i].enabled)
1099 			continue;
1100 		/* We send only if we have at least one remote system
1101 		 * speaking this protocol or if the protocol is forced */
1102 		if (cfg->g_protocols[i].enabled > 1) {
1103 			cfg->g_protocols[i].send(cfg, hardware);
1104 			sent++;
1105 			continue;
1106 		}
1107 		TAILQ_FOREACH(port, &hardware->h_rports, p_entries) {
1108 			/* If this remote port is disabled, we don't
1109 			 * consider it */
1110 			if (port->p_hidden_out)
1111 				continue;
1112 			if (port->p_protocol ==
1113 			    cfg->g_protocols[i].mode) {
1114 				TRACE(LLDPD_FRAME_SEND(hardware->h_ifname,
1115 					cfg->g_protocols[i].name));
1116 				log_debug("send", "send PDU on %s with protocol %s",
1117 				    hardware->h_ifname,
1118 				    cfg->g_protocols[i].name);
1119 				cfg->g_protocols[i].send(cfg,
1120 				    hardware);
1121 				hardware->h_lport.p_protocol = cfg->g_protocols[i].mode;
1122 				sent++;
1123 				break;
1124 			}
1125 		}
1126 	}
1127 
1128 	if (!sent) {
1129 		/* Nothing was sent for this port, let's speak the first
1130 		 * available protocol. */
1131 		for (i = 0; cfg->g_protocols[i].mode != 0; i++) {
1132 			if (!cfg->g_protocols[i].enabled) continue;
1133 			TRACE(LLDPD_FRAME_SEND(hardware->h_ifname,
1134 				cfg->g_protocols[i].name));
1135 			log_debug("send", "fallback to protocol %s for %s",
1136 			    cfg->g_protocols[i].name, hardware->h_ifname);
1137 			cfg->g_protocols[i].send(cfg,
1138 			    hardware);
1139 			break;
1140 		}
1141 		if (cfg->g_protocols[i].mode == 0)
1142 			log_warnx("send", "no protocol enabled, dunno what to send");
1143 	}
1144 }
1145 
1146 #ifdef ENABLE_LLDPMED
1147 static void
lldpd_med(struct lldpd_chassis * chassis)1148 lldpd_med(struct lldpd_chassis *chassis)
1149 {
1150 	static short int once = 0;
1151 	if (!once) {
1152 		chassis->c_med_hw = dmi_hw();
1153 		chassis->c_med_fw = dmi_fw();
1154 		chassis->c_med_sn = dmi_sn();
1155 		chassis->c_med_manuf = dmi_manuf();
1156 		chassis->c_med_model = dmi_model();
1157 		chassis->c_med_asset = dmi_asset();
1158 		once = 1;
1159 	}
1160 }
1161 #endif
1162 
1163 static int
lldpd_routing_enabled(struct lldpd * cfg)1164 lldpd_routing_enabled(struct lldpd *cfg)
1165 {
1166 	int routing;
1167 
1168 	if ((LOCAL_CHASSIS(cfg)->c_cap_available & LLDP_CAP_ROUTER) == 0)
1169 		return 0;
1170 
1171 	if ((routing = interfaces_routing_enabled(cfg)) == -1) {
1172 		log_debug("localchassis", "unable to check if routing is enabled");
1173 		return 0;
1174 	}
1175 	return routing;
1176 }
1177 
1178 void
lldpd_update_localchassis(struct lldpd * cfg)1179 lldpd_update_localchassis(struct lldpd *cfg)
1180 {
1181 	struct utsname un;
1182 	char *hp;
1183 
1184 	log_debug("localchassis", "update information for local chassis");
1185 	assert(LOCAL_CHASSIS(cfg) != NULL);
1186 
1187 	/* Set system name and description */
1188 	if (uname(&un) < 0)
1189 		fatal("localchassis", "failed to get system information");
1190 	if (cfg->g_config.c_hostname) {
1191 		log_debug("localchassis", "use overridden system name `%s`", cfg->g_config.c_hostname);
1192 		hp = cfg->g_config.c_hostname;
1193 	} else {
1194 		if ((hp = priv_gethostname()) == NULL)
1195 			fatal("localchassis", "failed to get system name");
1196 	}
1197 	free(LOCAL_CHASSIS(cfg)->c_name);
1198 	free(LOCAL_CHASSIS(cfg)->c_descr);
1199 	if ((LOCAL_CHASSIS(cfg)->c_name = strdup(hp)) == NULL)
1200 		fatal("localchassis", NULL);
1201         if (cfg->g_config.c_description) {
1202 		log_debug("localchassis", "use overridden description `%s`", cfg->g_config.c_description);
1203                 if (asprintf(&LOCAL_CHASSIS(cfg)->c_descr, "%s",
1204 			cfg->g_config.c_description) == -1)
1205 			fatal("localchassis", "failed to set full system description");
1206         } else {
1207 	        if (cfg->g_config.c_advertise_version) {
1208 			log_debug("localchassis", "advertise system version");
1209 		        if (asprintf(&LOCAL_CHASSIS(cfg)->c_descr, "%s %s %s %s %s",
1210 			        cfg->g_lsb_release?cfg->g_lsb_release:"",
1211 				un.sysname, un.release, un.version, un.machine)
1212                                 == -1)
1213 			        fatal("localchassis", "failed to set full system description");
1214 	        } else {
1215 			log_debug("localchassis", "do not advertise system version");
1216 		        if (asprintf(&LOCAL_CHASSIS(cfg)->c_descr, "%s",
1217                                 cfg->g_lsb_release?cfg->g_lsb_release:un.sysname) == -1)
1218 			        fatal("localchassis", "failed to set minimal system description");
1219 	        }
1220         }
1221 	if (cfg->g_config.c_platform == NULL)
1222 		cfg->g_config.c_platform = strdup(un.sysname);
1223 
1224 	/* Check routing */
1225 	if (lldpd_routing_enabled(cfg)) {
1226 		log_debug("localchassis", "routing is enabled, enable router capability");
1227 		LOCAL_CHASSIS(cfg)->c_cap_enabled |= LLDP_CAP_ROUTER;
1228 	} else
1229 		LOCAL_CHASSIS(cfg)->c_cap_enabled &= ~LLDP_CAP_ROUTER;
1230 
1231 #ifdef ENABLE_LLDPMED
1232 	if (LOCAL_CHASSIS(cfg)->c_cap_available & LLDP_CAP_TELEPHONE)
1233 		LOCAL_CHASSIS(cfg)->c_cap_enabled |= LLDP_CAP_TELEPHONE;
1234 	lldpd_med(LOCAL_CHASSIS(cfg));
1235 	free(LOCAL_CHASSIS(cfg)->c_med_sw);
1236 	if (cfg->g_config.c_advertise_version)
1237 		LOCAL_CHASSIS(cfg)->c_med_sw = strdup(un.release);
1238 	else
1239 		LOCAL_CHASSIS(cfg)->c_med_sw = strdup("Unknown");
1240 #endif
1241 	if ((LOCAL_CHASSIS(cfg)->c_cap_available & LLDP_CAP_STATION) &&
1242 		(LOCAL_CHASSIS(cfg)->c_cap_enabled == 0))
1243 		LOCAL_CHASSIS(cfg)->c_cap_enabled = LLDP_CAP_STATION;
1244 	else if (LOCAL_CHASSIS(cfg)->c_cap_enabled != LLDP_CAP_STATION)
1245 		LOCAL_CHASSIS(cfg)->c_cap_enabled &= ~LLDP_CAP_STATION;
1246 
1247 	/* Set chassis ID if needed. This is only done if chassis ID
1248 	   has not been set previously (with the MAC address of an
1249 	   interface for example)
1250 	*/
1251 	if (cfg->g_config.c_cid_string != NULL) {
1252 		log_debug("localchassis", "use specified chassis ID string");
1253 		free(LOCAL_CHASSIS(cfg)->c_id);
1254 		if (!(LOCAL_CHASSIS(cfg)->c_id = strdup(cfg->g_config.c_cid_string)))
1255 			fatal("localchassis", NULL);
1256 		LOCAL_CHASSIS(cfg)->c_id_len = strlen(cfg->g_config.c_cid_string);
1257 		LOCAL_CHASSIS(cfg)->c_id_subtype = LLDP_CHASSISID_SUBTYPE_LOCAL;
1258 	}
1259 	if (LOCAL_CHASSIS(cfg)->c_id == NULL) {
1260 		log_debug("localchassis", "no chassis ID is currently set, use chassis name");
1261 		if (!(LOCAL_CHASSIS(cfg)->c_id = strdup(LOCAL_CHASSIS(cfg)->c_name)))
1262 			fatal("localchassis", NULL);
1263 		LOCAL_CHASSIS(cfg)->c_id_len = strlen(LOCAL_CHASSIS(cfg)->c_name);
1264 		LOCAL_CHASSIS(cfg)->c_id_subtype = LLDP_CHASSISID_SUBTYPE_LOCAL;
1265 	}
1266 }
1267 
1268 void
lldpd_update_localports(struct lldpd * cfg)1269 lldpd_update_localports(struct lldpd *cfg)
1270 {
1271 	struct lldpd_hardware *hardware;
1272 
1273 	log_debug("localchassis", "update information for local ports");
1274 
1275 	/* h_flags is set to 0 for each port. If the port is updated, h_flags
1276 	 * will be set to a non-zero value. This will allow us to clean up any
1277 	 * non up-to-date port */
1278 	TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries)
1279 	    hardware->h_flags = 0;
1280 
1281 	TRACE(LLDPD_INTERFACES_UPDATE());
1282 	interfaces_update(cfg);
1283 	lldpd_cleanup(cfg);
1284 	lldpd_reset_timer(cfg);
1285 }
1286 
1287 void
lldpd_loop(struct lldpd * cfg)1288 lldpd_loop(struct lldpd *cfg)
1289 {
1290 	/* Main loop.
1291 	   1. Update local ports information
1292 	   2. Update local chassis information
1293 	*/
1294 	log_debug("loop", "start new loop");
1295 	LOCAL_CHASSIS(cfg)->c_cap_enabled = 0;
1296 	/* Information for local ports is triggered even when it is possible to
1297 	 * update them on some other event because we want to refresh them if we
1298 	 * missed something. */
1299 	log_debug("loop", "update information for local ports");
1300 	lldpd_update_localports(cfg);
1301 	log_debug("loop", "update information for local chassis");
1302 	lldpd_update_localchassis(cfg);
1303 	lldpd_count_neighbors(cfg);
1304 }
1305 
1306 static void
lldpd_exit(struct lldpd * cfg)1307 lldpd_exit(struct lldpd *cfg)
1308 {
1309 	struct lldpd_hardware *hardware, *hardware_next;
1310 	log_debug("main", "exit lldpd");
1311 
1312 	TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries)
1313 		lldpd_send_shutdown(hardware);
1314 
1315 	close(cfg->g_ctl);
1316 	priv_ctl_cleanup(cfg->g_ctlname);
1317 	log_debug("main", "cleanup hardware information");
1318 	for (hardware = TAILQ_FIRST(&cfg->g_hardware); hardware != NULL;
1319 	     hardware = hardware_next) {
1320 		hardware_next = TAILQ_NEXT(hardware, h_entries);
1321 		log_debug("main", "cleanup interface %s", hardware->h_ifname);
1322 		lldpd_remote_cleanup(hardware, NULL, 1);
1323 		lldpd_hardware_cleanup(cfg, hardware);
1324 	}
1325 	interfaces_cleanup(cfg);
1326 	lldpd_port_cleanup(cfg->g_default_local_port, 1);
1327 	lldpd_all_chassis_cleanup(cfg);
1328 	free(cfg->g_default_local_port);
1329 	free(cfg->g_config.c_platform);
1330 	levent_shutdown(cfg);
1331 }
1332 
1333 /**
1334  * Run lldpcli to configure lldpd.
1335  *
1336  * @return PID of running lldpcli or -1 if error.
1337  */
1338 static pid_t
lldpd_configure(int use_syslog,int debug,const char * path,const char * ctlname,const char * config_path)1339 lldpd_configure(int use_syslog, int debug, const char *path, const char *ctlname, const char *config_path)
1340 {
1341 	pid_t lldpcli = vfork();
1342 	int devnull;
1343 
1344 	char sdebug[debug + 4];
1345 	if (use_syslog)
1346 		strlcpy(sdebug, "-s", 3);
1347 	else {
1348 		/* debug = 0 -> -sd */
1349 		/* debug = 1 -> -sdd */
1350 		/* debug = 2 -> -sddd */
1351 		memset(sdebug, 'd', sizeof(sdebug));
1352 		sdebug[debug + 3] = '\0';
1353 		sdebug[0] = '-'; sdebug[1] = 's';
1354 	}
1355 	log_debug("main", "invoke %s %s", path, sdebug);
1356 
1357 	switch (lldpcli) {
1358 	case -1:
1359 		log_warn("main", "unable to fork");
1360 		return -1;
1361 	case 0:
1362 		/* Child, exec lldpcli */
1363 		if ((devnull = open("/dev/null", O_RDWR, 0)) != -1) {
1364 			dup2(devnull,   STDIN_FILENO);
1365 			dup2(devnull,   STDOUT_FILENO);
1366 			if (devnull > 2) close(devnull);
1367 
1368 			if (config_path) {
1369 				execl(path, "lldpcli", sdebug,
1370 				    "-u", ctlname,
1371 				    "-C", config_path,
1372 				    "resume",
1373 				    (char *)NULL);
1374 			} else {
1375 				execl(path, "lldpcli", sdebug,
1376 				    "-u", ctlname,
1377 				    "-C", SYSCONFDIR "/lldpd.conf",
1378 				    "-C", SYSCONFDIR "/lldpd.d",
1379 				    "resume",
1380 				    (char *)NULL);
1381 			}
1382 
1383 			log_warn("main", "unable to execute %s", path);
1384 			log_warnx("main", "configuration is incomplete, lldpd needs to be unpaused");
1385 		}
1386 		_exit(127);
1387 		break;
1388 	default:
1389 		/* Father, don't do anything stupid */
1390 		return lldpcli;
1391 	}
1392 	/* Should not be here */
1393 	return -1;
1394 }
1395 
1396 struct intint { int a; int b; };
1397 static const struct intint filters[] = {
1398 	{  0, 0 },
1399 	{  1, SMART_INCOMING_FILTER | SMART_INCOMING_ONE_PROTO |
1400 	      SMART_OUTGOING_FILTER | SMART_OUTGOING_ONE_PROTO },
1401 	{  2, SMART_INCOMING_FILTER | SMART_INCOMING_ONE_PROTO },
1402 	{  3, SMART_OUTGOING_FILTER | SMART_OUTGOING_ONE_PROTO },
1403 	{  4, SMART_INCOMING_FILTER | SMART_OUTGOING_FILTER },
1404 	{  5, SMART_INCOMING_FILTER },
1405 	{  6, SMART_OUTGOING_FILTER },
1406 	{  7, SMART_INCOMING_FILTER | SMART_INCOMING_ONE_PROTO | SMART_INCOMING_ONE_NEIGH |
1407 	      SMART_OUTGOING_FILTER | SMART_OUTGOING_ONE_PROTO },
1408 	{  8, SMART_INCOMING_FILTER | SMART_INCOMING_ONE_PROTO | SMART_INCOMING_ONE_NEIGH },
1409 	{  9, SMART_INCOMING_FILTER | SMART_INCOMING_ONE_NEIGH |
1410 	      SMART_OUTGOING_FILTER | SMART_OUTGOING_ONE_PROTO },
1411 	{ 10, SMART_OUTGOING_FILTER | SMART_OUTGOING_ONE_NEIGH },
1412 	{ 11, SMART_INCOMING_FILTER | SMART_INCOMING_ONE_NEIGH },
1413 	{ 12, SMART_INCOMING_FILTER | SMART_INCOMING_ONE_NEIGH |
1414 	      SMART_OUTGOING_FILTER | SMART_OUTGOING_ONE_NEIGH },
1415 	{ 13, SMART_INCOMING_FILTER | SMART_INCOMING_ONE_NEIGH |
1416 	      SMART_OUTGOING_FILTER },
1417 	{ 14, SMART_INCOMING_FILTER | SMART_INCOMING_ONE_PROTO |
1418 	      SMART_OUTGOING_FILTER | SMART_OUTGOING_ONE_NEIGH },
1419 	{ 15, SMART_INCOMING_FILTER | SMART_INCOMING_ONE_PROTO |
1420 	      SMART_OUTGOING_FILTER },
1421 	{ 16, SMART_INCOMING_FILTER | SMART_INCOMING_ONE_PROTO | SMART_INCOMING_ONE_NEIGH |
1422 	      SMART_OUTGOING_FILTER | SMART_OUTGOING_ONE_NEIGH },
1423 	{ 17, SMART_INCOMING_FILTER | SMART_INCOMING_ONE_PROTO | SMART_INCOMING_ONE_NEIGH |
1424 	      SMART_OUTGOING_FILTER },
1425 	{ 18, SMART_INCOMING_FILTER |
1426 	      SMART_OUTGOING_FILTER | SMART_OUTGOING_ONE_NEIGH },
1427 	{ 19, SMART_INCOMING_FILTER |
1428 	      SMART_OUTGOING_FILTER | SMART_OUTGOING_ONE_PROTO },
1429 	{ -1, 0 }
1430 };
1431 
1432 #ifndef HOST_OS_OSX
1433 /**
1434  * Tell if we have been started by systemd.
1435  */
1436 static int
lldpd_started_by_systemd()1437 lldpd_started_by_systemd()
1438 {
1439 #ifdef HOST_OS_LINUX
1440 	int fd = -1;
1441 	const char *notifysocket = getenv("NOTIFY_SOCKET");
1442 	if (!notifysocket ||
1443 	    !strchr("@/", notifysocket[0]) ||
1444 	    strlen(notifysocket) < 2)
1445 		return 0;
1446 
1447 	log_debug("main", "running with systemd, don't fork but signal ready");
1448 	if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
1449 		log_warn("main", "unable to open systemd notification socket %s",
1450 		    notifysocket);
1451 		return 0;
1452 	}
1453 
1454 	struct sockaddr_un su = { .sun_family = AF_UNIX };
1455 	strlcpy(su.sun_path, notifysocket, sizeof(su.sun_path));
1456 	if (notifysocket[0] == '@') su.sun_path[0] = 0;
1457 
1458 	struct iovec iov = {
1459 		.iov_base = "READY=1",
1460 		.iov_len = strlen("READY=1")
1461 	};
1462 	struct msghdr hdr = {
1463 		.msg_name = &su,
1464 		.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(notifysocket),
1465 		.msg_iov = &iov,
1466 		.msg_iovlen = 1
1467 	};
1468 	unsetenv("NOTIFY_SOCKET");
1469 	if (sendmsg(fd, &hdr, MSG_NOSIGNAL) < 0) {
1470 		log_warn("main", "unable to send notification to systemd");
1471 		close(fd);
1472 		return 0;
1473 	}
1474 	close(fd);
1475 	return 1;
1476 #else
1477 	return 0;
1478 #endif
1479 }
1480 #endif
1481 
1482 #ifdef HOST_OS_LINUX
1483 static void
version_convert(const char * sversion,unsigned iversion[],size_t n)1484 version_convert(const char *sversion, unsigned iversion[], size_t n)
1485 {
1486 	const char *p = sversion;
1487 	char *end;
1488 	for (size_t i = 0; i < n; i++) {
1489 		iversion[i] = strtol(p, &end, 10);
1490 		if (*end != '.') break;
1491 		p = end + 1;
1492 	}
1493 }
1494 
1495 static void
version_check(void)1496 version_check(void)
1497 {
1498 	struct utsname uts;
1499 	if (uname(&uts) == -1) return;
1500 	unsigned version_min[3] = {};
1501 	unsigned version_cur[3] = {};
1502 	version_convert(uts.release, version_cur, 3);
1503 	version_convert(MIN_LINUX_KERNEL_VERSION, version_min, 3);
1504 	if (version_min[0] > version_cur[0] ||
1505 	    (version_min[0] == version_cur[0] && version_min[1] > version_cur[1]) ||
1506 	    (version_min[0] == version_cur[0] && version_min[1] == version_cur[1] &&
1507 		version_min[2] > version_cur[2])) {
1508 		log_warnx("lldpd", "minimal kernel version required is %s, got %s",
1509 		    MIN_LINUX_KERNEL_VERSION, uts.release);
1510 		log_warnx("lldpd", "lldpd may be unable to detect bonds and bridges correctly");
1511 #ifndef ENABLE_OLDIES
1512 		log_warnx("lldpd", "consider recompiling with --enable-oldies option");
1513 #endif
1514 	}
1515 }
1516 #else
version_check(void)1517 static void version_check(void) {}
1518 #endif
1519 
1520 int
lldpd_main(int argc,char * argv[],char * envp[])1521 lldpd_main(int argc, char *argv[], char *envp[])
1522 {
1523 	struct lldpd *cfg;
1524 	struct lldpd_chassis *lchassis;
1525 	int ch, debug = 0, use_syslog = 1, daemonize = 1;
1526 	const char *errstr;
1527 #ifdef USE_SNMP
1528 	int snmp = 0;
1529 	const char *agentx = NULL;	/* AgentX socket */
1530 #endif
1531 	const char *ctlname = NULL;
1532 	char *mgmtp = NULL;
1533 	char *cidp = NULL;
1534 	char *interfaces = NULL;
1535 	/* We do not want more options here. Please add them in lldpcli instead
1536 	 * unless there is a very good reason. Most command-line options will
1537 	 * get deprecated at some point. */
1538 	char *popt, opts[] =
1539 	    "H:vhkrdD:p:xX:m:u:4:6:I:C:p:M:P:S:iL:O:@                    ";
1540 	int i, found, advertise_version = 1;
1541 #ifdef ENABLE_LLDPMED
1542 	int lldpmed = 0, noinventory = 0;
1543 	int enable_fast_start = 1;
1544 #endif
1545 	char *descr_override = NULL;
1546 	char *platform_override = NULL;
1547 	char *lsb_release = NULL;
1548 	const char *lldpcli = LLDPCLI_PATH;
1549 	const char *pidfile = LLDPD_PID_FILE;
1550 	int smart = 15;
1551 	int receiveonly = 0, version = 0;
1552 	int ctl;
1553 	const char *config_file = NULL;
1554 
1555 #ifdef ENABLE_PRIVSEP
1556 	/* Non privileged user */
1557 	struct passwd *user;
1558 	struct group *group;
1559 	uid_t uid;
1560 	gid_t gid;
1561 #endif
1562 
1563 	saved_argv = argv;
1564 
1565 #if HAVE_SETPROCTITLE_INIT
1566 	setproctitle_init(argc, argv, envp);
1567 #endif
1568 
1569 	/*
1570 	 * Get and parse command line options
1571 	 */
1572 	if ((popt = strchr(opts, '@')) != NULL) {
1573 		for (i=0;
1574 		     protos[i].mode != 0 && *popt != '\0';
1575 		     i++)
1576 			*(popt++) = protos[i].arg;
1577 		*popt = '\0';
1578 	}
1579 	while ((ch = getopt(argc, argv, opts)) != -1) {
1580 		switch (ch) {
1581 		case 'h':
1582 			usage();
1583 			break;
1584 		case 'v':
1585 			version++;
1586 			break;
1587 		case 'd':
1588 			if (daemonize)
1589 				daemonize = 0;
1590 			else if (use_syslog)
1591 				use_syslog = 0;
1592 			else
1593 				debug++;
1594 			break;
1595 		case 'D':
1596 			log_accept(optarg);
1597 			break;
1598 		case 'p':
1599 			pidfile = optarg;
1600 			break;
1601 		case 'r':
1602 			receiveonly = 1;
1603 			break;
1604 		case 'm':
1605 			if (mgmtp) {
1606 				fprintf(stderr, "-m can only be used once\n");
1607 				usage();
1608 			}
1609 			mgmtp = strdup(optarg);
1610 			break;
1611 		case 'u':
1612 			if (ctlname) {
1613 				fprintf(stderr, "-u can only be used once\n");
1614 				usage();
1615 			}
1616 			ctlname = optarg;
1617 			break;
1618 		case 'I':
1619 			if (interfaces) {
1620 				fprintf(stderr, "-I can only be used once\n");
1621 				usage();
1622 			}
1623 			interfaces = strdup(optarg);
1624 			break;
1625 		case 'C':
1626 			if (cidp) {
1627 				fprintf(stderr, "-C can only be used once\n");
1628 				usage();
1629 			}
1630 			cidp = strdup(optarg);
1631 			break;
1632 		case 'L':
1633 			if (strlen(optarg)) lldpcli = optarg;
1634 			else lldpcli = NULL;
1635 			break;
1636 		case 'k':
1637 			advertise_version = 0;
1638 			break;
1639 #ifdef ENABLE_LLDPMED
1640 		case 'M':
1641 			lldpmed = strtonum(optarg, 1, 4, &errstr);
1642 			if (errstr) {
1643 				fprintf(stderr, "-M requires an argument between 1 and 4\n");
1644 				usage();
1645 			}
1646 			break;
1647 		case 'i':
1648 			noinventory = 1;
1649 			break;
1650 #else
1651 		case 'M':
1652 		case 'i':
1653 			fprintf(stderr, "LLDP-MED support is not built-in\n");
1654 			usage();
1655 			break;
1656 #endif
1657 #ifdef USE_SNMP
1658 		case 'x':
1659 			snmp = 1;
1660 			break;
1661 		case 'X':
1662 			if (agentx) {
1663 				fprintf(stderr, "-X can only be used once\n");
1664 				usage();
1665 			}
1666 			snmp = 1;
1667 			agentx = optarg;
1668 			break;
1669 #else
1670 		case 'x':
1671 		case 'X':
1672 			fprintf(stderr, "SNMP support is not built-in\n");
1673 			usage();
1674 #endif
1675 			break;
1676                 case 'S':
1677 			if (descr_override) {
1678 				fprintf(stderr, "-S can only be used once\n");
1679 				usage();
1680 			}
1681                         descr_override = strdup(optarg);
1682                         break;
1683 		case 'P':
1684 			if (platform_override) {
1685 				fprintf(stderr, "-P can only be used once\n");
1686 				usage();
1687 			}
1688 			platform_override = strdup(optarg);
1689 			break;
1690 		case 'H':
1691 			smart = strtonum(optarg, 0, sizeof(filters)/sizeof(filters[0]),
1692 			    &errstr);
1693 			if (errstr) {
1694 				fprintf(stderr, "-H requires an int between 0 and %zu\n",
1695 				    sizeof(filters)/sizeof(filters[0]));
1696 				usage();
1697 			}
1698 			break;
1699 		case 'O':
1700 			if (config_file) {
1701 				fprintf(stderr, "-O can only be used once\n");
1702 				usage();
1703 			}
1704 			config_file = optarg;
1705 			break;
1706 		default:
1707 			found = 0;
1708 			for (i=0; protos[i].mode != 0; i++) {
1709 				if (ch == protos[i].arg) {
1710 					found = 1;
1711 					protos[i].enabled++;
1712 				}
1713 			}
1714 			if (!found)
1715 				usage();
1716 		}
1717 	}
1718 
1719 	if (version) {
1720 		version_display(stdout, "lldpd", version > 1);
1721 		exit(0);
1722 	}
1723 
1724 	if (ctlname == NULL) ctlname = LLDPD_CTL_SOCKET;
1725 
1726 	/* Set correct smart mode */
1727 	for (i=0; (filters[i].a != -1) && (filters[i].a != smart); i++);
1728 	if (filters[i].a == -1) {
1729 		fprintf(stderr, "Incorrect mode for -H\n");
1730 		usage();
1731 	}
1732 	smart = filters[i].b;
1733 
1734 	log_init(use_syslog, debug, __progname);
1735 	tzset();		/* Get timezone info before chroot */
1736 	if (use_syslog && daemonize) {
1737 		/* So, we use syslog and we daemonize (or we are started by
1738 		 * systemd). No need to continue writing to stdout. */
1739 		int fd;
1740 		if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
1741 			dup2(fd, STDIN_FILENO);
1742 			dup2(fd, STDOUT_FILENO);
1743 			dup2(fd, STDERR_FILENO);
1744 			if (fd > 2) close(fd);
1745 		}
1746 	}
1747 	log_debug("main", "lldpd " PACKAGE_VERSION " starting...");
1748 	version_check();
1749 
1750 	/* Grab uid and gid to use for priv sep */
1751 #ifdef ENABLE_PRIVSEP
1752 	if ((user = getpwnam(PRIVSEP_USER)) == NULL)
1753 		fatalx("main", "no " PRIVSEP_USER " user for privilege separation, please create it");
1754 	uid = user->pw_uid;
1755 	if ((group = getgrnam(PRIVSEP_GROUP)) == NULL)
1756 		fatalx("main", "no " PRIVSEP_GROUP " group for privilege separation, please create it");
1757 	gid = group->gr_gid;
1758 #endif
1759 
1760 	/* Create and setup socket */
1761 	int retry = 1;
1762 	log_debug("main", "creating control socket");
1763 	while ((ctl = ctl_create(ctlname)) == -1) {
1764 		if (retry-- && errno == EADDRINUSE) {
1765 			/* Check if a daemon is really listening */
1766 			int tfd;
1767 			log_info("main", "unable to create control socket because it already exists");
1768 			log_info("main", "check if another instance is running");
1769 			if ((tfd = ctl_connect(ctlname)) != -1) {
1770 				/* Another instance is running */
1771 				close(tfd);
1772 				log_warnx("main", "another instance is running, please stop it");
1773 				fatalx("main", "giving up");
1774 			} else if (errno == ECONNREFUSED) {
1775 				/* Nobody is listening */
1776 				log_info("main", "old control socket is present, clean it");
1777 				ctl_cleanup(ctlname);
1778 				continue;
1779 			}
1780 			log_warn("main", "cannot determine if another daemon is already running");
1781 			fatalx("main", "giving up");
1782 		}
1783 		log_warn("main", "unable to create control socket at %s", ctlname);
1784 		fatalx("main", "giving up");
1785 	}
1786 #ifdef ENABLE_PRIVSEP
1787 	if (chown(ctlname, uid, gid) == -1)
1788 		log_warn("main", "unable to chown control socket");
1789 	if (chmod(ctlname,
1790 		S_IRUSR | S_IWUSR | S_IXUSR |
1791 		S_IRGRP | S_IWGRP | S_IXGRP) == -1)
1792 		log_warn("main", "unable to chmod control socket");
1793 #endif
1794 
1795 	/* Disable SIGPIPE */
1796 	signal(SIGPIPE, SIG_IGN);
1797 
1798 	/* Disable SIGHUP, until handlers are installed */
1799 	signal(SIGHUP, SIG_IGN);
1800 
1801 	/* Daemonization, unless started by systemd or launchd or debug */
1802 #ifndef HOST_OS_OSX
1803 	if (!lldpd_started_by_systemd() && daemonize) {
1804 		int pid;
1805 		char *spid;
1806 		log_debug("main", "going into background");
1807 		if (daemon(0, 1) != 0)
1808 			fatal("main", "failed to detach daemon");
1809 		if ((pid = open(pidfile,
1810 			    O_TRUNC | O_CREAT | O_WRONLY, 0666)) == -1)
1811 			fatal("main", "unable to open pid file " LLDPD_PID_FILE
1812 			    " (or the specified one)");
1813 		if (asprintf(&spid, "%d\n", getpid()) == -1)
1814 			fatal("main", "unable to create pid file " LLDPD_PID_FILE
1815 			    " (or the specified one)");
1816 		if (write(pid, spid, strlen(spid)) == -1)
1817 			fatal("main", "unable to write pid file " LLDPD_PID_FILE
1818 			    " (or the specified one)");
1819 		free(spid);
1820 		close(pid);
1821 	}
1822 #endif
1823 
1824 	/* Configuration with lldpcli */
1825 	if (lldpcli) {
1826 		if (!config_file) {
1827 			log_debug("main", "invoking lldpcli for default configuration locations");
1828 		} else {
1829 			log_debug("main", "invoking lldpcli for user supplied configuration location");
1830 		}
1831 		if (lldpd_configure(use_syslog, debug, lldpcli, ctlname, config_file) == -1)
1832 			fatal("main", "unable to spawn lldpcli");
1833 	}
1834 
1835 	/* Try to read system information from /etc/os-release if possible.
1836 	   Fall back to lsb_release for compatibility. */
1837 	log_debug("main", "get OS/LSB release information");
1838 	lsb_release = lldpd_get_os_release();
1839 	if (!lsb_release) {
1840 		lsb_release = lldpd_get_lsb_release();
1841 	}
1842 
1843 	log_debug("main", "initialize privilege separation");
1844 #ifdef ENABLE_PRIVSEP
1845 	priv_init(PRIVSEP_CHROOT, ctl, uid, gid);
1846 #else
1847 	priv_init(PRIVSEP_CHROOT, ctl, 0, 0);
1848 #endif
1849 
1850 	/* Initialization of global configuration */
1851 	if ((cfg = (struct lldpd *)
1852 	    calloc(1, sizeof(struct lldpd))) == NULL)
1853 		fatal("main", NULL);
1854 
1855 	lldpd_alloc_default_local_port(cfg);
1856 	cfg->g_ctlname = ctlname;
1857 	cfg->g_ctl = ctl;
1858 	cfg->g_config.c_mgmt_pattern = mgmtp;
1859 	cfg->g_config.c_cid_pattern = cidp;
1860 	cfg->g_config.c_iface_pattern = interfaces;
1861 	cfg->g_config.c_smart = smart;
1862 	if (lldpcli)
1863 		cfg->g_config.c_paused = 1;
1864 	cfg->g_config.c_receiveonly = receiveonly;
1865 	cfg->g_config.c_tx_interval = LLDPD_TX_INTERVAL * 1000;
1866 	cfg->g_config.c_tx_hold = LLDPD_TX_HOLD;
1867 	cfg->g_config.c_ttl = cfg->g_config.c_tx_interval * cfg->g_config.c_tx_hold;
1868 	cfg->g_config.c_ttl = (cfg->g_config.c_ttl + 999) / 1000;
1869 	cfg->g_config.c_max_neighbors = LLDPD_MAX_NEIGHBORS;
1870 #ifdef ENABLE_LLDPMED
1871 	cfg->g_config.c_enable_fast_start = enable_fast_start;
1872 	cfg->g_config.c_tx_fast_init = LLDPD_FAST_INIT;
1873 	cfg->g_config.c_tx_fast_interval = LLDPD_FAST_TX_INTERVAL;
1874 #endif
1875 #ifdef USE_SNMP
1876 	cfg->g_snmp = snmp;
1877 	cfg->g_snmp_agentx = agentx;
1878 #endif /* USE_SNMP */
1879 	cfg->g_config.c_bond_slave_src_mac_type = \
1880 	    LLDP_BOND_SLAVE_SRC_MAC_TYPE_LOCALLY_ADMINISTERED;
1881 
1882 	/* Get ioctl socket */
1883 	log_debug("main", "get an ioctl socket");
1884 	if ((cfg->g_sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
1885 		fatal("main", "failed to get ioctl socket");
1886 
1887 	/* Description */
1888 	if (!(cfg->g_config.c_advertise_version = advertise_version) &&
1889 	    lsb_release && lsb_release[strlen(lsb_release) - 1] == '\n')
1890 		lsb_release[strlen(lsb_release) - 1] = '\0';
1891 	cfg->g_lsb_release = lsb_release;
1892         if (descr_override)
1893            cfg->g_config.c_description = descr_override;
1894 
1895 	if (platform_override)
1896 		cfg->g_config.c_platform = platform_override;
1897 
1898 	/* Set system capabilities */
1899 	log_debug("main", "set system capabilities");
1900 	if ((lchassis = (struct lldpd_chassis*)
1901 		calloc(1, sizeof(struct lldpd_chassis))) == NULL)
1902 		fatal("localchassis", NULL);
1903 	cfg->g_config.c_cap_advertise = 1;
1904 	lchassis->c_cap_available = LLDP_CAP_BRIDGE | LLDP_CAP_WLAN |
1905 	    LLDP_CAP_ROUTER | LLDP_CAP_STATION;
1906 	cfg->g_config.c_mgmt_advertise = 1;
1907 	TAILQ_INIT(&lchassis->c_mgmt);
1908 #ifdef ENABLE_LLDPMED
1909 	if (lldpmed > 0) {
1910 		if (lldpmed == LLDP_MED_CLASS_III)
1911 			lchassis->c_cap_available |= LLDP_CAP_TELEPHONE;
1912 		lchassis->c_med_type = lldpmed;
1913 		lchassis->c_med_cap_available = LLDP_MED_CAP_CAP |
1914 		    LLDP_MED_CAP_IV | LLDP_MED_CAP_LOCATION |
1915 		    LLDP_MED_CAP_POLICY | LLDP_MED_CAP_MDI_PSE | LLDP_MED_CAP_MDI_PD;
1916 		cfg->g_config.c_noinventory = noinventory;
1917 	} else
1918 		cfg->g_config.c_noinventory = 1;
1919 #endif
1920 
1921 	log_debug("main", "initialize protocols");
1922 	cfg->g_protocols = protos;
1923 	for (i=0; protos[i].mode != 0; i++) {
1924 
1925 		/* With -ll, disable LLDP */
1926 		if (protos[i].mode == LLDPD_MODE_LLDP)
1927 			protos[i].enabled %= 3;
1928 		/* With -ccc force CDPV2, enable CDPV1 */
1929 		if (protos[i].mode == LLDPD_MODE_CDPV1 && protos[i].enabled == 3) {
1930 			protos[i].enabled = 1;
1931 		}
1932 		/* With -cc force CDPV1, enable CDPV2 */
1933 		if (protos[i].mode == LLDPD_MODE_CDPV2 && protos[i].enabled == 2) {
1934 			protos[i].enabled = 1;
1935 		}
1936 
1937 		/* With -cccc disable CDPV1, enable CDPV2 */
1938 		if (protos[i].mode == LLDPD_MODE_CDPV1 && protos[i].enabled >= 4) {
1939 			protos[i].enabled = 0;
1940 		}
1941 
1942 		/* With -cccc disable CDPV1, enable CDPV2; -ccccc will force CDPv2 */
1943 		if (protos[i].mode == LLDPD_MODE_CDPV2 && protos[i].enabled == 4) {
1944 			protos[i].enabled = 1;
1945 		}
1946 
1947 		if (protos[i].enabled > 1)
1948 			log_info("main", "protocol %s enabled and forced", protos[i].name);
1949 		else if (protos[i].enabled)
1950 			log_info("main", "protocol %s enabled", protos[i].name);
1951 		else
1952 			log_info("main", "protocol %s disabled", protos[i].name);
1953 	    }
1954 
1955 	TAILQ_INIT(&cfg->g_hardware);
1956 	TAILQ_INIT(&cfg->g_chassis);
1957 	TAILQ_INSERT_TAIL(&cfg->g_chassis, lchassis, c_entries);
1958 	lchassis->c_refcount++; /* We should always keep a reference to local chassis */
1959 
1960 	/* Main loop */
1961 	log_debug("main", "start main loop");
1962 	levent_loop(cfg);
1963 	lchassis->c_refcount--;
1964 	lldpd_exit(cfg);
1965 	free(cfg);
1966 
1967 	return (0);
1968 }
1969