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