1 /* -*- mode: c; c-file-style: "openbsd" -*- */
3 * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx>
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.
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.
30 #include <sys/utsname.h>
31 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <sys/select.h>
36 #include <sys/ioctl.h>
37 #include <arpa/inet.h>
38 #include <netinet/if_ether.h>
42 static void usage(void);
44 static struct protocol protos
[] =
46 { LLDPD_MODE_LLDP
, 1, "LLDP", 'l', lldp_send
, lldp_decode
, NULL
,
47 LLDP_ADDR_NEAREST_BRIDGE
,
48 LLDP_ADDR_NEAREST_NONTPMR_BRIDGE
,
49 LLDP_ADDR_NEAREST_CUSTOMER_BRIDGE
},
51 { LLDPD_MODE_CDPV1
, 0, "CDPv1", 'c', cdpv1_send
, cdp_decode
, cdpv1_guess
,
53 { LLDPD_MODE_CDPV2
, 0, "CDPv2", 'c', cdpv2_send
, cdp_decode
, cdpv2_guess
,
57 { LLDPD_MODE_SONMP
, 0, "SONMP", 's', sonmp_send
, sonmp_decode
, NULL
,
58 SONMP_MULTICAST_ADDR
},
61 { LLDPD_MODE_EDP
, 0, "EDP", 'e', edp_send
, edp_decode
, NULL
,
65 { LLDPD_MODE_FDP
, 0, "FDP", 'f', fdp_send
, cdp_decode
, NULL
,
68 { 0, 0, "any", ' ', NULL
, NULL
, NULL
,
72 static char **saved_argv
;
73 #ifdef HAVE___PROGNAME
74 extern const char *__progname
;
76 # define __progname "lldpd"
82 fprintf(stderr
, "Usage: %s [OPTIONS ...]\n", __progname
);
83 fprintf(stderr
, "Version: %s\n", PACKAGE_STRING
);
85 fprintf(stderr
, "\n");
87 fprintf(stderr
, "-d Do not daemonize.\n");
88 fprintf(stderr
, "-r Receive-only mode\n");
89 fprintf(stderr
, "-i Disable LLDP-MED inventory TLV transmission.\n");
90 fprintf(stderr
, "-k Disable advertising of kernel release, version, machine.\n");
91 fprintf(stderr
, "-S descr Override the default system description.\n");
92 fprintf(stderr
, "-P name Override the default hardware platform.\n");
93 fprintf(stderr
, "-m IP Specify the IPv4 management addresses of this system.\n");
94 fprintf(stderr
, "-u file Specify the Unix-domain socket used for communication with lldpctl(8).\n");
95 fprintf(stderr
, "-H mode Specify the behaviour when detecting multiple neighbors.\n");
96 fprintf(stderr
, "-I iface Limit interfaces to use.\n");
98 fprintf(stderr
, "-M class Enable emission of LLDP-MED frame. 'class' should be one of:\n");
99 fprintf(stderr
, " 1 Generic Endpoint (Class I)\n");
100 fprintf(stderr
, " 2 Media Endpoint (Class II)\n");
101 fprintf(stderr
, " 3 Communication Device Endpoints (Class III)\n");
102 fprintf(stderr
, " 4 Network Connectivity Device\n");
105 fprintf(stderr
, "-x Enable SNMP subagent.\n");
107 fprintf(stderr
, "\n");
109 #if defined ENABLE_CDP || defined ENABLE_EDP || defined ENABLE_FDP || defined ENABLE_SONMP
110 fprintf(stderr
, "Additional protocol support.\n");
112 fprintf(stderr
, "-c Enable the support of CDP protocol. (Cisco)\n");
115 fprintf(stderr
, "-e Enable the support of EDP protocol. (Extreme)\n");
118 fprintf(stderr
, "-f Enable the support of FDP protocol. (Foundry)\n");
121 fprintf(stderr
, "-s Enable the support of SONMP protocol. (Nortel)\n");
124 fprintf(stderr
, "\n");
127 fprintf(stderr
, "see manual page lldpd(8) for more information\n");
131 struct lldpd_hardware
*
132 lldpd_get_hardware(struct lldpd
*cfg
, char *name
, int index
)
134 struct lldpd_hardware
*hardware
;
135 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
) {
136 if ((strcmp(hardware
->h_ifname
, name
) == 0) &&
137 (hardware
->h_ifindex
== index
))
144 * Allocate the default local port. This port will be cloned each time we need a
148 lldpd_alloc_default_local_port(struct lldpd
*cfg
)
150 struct lldpd_port
*port
;
152 if ((port
= (struct lldpd_port
*)
153 calloc(1, sizeof(struct lldpd_port
))) == NULL
)
157 TAILQ_INIT(&port
->p_vlans
);
158 TAILQ_INIT(&port
->p_ppvids
);
159 TAILQ_INIT(&port
->p_pids
);
162 TAILQ_INIT(&port
->p_custom_list
);
164 cfg
->g_default_local_port
= port
;
168 * Clone a given port. The destination needs to be already allocated.
171 lldpd_clone_port(struct lldpd_port
*destination
, struct lldpd_port
*source
)
174 u_int8_t
*output
= NULL
;
176 struct lldpd_port
*cloned
= NULL
;
177 output_len
= lldpd_port_serialize(source
, (void**)&output
);
178 if (output_len
== -1 ||
179 lldpd_port_unserialize(output
, output_len
, &cloned
) <= 0) {
180 log_warnx("alloc", "unable to clone default port");
184 memcpy(destination
, cloned
, sizeof(struct lldpd_port
));
188 marshal_repair_tailq(lldpd_vlan
, &destination
->p_vlans
, v_entries
);
189 marshal_repair_tailq(lldpd_ppvid
, &destination
->p_ppvids
, p_entries
);
190 marshal_repair_tailq(lldpd_pi
, &destination
->p_pids
, p_entries
);
193 marshal_repair_tailq(lldpd_custom
, &destination
->p_custom_list
, next
);
198 struct lldpd_hardware
*
199 lldpd_alloc_hardware(struct lldpd
*cfg
, char *name
, int index
)
201 struct lldpd_hardware
*hardware
;
203 log_debug("alloc", "allocate a new local port (%s)", name
);
205 if ((hardware
= (struct lldpd_hardware
*)
206 calloc(1, sizeof(struct lldpd_hardware
))) == NULL
)
209 /* Clone default local port */
210 if (lldpd_clone_port(&hardware
->h_lport
, cfg
->g_default_local_port
) == -1) {
211 log_warnx("alloc", "unable to clone default port");
216 hardware
->h_cfg
= cfg
;
217 strlcpy(hardware
->h_ifname
, name
, sizeof(hardware
->h_ifname
));
218 hardware
->h_ifindex
= index
;
219 hardware
->h_lport
.p_chassis
= LOCAL_CHASSIS(cfg
);
220 hardware
->h_lport
.p_chassis
->c_refcount
++;
221 TAILQ_INIT(&hardware
->h_rports
);
223 #ifdef ENABLE_LLDPMED
224 if (LOCAL_CHASSIS(cfg
)->c_med_cap_available
) {
225 hardware
->h_lport
.p_med_cap_enabled
= LLDP_MED_CAP_CAP
;
226 if (!cfg
->g_config
.c_noinventory
)
227 hardware
->h_lport
.p_med_cap_enabled
|= LLDP_MED_CAP_IV
;
231 levent_hardware_init(hardware
);
236 lldpd_alloc_mgmt(int family
, void *addrptr
, size_t addrsize
, u_int32_t iface
)
238 struct lldpd_mgmt
*mgmt
;
240 log_debug("alloc", "allocate a new management address (family: %d)", family
);
242 if (family
<= LLDPD_AF_UNSPEC
|| family
>= LLDPD_AF_LAST
) {
243 errno
= EAFNOSUPPORT
;
246 if (addrsize
> LLDPD_MGMT_MAXADDRSIZE
) {
250 mgmt
= calloc(1, sizeof(struct lldpd_mgmt
));
255 mgmt
->m_family
= family
;
256 memcpy(&mgmt
->m_addr
, addrptr
, addrsize
);
257 mgmt
->m_addrsize
= addrsize
;
258 mgmt
->m_iface
= iface
;
263 lldpd_hardware_cleanup(struct lldpd
*cfg
, struct lldpd_hardware
*hardware
)
265 log_debug("alloc", "cleanup hardware port %s", hardware
->h_ifname
);
267 free(hardware
->h_lport_previous
);
268 free(hardware
->h_lchassis_previous_id
);
269 free(hardware
->h_lport_previous_id
);
270 lldpd_port_cleanup(&hardware
->h_lport
, 1);
271 if (hardware
->h_ops
&& hardware
->h_ops
->cleanup
)
272 hardware
->h_ops
->cleanup(cfg
, hardware
);
273 levent_hardware_release(hardware
);
278 lldpd_display_neighbors(struct lldpd
*cfg
)
280 if (!cfg
->g_config
.c_set_ifdescr
) return;
281 struct lldpd_hardware
*hardware
;
282 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
) {
283 struct lldpd_port
*port
;
285 const char *neighbor
= NULL
;
286 unsigned neighbors
= 0;
287 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
288 if (SMART_HIDDEN(port
)) continue;
290 neighbor
= port
->p_chassis
->c_name
;
293 priv_iface_description(hardware
->h_ifname
,
295 else if (neighbors
== 1 && neighbor
&& *neighbor
!= '\0') {
296 if (asprintf(&description
, "%s",
298 priv_iface_description(hardware
->h_ifname
, description
);
302 if (asprintf(&description
, "%d neighbor%s",
303 neighbors
, (neighbors
> 1)?"s":"") != -1) {
304 priv_iface_description(hardware
->h_ifname
,
313 lldpd_count_neighbors(struct lldpd
*cfg
)
315 #if HAVE_SETPROCTITLE
316 struct lldpd_chassis
*chassis
;
317 const char *neighbor
;
318 unsigned neighbors
= 0;
319 TAILQ_FOREACH(chassis
, &cfg
->g_chassis
, c_entries
) {
321 neighbor
= chassis
->c_name
;
325 setproctitle("no neighbor.");
326 else if (neighbors
== 1 && neighbor
&& *neighbor
!= '\0')
327 setproctitle("connected to %s.", neighbor
);
329 setproctitle("%d neighbor%s.", neighbors
,
330 (neighbors
> 1)?"s":"");
332 lldpd_display_neighbors(cfg
);
336 notify_clients_deletion(struct lldpd_hardware
*hardware
,
337 struct lldpd_port
*rport
)
339 TRACE(LLDPD_NEIGHBOR_DELETE(hardware
->h_ifname
,
340 rport
->p_chassis
->c_name
,
342 levent_ctl_notify(hardware
->h_ifname
, NEIGHBOR_CHANGE_DELETED
,
345 agent_notify(hardware
, NEIGHBOR_CHANGE_DELETED
, rport
);
350 lldpd_reset_timer(struct lldpd
*cfg
)
352 /* Reset timer for ports that have been changed. */
353 struct lldpd_hardware
*hardware
;
354 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
) {
355 /* We keep a flat copy of the local port to see if there is any
356 * change. To do this, we zero out fields that are not
357 * significant, marshal the port, then restore. */
358 struct lldpd_port
*port
= &hardware
->h_lport
;
359 /* Take the current flags into account to detect a change. */
360 port
->_p_hardware_flags
= hardware
->h_flags
;
361 u_int8_t
*output
= NULL
;
363 char save
[LLDPD_PORT_START_MARKER
];
364 memcpy(save
, port
, sizeof(save
));
365 /* coverity[suspicious_sizeof]
366 We intentionally partially memset port */
367 memset(port
, 0, sizeof(save
));
368 output_len
= lldpd_port_serialize(port
, (void**)&output
);
369 memcpy(port
, save
, sizeof(save
));
370 if (output_len
== -1) {
371 log_warnx("localchassis",
372 "unable to serialize local port %s to check for differences",
377 /* Compare with the previous value */
378 if (hardware
->h_lport_previous
&&
379 output_len
== hardware
->h_lport_previous_len
&&
380 !memcmp(output
, hardware
->h_lport_previous
, output_len
)) {
381 log_debug("localchassis",
382 "no change detected for port %s",
385 log_debug("localchassis",
386 "change detected for port %s, resetting its timer",
388 levent_schedule_pdu(hardware
);
391 /* Update the value */
392 free(hardware
->h_lport_previous
);
393 hardware
->h_lport_previous
= output
;
394 hardware
->h_lport_previous_len
= output_len
;
399 lldpd_all_chassis_cleanup(struct lldpd
*cfg
)
401 struct lldpd_chassis
*chassis
, *chassis_next
;
402 log_debug("localchassis", "cleanup all chassis");
404 for (chassis
= TAILQ_FIRST(&cfg
->g_chassis
); chassis
;
405 chassis
= chassis_next
) {
406 chassis_next
= TAILQ_NEXT(chassis
, c_entries
);
407 if (chassis
->c_refcount
== 0) {
408 TAILQ_REMOVE(&cfg
->g_chassis
, chassis
, c_entries
);
409 lldpd_chassis_cleanup(chassis
, 1);
415 lldpd_cleanup(struct lldpd
*cfg
)
417 struct lldpd_hardware
*hardware
, *hardware_next
;
419 log_debug("localchassis", "cleanup all ports");
421 for (hardware
= TAILQ_FIRST(&cfg
->g_hardware
); hardware
!= NULL
;
422 hardware
= hardware_next
) {
423 hardware_next
= TAILQ_NEXT(hardware
, h_entries
);
424 if (!hardware
->h_flags
) {
425 TRACE(LLDPD_INTERFACES_DELETE(hardware
->h_ifname
));
426 TAILQ_REMOVE(&cfg
->g_hardware
, hardware
, h_entries
);
427 lldpd_remote_cleanup(hardware
, notify_clients_deletion
, 1);
428 lldpd_hardware_cleanup(cfg
, hardware
);
430 lldpd_remote_cleanup(hardware
, notify_clients_deletion
,
431 !(hardware
->h_flags
& IFF_RUNNING
));
435 levent_schedule_cleanup(cfg
);
436 lldpd_all_chassis_cleanup(cfg
);
437 lldpd_count_neighbors(cfg
);
440 /* Update chassis `ochassis' with values from `chassis'. The later one is not
441 expected to be part of a list! It will also be wiped from memory. */
443 lldpd_move_chassis(struct lldpd_chassis
*ochassis
,
444 struct lldpd_chassis
*chassis
) {
445 struct lldpd_mgmt
*mgmt
, *mgmt_next
;
447 /* We want to keep refcount, index and list stuff from the current
449 TAILQ_ENTRY(lldpd_chassis
) entries
;
450 int refcount
= ochassis
->c_refcount
;
451 int index
= ochassis
->c_index
;
452 memcpy(&entries
, &ochassis
->c_entries
,
454 lldpd_chassis_cleanup(ochassis
, 0);
457 /* WARNING: this is a kludgy hack, we need in-place copy and cannot use
459 memcpy(ochassis
, chassis
, sizeof(struct lldpd_chassis
));
460 TAILQ_INIT(&ochassis
->c_mgmt
);
462 /* Copy of management addresses */
463 for (mgmt
= TAILQ_FIRST(&chassis
->c_mgmt
);
466 mgmt_next
= TAILQ_NEXT(mgmt
, m_entries
);
467 TAILQ_REMOVE(&chassis
->c_mgmt
, mgmt
, m_entries
);
468 TAILQ_INSERT_TAIL(&ochassis
->c_mgmt
, mgmt
, m_entries
);
471 /* Restore saved values */
472 ochassis
->c_refcount
= refcount
;
473 ochassis
->c_index
= index
;
474 memcpy(&ochassis
->c_entries
, &entries
, sizeof(entries
));
476 /* Get rid of the new chassis */
481 lldpd_guess_type(struct lldpd
*cfg
, char *frame
, int s
)
484 if (s
< ETHER_ADDR_LEN
)
486 for (i
=0; cfg
->g_protocols
[i
].mode
!= 0; i
++) {
487 if (!cfg
->g_protocols
[i
].enabled
)
489 if (cfg
->g_protocols
[i
].guess
== NULL
) {
490 if (memcmp(frame
, cfg
->g_protocols
[i
].mac1
, ETHER_ADDR_LEN
) == 0 ||
491 memcmp(frame
, cfg
->g_protocols
[i
].mac2
, ETHER_ADDR_LEN
) == 0 ||
492 memcmp(frame
, cfg
->g_protocols
[i
].mac3
, ETHER_ADDR_LEN
) == 0) {
493 log_debug("decode", "guessed protocol is %s (from MAC address)",
494 cfg
->g_protocols
[i
].name
);
495 return cfg
->g_protocols
[i
].mode
;
498 if (cfg
->g_protocols
[i
].guess(frame
, s
)) {
499 log_debug("decode", "guessed protocol is %s (from detector function)",
500 cfg
->g_protocols
[i
].name
);
501 return cfg
->g_protocols
[i
].mode
;
509 lldpd_decode(struct lldpd
*cfg
, char *frame
, int s
,
510 struct lldpd_hardware
*hardware
)
513 struct lldpd_chassis
*chassis
, *ochassis
= NULL
;
514 struct lldpd_port
*port
, *oport
= NULL
, *aport
;
515 int guess
= LLDPD_MODE_LLDP
;
517 log_debug("decode", "decode a received frame on %s",
520 if (s
< sizeof(struct ether_header
) + 4) {
521 /* Too short, just discard it */
522 hardware
->h_rx_discarded_cnt
++;
526 /* Decapsulate VLAN frames */
527 struct ether_header eheader
;
528 memcpy(&eheader
, frame
, sizeof(struct ether_header
));
529 if (eheader
.ether_type
== htons(ETHERTYPE_VLAN
)) {
530 /* VLAN decapsulation means to shift 4 bytes left the frame from
531 * offset 2*ETHER_ADDR_LEN */
532 memmove(frame
+ 2*ETHER_ADDR_LEN
, frame
+ 2*ETHER_ADDR_LEN
+ 4, s
- 2*ETHER_ADDR_LEN
);
536 TAILQ_FOREACH(oport
, &hardware
->h_rports
, p_entries
) {
537 if ((oport
->p_lastframe
!= NULL
) &&
538 (oport
->p_lastframe
->size
== s
) &&
539 (memcmp(oport
->p_lastframe
->frame
, frame
, s
) == 0)) {
540 /* Already received the same frame */
541 log_debug("decode", "duplicate frame, no need to decode");
542 oport
->p_lastupdate
= time(NULL
);
547 guess
= lldpd_guess_type(cfg
, frame
, s
);
548 for (i
=0; cfg
->g_protocols
[i
].mode
!= 0; i
++) {
549 if (!cfg
->g_protocols
[i
].enabled
)
551 if (cfg
->g_protocols
[i
].mode
== guess
) {
552 log_debug("decode", "using decode function for %s protocol",
553 cfg
->g_protocols
[i
].name
);
554 if (cfg
->g_protocols
[i
].decode(cfg
, frame
,
555 s
, hardware
, &chassis
, &port
) == -1) {
556 log_debug("decode", "function for %s protocol did not decode this frame",
557 cfg
->g_protocols
[i
].name
);
558 hardware
->h_rx_discarded_cnt
++;
561 chassis
->c_protocol
= port
->p_protocol
=
562 cfg
->g_protocols
[i
].mode
;
566 if (cfg
->g_protocols
[i
].mode
== 0) {
567 log_debug("decode", "unable to guess frame type on %s",
571 TRACE(LLDPD_FRAME_DECODED(
573 cfg
->g_protocols
[i
].name
,
577 /* Do we already have the same MSAP somewhere? */
579 log_debug("decode", "search for the same MSAP");
580 TAILQ_FOREACH(oport
, &hardware
->h_rports
, p_entries
) {
581 if (port
->p_protocol
== oport
->p_protocol
) {
583 if ((port
->p_id_subtype
== oport
->p_id_subtype
) &&
584 (port
->p_id_len
== oport
->p_id_len
) &&
585 (memcmp(port
->p_id
, oport
->p_id
, port
->p_id_len
) == 0) &&
586 (chassis
->c_id_subtype
== oport
->p_chassis
->c_id_subtype
) &&
587 (chassis
->c_id_len
== oport
->p_chassis
->c_id_len
) &&
588 (memcmp(chassis
->c_id
, oport
->p_chassis
->c_id
,
589 chassis
->c_id_len
) == 0)) {
590 ochassis
= oport
->p_chassis
;
591 log_debug("decode", "MSAP is already known");
596 /* Do we have room for a new MSAP? */
597 if (!oport
&& cfg
->g_config
.c_max_neighbors
) {
598 if (count
== (cfg
->g_config
.c_max_neighbors
- 1)) {
600 "max neighbors %d reached for port %s, "
601 "dropping any new ones silently",
602 cfg
->g_config
.c_max_neighbors
,
604 } else if (count
> cfg
->g_config
.c_max_neighbors
- 1) {
606 "too many neighbors for port %s, drop this new one",
608 lldpd_port_cleanup(port
, 1);
609 lldpd_chassis_cleanup(chassis
, 1);
614 /* No, but do we already know the system? */
616 log_debug("decode", "MSAP is unknown, search for the chassis");
617 TAILQ_FOREACH(ochassis
, &cfg
->g_chassis
, c_entries
) {
618 if ((chassis
->c_protocol
== ochassis
->c_protocol
) &&
619 (chassis
->c_id_subtype
== ochassis
->c_id_subtype
) &&
620 (chassis
->c_id_len
== ochassis
->c_id_len
) &&
621 (memcmp(chassis
->c_id
, ochassis
->c_id
,
622 chassis
->c_id_len
) == 0))
628 /* The port is known, remove it before adding it back */
629 TAILQ_REMOVE(&hardware
->h_rports
, oport
, p_entries
);
630 lldpd_port_cleanup(oport
, 1);
634 lldpd_move_chassis(ochassis
, chassis
);
637 /* Chassis not known, add it */
638 log_debug("decode", "unknown chassis, add it to the list");
639 chassis
->c_index
= ++cfg
->g_lastrid
;
640 chassis
->c_refcount
= 0;
641 TAILQ_INSERT_TAIL(&cfg
->g_chassis
, chassis
, c_entries
);
642 i
= 0; TAILQ_FOREACH(ochassis
, &cfg
->g_chassis
, c_entries
) i
++;
643 log_debug("decode", "%d different systems are known", i
);
646 port
->p_lastchange
= port
->p_lastupdate
= time(NULL
);
647 if ((port
->p_lastframe
= (struct lldpd_frame
*)malloc(s
+
648 sizeof(struct lldpd_frame
))) != NULL
) {
649 port
->p_lastframe
->size
= s
;
650 memcpy(port
->p_lastframe
->frame
, frame
, s
);
652 TAILQ_INSERT_TAIL(&hardware
->h_rports
, port
, p_entries
);
653 port
->p_chassis
= chassis
;
654 port
->p_chassis
->c_refcount
++;
655 /* Several cases are possible :
656 1. chassis is new, its refcount was 0. It is now attached
657 to this port, its refcount is 1.
658 2. chassis already exists and was attached to another
659 port, we increase its refcount accordingly.
660 3. chassis already exists and was attached to the same
661 port, its refcount was decreased with
662 lldpd_port_cleanup() and is now increased again.
664 In all cases, if the port already existed, it has been
665 freed with lldpd_port_cleanup() and therefore, the refcount
666 of the chassis that was attached to it is decreased.
668 /* coverity[use_after_free]
669 TAILQ_REMOVE does the right thing */
670 i
= 0; TAILQ_FOREACH(aport
, &hardware
->h_rports
, p_entries
)
672 log_debug("decode", "%d neighbors for %s", i
,
675 if (!oport
) hardware
->h_insert_cnt
++;
678 log_debug("decode", "send notifications for changes on %s",
681 TRACE(LLDPD_NEIGHBOR_UPDATE(hardware
->h_ifname
,
685 levent_ctl_notify(hardware
->h_ifname
, NEIGHBOR_CHANGE_UPDATED
, port
);
687 agent_notify(hardware
, NEIGHBOR_CHANGE_UPDATED
, port
);
690 TRACE(LLDPD_NEIGHBOR_NEW(hardware
->h_ifname
,
694 levent_ctl_notify(hardware
->h_ifname
, NEIGHBOR_CHANGE_ADDED
, port
);
696 agent_notify(hardware
, NEIGHBOR_CHANGE_ADDED
, port
);
700 #ifdef ENABLE_LLDPMED
701 if (!oport
&& port
->p_chassis
->c_med_type
) {
702 /* New neighbor, fast start */
703 if (hardware
->h_cfg
->g_config
.c_enable_fast_start
&&
704 !hardware
->h_tx_fast
) {
705 log_debug("decode", "%s: entering fast start due to "
706 "new neighbor", hardware
->h_ifname
);
707 hardware
->h_tx_fast
= hardware
->h_cfg
->g_config
.c_tx_fast_init
;
710 levent_schedule_pdu(hardware
);
717 /* Get the output of lsb_release -s -d. This is a slow function. It should be
718 called once. It return NULL if any problem happens. Otherwise, this is a
719 statically allocated buffer. The result includes the trailing \n */
721 lldpd_get_lsb_release() {
722 static char release
[1024];
723 char *const command
[] = { "lsb_release", "-s", "-d", NULL
};
724 int pid
, status
, devnull
, count
;
727 log_debug("localchassis", "grab LSB release");
730 log_warn("localchassis", "unable to get a pair of pipes");
737 log_warn("localchassis", "unable to fork");
740 /* Child, exec lsb_release */
742 if ((devnull
= open("/dev/null", O_RDWR
, 0)) != -1) {
743 dup2(devnull
, STDIN_FILENO
);
744 dup2(devnull
, STDERR_FILENO
);
745 dup2(pipefd
[1], STDOUT_FILENO
);
746 if (devnull
> 2) close(devnull
);
747 if (pipefd
[1] > 2) close(pipefd
[1]);
748 execvp("lsb_release", command
);
753 /* Father, read the output from the children */
757 status
= read(pipefd
[0], release
+count
, sizeof(release
)-count
);
758 if ((status
== -1) && (errno
== EINTR
)) continue;
761 } while (count
< sizeof(release
) && (status
> 0));
763 log_info("localchassis", "unable to read from lsb_release");
765 waitpid(pid
, &status
, 0);
769 if (count
>= sizeof(release
)) {
770 log_info("localchassis", "output of lsb_release is too large");
771 waitpid(pid
, &status
, 0);
775 if (waitpid(pid
, &status
, 0) != pid
)
777 if (!WIFEXITED(status
) || (WEXITSTATUS(status
) != 0)) {
778 log_info("localchassis", "lsb_release information not available");
782 log_info("localchassis", "lsb_release returned an empty string");
785 release
[count
] = '\0';
788 /* Should not be here */
792 /* Same like lldpd_get_lsb_release but reads /etc/os-release for PRETTY_NAME=. */
794 lldpd_get_os_release() {
795 static char release
[1024];
798 char *ptr1
= release
;
800 log_debug("localchassis", "grab OS release");
801 FILE *fp
= fopen("/etc/os-release", "r");
803 log_debug("localchassis", "could not open /etc/os-release");
804 fp
= fopen("/usr/lib/os-release", "r");
807 log_info("localchassis",
808 "could not open either /etc/os-release or /usr/lib/os-release");
812 while ((fgets(line
, sizeof(line
), fp
) != NULL
)) {
813 key
= strtok(line
, "=");
814 val
= strtok(NULL
, "=");
816 if (strncmp(key
, "PRETTY_NAME", sizeof(line
)) == 0) {
817 strlcpy(release
, val
, sizeof(line
));
823 /* Remove trailing newline and all " in the string. */
824 ptr1
= release
+ strlen(release
) - 1;
825 while (ptr1
!= release
&&
826 ((*ptr1
== '"') || (*ptr1
== '\n'))) {
830 if (release
[0] == '"')
836 lldpd_hide_ports(struct lldpd
*cfg
, struct lldpd_hardware
*hardware
, int mask
) {
837 struct lldpd_port
*port
;
838 int protocols
[LLDPD_MODE_MAX
+1];
843 log_debug("smartfilter", "apply smart filter for port %s",
846 /* Compute the number of occurrences of each protocol */
847 for (i
= 0; i
<= LLDPD_MODE_MAX
; i
++) protocols
[i
] = 0;
848 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
)
849 protocols
[port
->p_protocol
]++;
851 /* Turn the protocols[] array into an array of
852 enabled/disabled protocols. 1 means enabled, 0
854 min
= (unsigned int)-1;
855 for (i
= 0; i
<= LLDPD_MODE_MAX
; i
++)
856 if (protocols
[i
] && (protocols
[i
] < min
))
859 for (i
= 0; i
<= LLDPD_MODE_MAX
; i
++)
860 if ((protocols
[i
] == min
) && !found
) {
861 /* If we need a tie breaker, we take
862 the first protocol only */
863 if (cfg
->g_config
.c_smart
& mask
&
864 (SMART_OUTGOING_ONE_PROTO
| SMART_INCOMING_ONE_PROTO
))
867 } else protocols
[i
] = 0;
869 /* We set the p_hidden flag to 1 if the protocol is disabled */
870 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
871 if (mask
== SMART_OUTGOING
)
872 port
->p_hidden_out
= protocols
[port
->p_protocol
]?0:1;
874 port
->p_hidden_in
= protocols
[port
->p_protocol
]?0:1;
877 /* If we want only one neighbor, we take the first one */
878 if (cfg
->g_config
.c_smart
& mask
&
879 (SMART_OUTGOING_ONE_NEIGH
| SMART_INCOMING_ONE_NEIGH
)) {
881 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
882 if (mask
== SMART_OUTGOING
) {
883 if (found
) port
->p_hidden_out
= 1;
884 if (!port
->p_hidden_out
)
887 if (mask
== SMART_INCOMING
) {
888 if (found
) port
->p_hidden_in
= 1;
889 if (!port
->p_hidden_in
)
895 /* Print a debug message summarizing the operation */
896 for (i
= 0; i
<= LLDPD_MODE_MAX
; i
++) protocols
[i
] = 0;
898 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
899 if (!(((mask
== SMART_OUTGOING
) && port
->p_hidden_out
) ||
900 ((mask
== SMART_INCOMING
) && port
->p_hidden_in
))) {
902 protocols
[port
->p_protocol
] = 1;
907 for (i
=0; cfg
->g_protocols
[i
].mode
!= 0; i
++) {
908 if (cfg
->g_protocols
[i
].enabled
&& protocols
[cfg
->g_protocols
[i
].mode
]) {
910 strlen(cfg
->g_protocols
[i
].name
) + 3 > sizeof(buffer
)) {
911 /* Unlikely, our buffer is too small */
912 memcpy(buffer
+ sizeof(buffer
) - 4, "...", 4);
916 strncat(buffer
, ", ", 2);
917 strncat(buffer
, cfg
->g_protocols
[i
].name
, strlen(cfg
->g_protocols
[i
].name
));
920 log_debug("smartfilter", "%s: %s: %d visible neighbors (out of %d)",
922 (mask
== SMART_OUTGOING
)?"out filter":"in filter",
924 log_debug("smartfilter", "%s: protocols: %s",
925 hardware
->h_ifname
, buffer
[0]?buffer
:"(none)");
928 /* Hide unwanted ports depending on smart mode set by the user */
930 lldpd_hide_all(struct lldpd
*cfg
)
932 struct lldpd_hardware
*hardware
;
934 if (!cfg
->g_config
.c_smart
)
936 log_debug("smartfilter", "apply smart filter results on all ports");
937 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
) {
938 if (cfg
->g_config
.c_smart
& SMART_INCOMING_FILTER
)
939 lldpd_hide_ports(cfg
, hardware
, SMART_INCOMING
);
940 if (cfg
->g_config
.c_smart
& SMART_OUTGOING_FILTER
)
941 lldpd_hide_ports(cfg
, hardware
, SMART_OUTGOING
);
946 lldpd_recv(struct lldpd
*cfg
, struct lldpd_hardware
*hardware
, int fd
)
950 log_debug("receive", "receive a frame on %s",
952 if ((buffer
= (char *)malloc(hardware
->h_mtu
)) == NULL
) {
953 log_warn("receive", "failed to alloc reception buffer");
956 if ((n
= hardware
->h_ops
->recv(cfg
, hardware
,
958 hardware
->h_mtu
)) == -1) {
959 log_debug("receive", "discard frame received on %s",
964 if (hardware
->h_lport
.p_disable_rx
) {
965 log_debug("receive", "RX disabled, ignore the frame on %s",
970 if (cfg
->g_config
.c_paused
) {
971 log_debug("receive", "paused, ignore the frame on %s",
976 hardware
->h_rx_cnt
++;
977 log_debug("receive", "decode received frame on %s",
979 TRACE(LLDPD_FRAME_RECEIVED(hardware
->h_ifname
, buffer
, (size_t)n
));
980 lldpd_decode(cfg
, buffer
, n
, hardware
);
981 lldpd_hide_all(cfg
); /* Immediatly hide */
982 lldpd_count_neighbors(cfg
);
987 lldpd_send_shutdown(struct lldpd_hardware
*hardware
)
989 struct lldpd
*cfg
= hardware
->h_cfg
;
990 if (cfg
->g_config
.c_receiveonly
|| cfg
->g_config
.c_paused
) return;
991 if (hardware
->h_lport
.p_disable_tx
) return;
992 if ((hardware
->h_flags
& IFF_RUNNING
) == 0)
995 /* It's safe to call `lldp_send_shutdown()` because shutdown LLDPU will
996 * only be emitted if LLDP was sent on that port. */
997 if (lldp_send_shutdown(hardware
->h_cfg
, hardware
) != 0)
998 log_warnx("send", "unable to send shutdown LLDPDU on %s",
1003 lldpd_send(struct lldpd_hardware
*hardware
)
1005 struct lldpd
*cfg
= hardware
->h_cfg
;
1006 struct lldpd_port
*port
;
1009 if (cfg
->g_config
.c_receiveonly
|| cfg
->g_config
.c_paused
) return;
1010 if (hardware
->h_lport
.p_disable_tx
) return;
1011 if ((hardware
->h_flags
& IFF_RUNNING
) == 0)
1014 log_debug("send", "send PDU on %s", hardware
->h_ifname
);
1016 for (i
=0; cfg
->g_protocols
[i
].mode
!= 0; i
++) {
1017 if (!cfg
->g_protocols
[i
].enabled
)
1019 /* We send only if we have at least one remote system
1020 * speaking this protocol or if the protocol is forced */
1021 if (cfg
->g_protocols
[i
].enabled
> 1) {
1022 cfg
->g_protocols
[i
].send(cfg
, hardware
);
1026 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
1027 /* If this remote port is disabled, we don't
1029 if (port
->p_hidden_out
)
1031 if (port
->p_protocol
==
1032 cfg
->g_protocols
[i
].mode
) {
1033 TRACE(LLDPD_FRAME_SEND(hardware
->h_ifname
,
1034 cfg
->g_protocols
[i
].name
));
1035 log_debug("send", "send PDU on %s with protocol %s",
1037 cfg
->g_protocols
[i
].name
);
1038 cfg
->g_protocols
[i
].send(cfg
,
1047 /* Nothing was sent for this port, let's speak the first
1048 * available protocol. */
1049 for (i
= 0; cfg
->g_protocols
[i
].mode
!= 0; i
++) {
1050 if (!cfg
->g_protocols
[i
].enabled
) continue;
1051 TRACE(LLDPD_FRAME_SEND(hardware
->h_ifname
,
1052 cfg
->g_protocols
[i
].name
));
1053 log_debug("send", "fallback to protocol %s for %s",
1054 cfg
->g_protocols
[i
].name
, hardware
->h_ifname
);
1055 cfg
->g_protocols
[i
].send(cfg
,
1059 if (cfg
->g_protocols
[i
].mode
== 0)
1060 log_warnx("send", "no protocol enabled, dunno what to send");
1064 #ifdef ENABLE_LLDPMED
1066 lldpd_med(struct lldpd_chassis
*chassis
)
1068 static short int once
= 0;
1070 chassis
->c_med_hw
= dmi_hw();
1071 chassis
->c_med_fw
= dmi_fw();
1072 chassis
->c_med_sn
= dmi_sn();
1073 chassis
->c_med_manuf
= dmi_manuf();
1074 chassis
->c_med_model
= dmi_model();
1075 chassis
->c_med_asset
= dmi_asset();
1082 lldpd_routing_enabled(struct lldpd
*cfg
)
1086 if ((LOCAL_CHASSIS(cfg
)->c_cap_available
& LLDP_CAP_ROUTER
) == 0)
1089 if ((routing
= interfaces_routing_enabled(cfg
)) == -1) {
1090 log_debug("localchassis", "unable to check if routing is enabled");
1097 lldpd_update_localchassis(struct lldpd
*cfg
)
1102 log_debug("localchassis", "update information for local chassis");
1103 assert(LOCAL_CHASSIS(cfg
) != NULL
);
1105 /* Set system name and description */
1107 fatal("localchassis", "failed to get system information");
1108 if (cfg
->g_config
.c_hostname
) {
1109 log_debug("localchassis", "use overridden system name `%s`", cfg
->g_config
.c_hostname
);
1110 hp
= cfg
->g_config
.c_hostname
;
1112 if ((hp
= priv_gethostname()) == NULL
)
1113 fatal("localchassis", "failed to get system name");
1115 free(LOCAL_CHASSIS(cfg
)->c_name
);
1116 free(LOCAL_CHASSIS(cfg
)->c_descr
);
1117 if ((LOCAL_CHASSIS(cfg
)->c_name
= strdup(hp
)) == NULL
)
1118 fatal("localchassis", NULL
);
1119 if (cfg
->g_config
.c_description
) {
1120 log_debug("localchassis", "use overridden description `%s`", cfg
->g_config
.c_description
);
1121 if (asprintf(&LOCAL_CHASSIS(cfg
)->c_descr
, "%s",
1122 cfg
->g_config
.c_description
) == -1)
1123 fatal("localchassis", "failed to set full system description");
1125 if (cfg
->g_config
.c_advertise_version
) {
1126 log_debug("localchassis", "advertise system version");
1127 if (asprintf(&LOCAL_CHASSIS(cfg
)->c_descr
, "%s %s %s %s %s",
1128 cfg
->g_lsb_release
?cfg
->g_lsb_release
:"",
1129 un
.sysname
, un
.release
, un
.version
, un
.machine
)
1131 fatal("localchassis", "failed to set full system description");
1133 log_debug("localchassis", "do not advertise system version");
1134 if (asprintf(&LOCAL_CHASSIS(cfg
)->c_descr
, "%s",
1135 cfg
->g_lsb_release
?cfg
->g_lsb_release
:un
.sysname
) == -1)
1136 fatal("localchassis", "failed to set minimal system description");
1139 if (cfg
->g_config
.c_platform
== NULL
)
1140 cfg
->g_config
.c_platform
= strdup(un
.sysname
);
1143 if (lldpd_routing_enabled(cfg
)) {
1144 log_debug("localchassis", "routing is enabled, enable router capability");
1145 LOCAL_CHASSIS(cfg
)->c_cap_enabled
|= LLDP_CAP_ROUTER
;
1147 LOCAL_CHASSIS(cfg
)->c_cap_enabled
&= ~LLDP_CAP_ROUTER
;
1149 #ifdef ENABLE_LLDPMED
1150 if (LOCAL_CHASSIS(cfg
)->c_cap_available
& LLDP_CAP_TELEPHONE
)
1151 LOCAL_CHASSIS(cfg
)->c_cap_enabled
|= LLDP_CAP_TELEPHONE
;
1152 lldpd_med(LOCAL_CHASSIS(cfg
));
1153 free(LOCAL_CHASSIS(cfg
)->c_med_sw
);
1154 if (cfg
->g_config
.c_advertise_version
)
1155 LOCAL_CHASSIS(cfg
)->c_med_sw
= strdup(un
.release
);
1157 LOCAL_CHASSIS(cfg
)->c_med_sw
= strdup("Unknown");
1159 if ((LOCAL_CHASSIS(cfg
)->c_cap_available
& LLDP_CAP_STATION
) &&
1160 (LOCAL_CHASSIS(cfg
)->c_cap_enabled
== 0))
1161 LOCAL_CHASSIS(cfg
)->c_cap_enabled
= LLDP_CAP_STATION
;
1163 /* Set chassis ID if needed. This is only done if chassis ID
1164 has not been set previously (with the MAC address of an
1165 interface for example)
1167 if (LOCAL_CHASSIS(cfg
)->c_id
== NULL
) {
1168 log_debug("localchassis", "no chassis ID is currently set, use chassis name");
1169 if (!(LOCAL_CHASSIS(cfg
)->c_id
= strdup(LOCAL_CHASSIS(cfg
)->c_name
)))
1170 fatal("localchassis", NULL
);
1171 LOCAL_CHASSIS(cfg
)->c_id_len
= strlen(LOCAL_CHASSIS(cfg
)->c_name
);
1172 LOCAL_CHASSIS(cfg
)->c_id_subtype
= LLDP_CHASSISID_SUBTYPE_LOCAL
;
1177 lldpd_update_localports(struct lldpd
*cfg
)
1179 struct lldpd_hardware
*hardware
;
1181 log_debug("localchassis", "update information for local ports");
1183 /* h_flags is set to 0 for each port. If the port is updated, h_flags
1184 * will be set to a non-zero value. This will allow us to clean up any
1185 * non up-to-date port */
1186 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
)
1187 hardware
->h_flags
= 0;
1189 TRACE(LLDPD_INTERFACES_UPDATE());
1190 interfaces_update(cfg
);
1192 lldpd_reset_timer(cfg
);
1196 lldpd_loop(struct lldpd
*cfg
)
1199 1. Update local ports information
1200 2. Update local chassis information
1202 log_debug("loop", "start new loop");
1203 LOCAL_CHASSIS(cfg
)->c_cap_enabled
= 0;
1204 /* Information for local ports is triggered even when it is possible to
1205 * update them on some other event because we want to refresh them if we
1206 * missed something. */
1207 log_debug("loop", "update information for local ports");
1208 lldpd_update_localports(cfg
);
1209 log_debug("loop", "update information for local chassis");
1210 lldpd_update_localchassis(cfg
);
1211 lldpd_count_neighbors(cfg
);
1215 lldpd_exit(struct lldpd
*cfg
)
1217 struct lldpd_hardware
*hardware
, *hardware_next
;
1218 log_debug("main", "exit lldpd");
1220 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
)
1221 lldpd_send_shutdown(hardware
);
1224 priv_ctl_cleanup(cfg
->g_ctlname
);
1225 log_debug("main", "cleanup hardware information");
1226 for (hardware
= TAILQ_FIRST(&cfg
->g_hardware
); hardware
!= NULL
;
1227 hardware
= hardware_next
) {
1228 hardware_next
= TAILQ_NEXT(hardware
, h_entries
);
1229 log_debug("main", "cleanup interface %s", hardware
->h_ifname
);
1230 lldpd_remote_cleanup(hardware
, NULL
, 1);
1231 lldpd_hardware_cleanup(cfg
, hardware
);
1233 interfaces_cleanup(cfg
);
1234 lldpd_port_cleanup(cfg
->g_default_local_port
, 1);
1235 lldpd_all_chassis_cleanup(cfg
);
1236 free(cfg
->g_default_local_port
);
1237 free(cfg
->g_config
.c_platform
);
1238 levent_shutdown(cfg
);
1242 * Run lldpcli to configure lldpd.
1244 * @return PID of running lldpcli or -1 if error.
1247 lldpd_configure(int use_syslog
, int debug
, const char *path
, const char *ctlname
)
1249 pid_t lldpcli
= vfork();
1252 char sdebug
[debug
+ 4];
1254 strlcpy(sdebug
, "-s", 3);
1256 /* debug = 0 -> -sd */
1257 /* debug = 1 -> -sdd */
1258 /* debug = 2 -> -sddd */
1259 memset(sdebug
, 'd', sizeof(sdebug
));
1260 sdebug
[debug
+ 3] = '\0';
1261 sdebug
[0] = '-'; sdebug
[1] = 's';
1263 log_debug("main", "invoke %s %s", path
, sdebug
);
1267 log_warn("main", "unable to fork");
1270 /* Child, exec lldpcli */
1271 if ((devnull
= open("/dev/null", O_RDWR
, 0)) != -1) {
1272 dup2(devnull
, STDIN_FILENO
);
1273 dup2(devnull
, STDOUT_FILENO
);
1274 if (devnull
> 2) close(devnull
);
1276 execl(path
, "lldpcli", sdebug
,
1278 "-C", SYSCONFDIR
"/lldpd.conf",
1279 "-C", SYSCONFDIR
"/lldpd.d",
1282 log_warn("main", "unable to execute %s", path
);
1283 log_warnx("main", "configuration is incomplete, lldpd needs to be unpaused");
1288 /* Father, don't do anything stupid */
1291 /* Should not be here */
1295 struct intint
{ int a
; int b
; };
1296 static const struct intint filters
[] = {
1298 { 1, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
|
1299 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_PROTO
},
1300 { 2, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
},
1301 { 3, SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_PROTO
},
1302 { 4, SMART_INCOMING_FILTER
| SMART_OUTGOING_FILTER
},
1303 { 5, SMART_INCOMING_FILTER
},
1304 { 6, SMART_OUTGOING_FILTER
},
1305 { 7, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
| SMART_INCOMING_ONE_NEIGH
|
1306 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_PROTO
},
1307 { 8, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
| SMART_INCOMING_ONE_NEIGH
},
1308 { 9, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_NEIGH
|
1309 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_PROTO
},
1310 { 10, SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_NEIGH
},
1311 { 11, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_NEIGH
},
1312 { 12, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_NEIGH
|
1313 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_NEIGH
},
1314 { 13, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_NEIGH
|
1315 SMART_OUTGOING_FILTER
},
1316 { 14, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
|
1317 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_NEIGH
},
1318 { 15, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
|
1319 SMART_OUTGOING_FILTER
},
1320 { 16, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
| SMART_INCOMING_ONE_NEIGH
|
1321 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_NEIGH
},
1322 { 17, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
| SMART_INCOMING_ONE_NEIGH
|
1323 SMART_OUTGOING_FILTER
},
1324 { 18, SMART_INCOMING_FILTER
|
1325 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_NEIGH
},
1326 { 19, SMART_INCOMING_FILTER
|
1327 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_PROTO
},
1333 * Tell if we have been started by upstart.
1336 lldpd_started_by_upstart()
1338 #ifdef HOST_OS_LINUX
1339 const char *upstartjob
= getenv("UPSTART_JOB");
1340 if (!(upstartjob
&& !strcmp(upstartjob
, "lldpd")))
1342 log_debug("main", "running with upstart, don't fork but stop");
1344 unsetenv("UPSTART_JOB");
1352 * Tell if we have been started by systemd.
1355 lldpd_started_by_systemd()
1357 #ifdef HOST_OS_LINUX
1359 const char *notifysocket
= getenv("NOTIFY_SOCKET");
1360 if (!notifysocket
||
1361 !strchr("@/", notifysocket
[0]) ||
1362 strlen(notifysocket
) < 2)
1365 log_debug("main", "running with systemd, don't fork but signal ready");
1366 if ((fd
= socket(AF_UNIX
, SOCK_DGRAM
, 0)) < 0) {
1367 log_warn("main", "unable to open systemd notification socket %s",
1372 struct sockaddr_un su
= { .sun_family
= AF_UNIX
};
1373 strlcpy(su
.sun_path
, notifysocket
, sizeof(su
.sun_path
));
1374 if (notifysocket
[0] == '@') su
.sun_path
[0] = 0;
1376 struct iovec iov
= {
1377 .iov_base
= "READY=1",
1378 .iov_len
= strlen("READY=1")
1380 struct msghdr hdr
= {
1382 .msg_namelen
= offsetof(struct sockaddr_un
, sun_path
) + strlen(notifysocket
),
1386 unsetenv("NOTIFY_SOCKET");
1387 if (sendmsg(fd
, &hdr
, MSG_NOSIGNAL
) < 0) {
1388 log_warn("main", "unable to send notification to systemd");
1400 #ifdef HOST_OS_LINUX
1402 version_convert(const char *sversion
, unsigned iversion
[], size_t n
)
1404 const char *p
= sversion
;
1406 for (size_t i
= 0; i
< n
; i
++) {
1407 iversion
[i
] = strtol(p
, &end
, 10);
1408 if (*end
!= '.') break;
1417 if (uname(&uts
) == -1) return;
1418 unsigned version_min
[3] = {};
1419 unsigned version_cur
[3] = {};
1420 version_convert(uts
.release
, version_cur
, 3);
1421 version_convert(MIN_LINUX_KERNEL_VERSION
, version_min
, 3);
1422 if (version_min
[0] > version_cur
[0] ||
1423 (version_min
[0] == version_cur
[0] && version_min
[1] > version_cur
[1]) ||
1424 (version_min
[0] == version_cur
[0] && version_min
[1] == version_cur
[1] &&
1425 version_min
[2] > version_cur
[2])) {
1426 log_warnx("lldpd", "minimal kernel version required is %s, got %s",
1427 MIN_LINUX_KERNEL_VERSION
, uts
.release
);
1428 log_warnx("lldpd", "lldpd may be unable to detect bonds and bridges correctly");
1429 #ifndef ENABLE_OLDIES
1430 log_warnx("lldpd", "consider recompiling with --enable-oldies option");
1435 static void version_check(void) {}
1439 lldpd_main(int argc
, char *argv
[], char *envp
[])
1442 struct lldpd_chassis
*lchassis
;
1443 int ch
, debug
= 0, use_syslog
= 1, daemonize
= 1;
1447 const char *agentx
= NULL
; /* AgentX socket */
1449 const char *ctlname
= NULL
;
1452 char *interfaces
= NULL
;
1453 /* We do not want more options here. Please add them in lldpcli instead
1454 * unless there is a very good reason. Most command-line options will
1455 * get deprecated at some point. */
1456 char *popt
, opts
[] =
1457 "H:vhkrdD:p:xX:m:u:4:6:I:C:p:M:P:S:iL:@ ";
1458 int i
, found
, advertise_version
= 1;
1459 #ifdef ENABLE_LLDPMED
1460 int lldpmed
= 0, noinventory
= 0;
1461 int enable_fast_start
= 1;
1463 char *descr_override
= NULL
;
1464 char *platform_override
= NULL
;
1465 char *lsb_release
= NULL
;
1466 const char *lldpcli
= LLDPCLI_PATH
;
1467 const char *pidfile
= LLDPD_PID_FILE
;
1469 int receiveonly
= 0, version
= 0;
1472 #ifdef ENABLE_PRIVSEP
1473 /* Non privileged user */
1474 struct passwd
*user
;
1475 struct group
*group
;
1482 #if HAVE_SETPROCTITLE_INIT
1483 setproctitle_init(argc
, argv
, envp
);
1487 * Get and parse command line options
1489 if ((popt
= strchr(opts
, '@')) != NULL
) {
1491 protos
[i
].mode
!= 0 && *popt
!= '\0';
1493 *(popt
++) = protos
[i
].arg
;
1496 while ((ch
= getopt(argc
, argv
, opts
)) != -1) {
1507 else if (use_syslog
)
1523 fprintf(stderr
, "-m can only be used once\n");
1526 mgmtp
= strdup(optarg
);
1530 fprintf(stderr
, "-u can only be used once\n");
1537 fprintf(stderr
, "-I can only be used once\n");
1540 interfaces
= strdup(optarg
);
1544 fprintf(stderr
, "-C can only be used once\n");
1547 cidp
= strdup(optarg
);
1550 if (strlen(optarg
)) lldpcli
= optarg
;
1551 else lldpcli
= NULL
;
1554 advertise_version
= 0;
1556 #ifdef ENABLE_LLDPMED
1558 lldpmed
= strtonum(optarg
, 1, 4, &errstr
);
1560 fprintf(stderr
, "-M requires an argument between 1 and 4\n");
1570 fprintf(stderr
, "LLDP-MED support is not built-in\n");
1580 fprintf(stderr
, "-X can only be used once\n");
1589 fprintf(stderr
, "SNMP support is not built-in\n");
1594 if (descr_override
) {
1595 fprintf(stderr
, "-S can only be used once\n");
1598 descr_override
= strdup(optarg
);
1601 if (platform_override
) {
1602 fprintf(stderr
, "-P can only be used once\n");
1605 platform_override
= strdup(optarg
);
1608 smart
= strtonum(optarg
, 0, sizeof(filters
)/sizeof(filters
[0]),
1611 fprintf(stderr
, "-H requires an int between 0 and %zu\n",
1612 sizeof(filters
)/sizeof(filters
[0]));
1618 for (i
=0; protos
[i
].mode
!= 0; i
++) {
1619 if (ch
== protos
[i
].arg
) {
1621 protos
[i
].enabled
++;
1630 version_display(stdout
, "lldpd", version
> 1);
1634 if (ctlname
== NULL
) ctlname
= LLDPD_CTL_SOCKET
;
1636 /* Set correct smart mode */
1637 for (i
=0; (filters
[i
].a
!= -1) && (filters
[i
].a
!= smart
); i
++);
1638 if (filters
[i
].a
== -1) {
1639 fprintf(stderr
, "Incorrect mode for -H\n");
1642 smart
= filters
[i
].b
;
1644 log_init(use_syslog
, debug
, __progname
);
1645 tzset(); /* Get timezone info before chroot */
1646 if (use_syslog
&& daemonize
) {
1647 /* So, we use syslog and we daemonize (or we are started by
1648 * upstart/systemd). No need to continue writing to stdout. */
1650 if ((fd
= open("/dev/null", O_RDWR
, 0)) != -1) {
1651 dup2(fd
, STDIN_FILENO
);
1652 dup2(fd
, STDOUT_FILENO
);
1653 dup2(fd
, STDERR_FILENO
);
1654 if (fd
> 2) close(fd
);
1657 log_debug("main", "lldpd " PACKAGE_VERSION
" starting...");
1660 /* Grab uid and gid to use for priv sep */
1661 #ifdef ENABLE_PRIVSEP
1662 if ((user
= getpwnam(PRIVSEP_USER
)) == NULL
)
1663 fatalx("main", "no " PRIVSEP_USER
" user for privilege separation, please create it");
1665 if ((group
= getgrnam(PRIVSEP_GROUP
)) == NULL
)
1666 fatalx("main", "no " PRIVSEP_GROUP
" group for privilege separation, please create it");
1667 gid
= group
->gr_gid
;
1670 /* Create and setup socket */
1672 log_debug("main", "creating control socket");
1673 while ((ctl
= ctl_create(ctlname
)) == -1) {
1674 if (retry
-- && errno
== EADDRINUSE
) {
1675 /* Check if a daemon is really listening */
1677 log_info("main", "unable to create control socket because it already exists");
1678 log_info("main", "check if another instance is running");
1679 if ((tfd
= ctl_connect(ctlname
)) != -1) {
1680 /* Another instance is running */
1682 log_warnx("main", "another instance is running, please stop it");
1683 fatalx("main", "giving up");
1684 } else if (errno
== ECONNREFUSED
) {
1685 /* Nobody is listening */
1686 log_info("main", "old control socket is present, clean it");
1687 ctl_cleanup(ctlname
);
1690 log_warn("main", "cannot determine if another daemon is already running");
1691 fatalx("main", "giving up");
1693 log_warn("main", "unable to create control socket at %s", ctlname
);
1694 fatalx("main", "giving up");
1696 #ifdef ENABLE_PRIVSEP
1697 if (chown(ctlname
, uid
, gid
) == -1)
1698 log_warn("main", "unable to chown control socket");
1700 S_IRUSR
| S_IWUSR
| S_IXUSR
|
1701 S_IRGRP
| S_IWGRP
| S_IXGRP
) == -1)
1702 log_warn("main", "unable to chmod control socket");
1705 /* Disable SIGPIPE */
1706 signal(SIGPIPE
, SIG_IGN
);
1708 /* Disable SIGHUP, until handlers are installed */
1709 signal(SIGHUP
, SIG_IGN
);
1711 /* Daemonization, unless started by upstart, systemd or launchd or debug */
1714 !lldpd_started_by_upstart() && !lldpd_started_by_systemd()) {
1717 log_info("main", "going into background");
1718 if (daemon(0, 1) != 0)
1719 fatal("main", "failed to detach daemon");
1720 if ((pid
= open(pidfile
,
1721 O_TRUNC
| O_CREAT
| O_WRONLY
, 0666)) == -1)
1722 fatal("main", "unable to open pid file " LLDPD_PID_FILE
1723 " (or the specified one)");
1724 if (asprintf(&spid
, "%d\n", getpid()) == -1)
1725 fatal("main", "unable to create pid file " LLDPD_PID_FILE
1726 " (or the specified one)");
1727 if (write(pid
, spid
, strlen(spid
)) == -1)
1728 fatal("main", "unable to write pid file " LLDPD_PID_FILE
1729 " (or the specified one)");
1735 /* Configuration with lldpcli */
1737 log_debug("main", "invoking lldpcli for configuration");
1738 if (lldpd_configure(use_syslog
, debug
, lldpcli
, ctlname
) == -1)
1739 fatal("main", "unable to spawn lldpcli");
1742 /* Try to read system information from /etc/os-release if possible.
1743 Fall back to lsb_release for compatibility. */
1744 log_debug("main", "get OS/LSB release information");
1745 lsb_release
= lldpd_get_os_release();
1747 lsb_release
= lldpd_get_lsb_release();
1750 log_debug("main", "initialize privilege separation");
1751 #ifdef ENABLE_PRIVSEP
1752 priv_init(PRIVSEP_CHROOT
, ctl
, uid
, gid
);
1754 priv_init(PRIVSEP_CHROOT
, ctl
, 0, 0);
1757 /* Initialization of global configuration */
1758 if ((cfg
= (struct lldpd
*)
1759 calloc(1, sizeof(struct lldpd
))) == NULL
)
1760 fatal("main", NULL
);
1762 lldpd_alloc_default_local_port(cfg
);
1763 cfg
->g_ctlname
= ctlname
;
1765 cfg
->g_config
.c_mgmt_pattern
= mgmtp
;
1766 cfg
->g_config
.c_cid_pattern
= cidp
;
1767 cfg
->g_config
.c_iface_pattern
= interfaces
;
1768 cfg
->g_config
.c_smart
= smart
;
1770 cfg
->g_config
.c_paused
= 1;
1771 cfg
->g_config
.c_receiveonly
= receiveonly
;
1772 cfg
->g_config
.c_tx_interval
= LLDPD_TX_INTERVAL
;
1773 cfg
->g_config
.c_tx_hold
= LLDPD_TX_HOLD
;
1774 cfg
->g_config
.c_max_neighbors
= LLDPD_MAX_NEIGHBORS
;
1775 #ifdef ENABLE_LLDPMED
1776 cfg
->g_config
.c_enable_fast_start
= enable_fast_start
;
1777 cfg
->g_config
.c_tx_fast_init
= LLDPD_FAST_INIT
;
1778 cfg
->g_config
.c_tx_fast_interval
= LLDPD_FAST_TX_INTERVAL
;
1782 cfg
->g_snmp_agentx
= agentx
;
1783 #endif /* USE_SNMP */
1784 cfg
->g_config
.c_bond_slave_src_mac_type
= \
1785 LLDP_BOND_SLAVE_SRC_MAC_TYPE_LOCALLY_ADMINISTERED
;
1787 /* Get ioctl socket */
1788 log_debug("main", "get an ioctl socket");
1789 if ((cfg
->g_sock
= socket(AF_INET
, SOCK_DGRAM
, 0)) == -1)
1790 fatal("main", "failed to get ioctl socket");
1793 if (!(cfg
->g_config
.c_advertise_version
= advertise_version
) &&
1794 lsb_release
&& lsb_release
[strlen(lsb_release
) - 1] == '\n')
1795 lsb_release
[strlen(lsb_release
) - 1] = '\0';
1796 cfg
->g_lsb_release
= lsb_release
;
1798 cfg
->g_config
.c_description
= descr_override
;
1800 if (platform_override
)
1801 cfg
->g_config
.c_platform
= platform_override
;
1803 /* Set system capabilities */
1804 log_debug("main", "set system capabilities");
1805 if ((lchassis
= (struct lldpd_chassis
*)
1806 calloc(1, sizeof(struct lldpd_chassis
))) == NULL
)
1807 fatal("localchassis", NULL
);
1808 cfg
->g_config
.c_cap_advertise
= 1;
1809 lchassis
->c_cap_available
= LLDP_CAP_BRIDGE
| LLDP_CAP_WLAN
|
1810 LLDP_CAP_ROUTER
| LLDP_CAP_STATION
;
1811 cfg
->g_config
.c_mgmt_advertise
= 1;
1812 TAILQ_INIT(&lchassis
->c_mgmt
);
1813 #ifdef ENABLE_LLDPMED
1815 if (lldpmed
== LLDP_MED_CLASS_III
)
1816 lchassis
->c_cap_available
|= LLDP_CAP_TELEPHONE
;
1817 lchassis
->c_med_type
= lldpmed
;
1818 lchassis
->c_med_cap_available
= LLDP_MED_CAP_CAP
|
1819 LLDP_MED_CAP_IV
| LLDP_MED_CAP_LOCATION
|
1820 LLDP_MED_CAP_POLICY
| LLDP_MED_CAP_MDI_PSE
| LLDP_MED_CAP_MDI_PD
;
1821 cfg
->g_config
.c_noinventory
= noinventory
;
1823 cfg
->g_config
.c_noinventory
= 1;
1827 lchassis
->c_ttl
= cfg
->g_config
.c_tx_interval
* cfg
->g_config
.c_tx_hold
;
1829 log_debug("main", "initialize protocols");
1830 cfg
->g_protocols
= protos
;
1831 for (i
=0; protos
[i
].mode
!= 0; i
++) {
1833 /* With -ll, disable LLDP */
1834 if (protos
[i
].mode
== LLDPD_MODE_LLDP
)
1835 protos
[i
].enabled
%= 3;
1836 /* With -ccc force CDPV2, enable CDPV1 */
1837 if (protos
[i
].mode
== LLDPD_MODE_CDPV1
&& protos
[i
].enabled
== 3) {
1838 protos
[i
].enabled
= 1;
1840 /* With -cc force CDPV1, enable CDPV2 */
1841 if (protos
[i
].mode
== LLDPD_MODE_CDPV2
&& protos
[i
].enabled
== 2) {
1842 protos
[i
].enabled
= 1;
1845 /* With -cccc disable CDPV1, enable CDPV2 */
1846 if (protos
[i
].mode
== LLDPD_MODE_CDPV1
&& protos
[i
].enabled
>= 4) {
1847 protos
[i
].enabled
= 0;
1850 /* With -cccc disable CDPV1, enable CDPV2; -ccccc will force CDPv2 */
1851 if (protos
[i
].mode
== LLDPD_MODE_CDPV2
&& protos
[i
].enabled
== 4) {
1852 protos
[i
].enabled
= 1;
1855 if (protos
[i
].enabled
> 1)
1856 log_info("main", "protocol %s enabled and forced", protos
[i
].name
);
1857 else if (protos
[i
].enabled
)
1858 log_info("main", "protocol %s enabled", protos
[i
].name
);
1860 log_info("main", "protocol %s disabled", protos
[i
].name
);
1863 TAILQ_INIT(&cfg
->g_hardware
);
1864 TAILQ_INIT(&cfg
->g_chassis
);
1865 TAILQ_INSERT_TAIL(&cfg
->g_chassis
, lchassis
, c_entries
);
1866 lchassis
->c_refcount
++; /* We should always keep a reference to local chassis */
1869 log_debug("main", "start main loop");
1871 lchassis
->c_refcount
--;