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_MULTICAST_ADDR
},
49 { LLDPD_MODE_CDPV1
, 0, "CDPv1", 'c', cdpv1_send
, cdp_decode
, cdpv1_guess
,
51 { LLDPD_MODE_CDPV2
, 0, "CDPv2", 'c', cdpv2_send
, cdp_decode
, cdpv2_guess
,
55 { LLDPD_MODE_SONMP
, 0, "SONMP", 's', sonmp_send
, sonmp_decode
, NULL
,
56 SONMP_MULTICAST_ADDR
},
59 { LLDPD_MODE_EDP
, 0, "EDP", 'e', edp_send
, edp_decode
, NULL
,
63 { LLDPD_MODE_FDP
, 0, "FDP", 'f', fdp_send
, cdp_decode
, NULL
,
66 { 0, 0, "any", ' ', NULL
, NULL
, NULL
,
70 static char **saved_argv
;
71 #ifdef HAVE___PROGNAME
72 extern const char *__progname
;
74 # define __progname "lldpd"
80 fprintf(stderr
, "Usage: %s [OPTIONS ...]\n", __progname
);
81 fprintf(stderr
, "Version: %s\n", PACKAGE_STRING
);
83 fprintf(stderr
, "\n");
85 fprintf(stderr
, "-d Do not daemonize.\n");
86 fprintf(stderr
, "-r Receive-only mode\n");
87 fprintf(stderr
, "-i Disable LLDP-MED inventory TLV transmission.\n");
88 fprintf(stderr
, "-k Disable advertising of kernel release, version, machine.\n");
89 fprintf(stderr
, "-S descr Override the default system description.\n");
90 fprintf(stderr
, "-P name Override the default hardware platform.\n");
91 fprintf(stderr
, "-m IP Specify the IPv4 management addresses of this system.\n");
92 fprintf(stderr
, "-u file Specify the Unix-domain socket used for communication with lldpctl(8).\n");
93 fprintf(stderr
, "-H mode Specify the behaviour when detecting multiple neighbors.\n");
94 fprintf(stderr
, "-I iface Limit interfaces to use.\n");
96 fprintf(stderr
, "-M class Enable emission of LLDP-MED frame. 'class' should be one of:\n");
97 fprintf(stderr
, " 1 Generic Endpoint (Class I)\n");
98 fprintf(stderr
, " 2 Media Endpoint (Class II)\n");
99 fprintf(stderr
, " 3 Communication Device Endpoints (Class III)\n");
100 fprintf(stderr
, " 4 Network Connectivity Device\n");
103 fprintf(stderr
, "-x Enable SNMP subagent.\n");
105 fprintf(stderr
, "\n");
107 #if defined ENABLE_CDP || defined ENABLE_EDP || defined ENABLE_FDP || defined ENABLE_SONMP
108 fprintf(stderr
, "Additional protocol support.\n");
110 fprintf(stderr
, "-c Enable the support of CDP protocol. (Cisco)\n");
113 fprintf(stderr
, "-e Enable the support of EDP protocol. (Extreme)\n");
116 fprintf(stderr
, "-f Enable the support of FDP protocol. (Foundry)\n");
119 fprintf(stderr
, "-s Enable the support of SONMP protocol. (Nortel)\n");
122 fprintf(stderr
, "\n");
125 fprintf(stderr
, "see manual page lldpd(8) for more information\n");
129 struct lldpd_hardware
*
130 lldpd_get_hardware(struct lldpd
*cfg
, char *name
, int index
, struct lldpd_ops
*ops
)
132 struct lldpd_hardware
*hardware
;
133 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
) {
134 if ((strcmp(hardware
->h_ifname
, name
) == 0) &&
135 (hardware
->h_ifindex
== index
) &&
136 ((!ops
) || (ops
== hardware
->h_ops
)))
142 struct lldpd_hardware
*
143 lldpd_alloc_hardware(struct lldpd
*cfg
, char *name
, int index
)
145 struct lldpd_hardware
*hardware
;
147 log_debug("alloc", "allocate a new local port (%s)", name
);
149 if ((hardware
= (struct lldpd_hardware
*)
150 calloc(1, sizeof(struct lldpd_hardware
))) == NULL
)
153 hardware
->h_cfg
= cfg
;
154 strlcpy(hardware
->h_ifname
, name
, sizeof(hardware
->h_ifname
));
155 hardware
->h_ifindex
= index
;
156 hardware
->h_lport
.p_chassis
= LOCAL_CHASSIS(cfg
);
157 hardware
->h_lport
.p_chassis
->c_refcount
++;
158 TAILQ_INIT(&hardware
->h_rports
);
160 #ifdef ENABLE_LLDPMED
161 if (LOCAL_CHASSIS(cfg
)->c_med_cap_available
) {
162 hardware
->h_lport
.p_med_cap_enabled
= LLDP_MED_CAP_CAP
;
163 if (!cfg
->g_config
.c_noinventory
)
164 hardware
->h_lport
.p_med_cap_enabled
|= LLDP_MED_CAP_IV
;
168 TAILQ_INIT(&hardware
->h_lport
.p_vlans
);
169 TAILQ_INIT(&hardware
->h_lport
.p_ppvids
);
170 TAILQ_INIT(&hardware
->h_lport
.p_pids
);
173 TAILQ_INIT(&hardware
->h_lport
.p_custom_list
);
176 levent_hardware_init(hardware
);
181 lldpd_alloc_mgmt(int family
, void *addrptr
, size_t addrsize
, u_int32_t iface
)
183 struct lldpd_mgmt
*mgmt
;
185 log_debug("alloc", "allocate a new management address (family: %d)", family
);
187 if (family
<= LLDPD_AF_UNSPEC
|| family
>= LLDPD_AF_LAST
) {
188 errno
= EAFNOSUPPORT
;
191 if (addrsize
> LLDPD_MGMT_MAXADDRSIZE
) {
195 mgmt
= calloc(1, sizeof(struct lldpd_mgmt
));
200 mgmt
->m_family
= family
;
201 assert(addrsize
<= LLDPD_MGMT_MAXADDRSIZE
);
202 memcpy(&mgmt
->m_addr
, addrptr
, addrsize
);
203 mgmt
->m_addrsize
= addrsize
;
204 mgmt
->m_iface
= iface
;
209 lldpd_hardware_cleanup(struct lldpd
*cfg
, struct lldpd_hardware
*hardware
)
211 log_debug("alloc", "cleanup hardware port %s", hardware
->h_ifname
);
213 free(hardware
->h_lport_previous
);
214 free(hardware
->h_lchassis_previous_id
);
215 free(hardware
->h_lport_previous_id
);
216 lldpd_port_cleanup(&hardware
->h_lport
, 1);
217 if (hardware
->h_ops
&& hardware
->h_ops
->cleanup
)
218 hardware
->h_ops
->cleanup(cfg
, hardware
);
219 levent_hardware_release(hardware
);
224 lldpd_display_neighbors(struct lldpd
*cfg
)
226 if (!cfg
->g_config
.c_set_ifdescr
) return;
227 struct lldpd_hardware
*hardware
;
228 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
) {
229 struct lldpd_port
*port
;
231 const char *neighbor
= NULL
;
232 unsigned neighbors
= 0;
233 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
234 if (SMART_HIDDEN(port
)) continue;
236 neighbor
= port
->p_chassis
->c_name
;
239 priv_iface_description(hardware
->h_ifname
,
241 else if (neighbors
== 1 && neighbor
&& *neighbor
!= '\0') {
242 if (asprintf(&description
, "%s",
244 priv_iface_description(hardware
->h_ifname
, description
);
248 if (asprintf(&description
, "%d neighbor%s",
249 neighbors
, (neighbors
> 1)?"s":"") != -1) {
250 priv_iface_description(hardware
->h_ifname
,
259 lldpd_count_neighbors(struct lldpd
*cfg
)
261 #if HAVE_SETPROCTITLE
262 struct lldpd_chassis
*chassis
;
263 const char *neighbor
;
264 unsigned neighbors
= 0;
265 TAILQ_FOREACH(chassis
, &cfg
->g_chassis
, c_entries
) {
267 neighbor
= chassis
->c_name
;
271 setproctitle("no neighbor");
272 else if (neighbors
== 1 && neighbor
&& *neighbor
!= '\0')
273 setproctitle("connected to %s", neighbor
);
275 setproctitle("%d neighbor%s", neighbors
,
276 (neighbors
> 1)?"s":"");
278 lldpd_display_neighbors(cfg
);
282 notify_clients_deletion(struct lldpd_hardware
*hardware
,
283 struct lldpd_port
*rport
)
285 TRACE(LLDPD_NEIGHBOR_DELETE(hardware
->h_ifname
,
286 rport
->p_chassis
->c_name
,
288 levent_ctl_notify(hardware
->h_ifname
, NEIGHBOR_CHANGE_DELETED
,
291 agent_notify(hardware
, NEIGHBOR_CHANGE_DELETED
, rport
);
296 lldpd_reset_timer(struct lldpd
*cfg
)
298 /* Reset timer for ports that have been changed. */
299 struct lldpd_hardware
*hardware
;
300 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
) {
301 /* We keep a flat copy of the local port to see if there is any
302 * change. To do this, we zero out fields that are not
303 * significant, marshal the port, then restore. */
304 struct lldpd_port
*port
= &hardware
->h_lport
;
305 u_int8_t
*output
= NULL
;
307 char save
[LLDPD_PORT_START_MARKER
];
308 memcpy(save
, port
, sizeof(save
));
309 /* coverity[suspicious_sizeof]
310 We intentionally partially memset port */
311 memset(port
, 0, sizeof(save
));
312 output_len
= lldpd_port_serialize(port
, (void**)&output
);
313 memcpy(port
, save
, sizeof(save
));
314 if (output_len
== -1) {
315 log_warnx("localchassis",
316 "unable to serialize local port %s to check for differences",
321 /* Compare with the previous value */
322 if (hardware
->h_lport_previous
&&
323 output_len
== hardware
->h_lport_previous_len
&&
324 !memcmp(output
, hardware
->h_lport_previous
, output_len
)) {
325 log_debug("localchassis",
326 "no change detected for port %s",
329 log_debug("localchassis",
330 "change detected for port %s, resetting its timer",
332 levent_schedule_pdu(hardware
);
335 /* Update the value */
336 free(hardware
->h_lport_previous
);
337 hardware
->h_lport_previous
= output
;
338 hardware
->h_lport_previous_len
= output_len
;
343 lldpd_cleanup(struct lldpd
*cfg
)
345 struct lldpd_hardware
*hardware
, *hardware_next
;
346 struct lldpd_chassis
*chassis
, *chassis_next
;
348 log_debug("localchassis", "cleanup all ports");
350 for (hardware
= TAILQ_FIRST(&cfg
->g_hardware
); hardware
!= NULL
;
351 hardware
= hardware_next
) {
352 hardware_next
= TAILQ_NEXT(hardware
, h_entries
);
353 if (!hardware
->h_flags
) {
354 TRACE(LLDPD_INTERFACES_DELETE(hardware
->h_ifname
));
355 TAILQ_REMOVE(&cfg
->g_hardware
, hardware
, h_entries
);
356 lldpd_remote_cleanup(hardware
, notify_clients_deletion
, 1);
357 lldpd_hardware_cleanup(cfg
, hardware
);
359 lldpd_remote_cleanup(hardware
, notify_clients_deletion
, 0);
362 log_debug("localchassis", "cleanup all chassis");
364 for (chassis
= TAILQ_FIRST(&cfg
->g_chassis
); chassis
;
365 chassis
= chassis_next
) {
366 chassis_next
= TAILQ_NEXT(chassis
, c_entries
);
367 if (chassis
->c_refcount
== 0) {
368 TAILQ_REMOVE(&cfg
->g_chassis
, chassis
, c_entries
);
369 lldpd_chassis_cleanup(chassis
, 1);
373 lldpd_count_neighbors(cfg
);
374 levent_schedule_cleanup(cfg
);
377 /* Update chassis `ochassis' with values from `chassis'. The later one is not
378 expected to be part of a list! It will also be wiped from memory. */
380 lldpd_move_chassis(struct lldpd_chassis
*ochassis
,
381 struct lldpd_chassis
*chassis
) {
382 struct lldpd_mgmt
*mgmt
, *mgmt_next
;
384 /* We want to keep refcount, index and list stuff from the current
386 TAILQ_ENTRY(lldpd_chassis
) entries
;
387 int refcount
= ochassis
->c_refcount
;
388 int index
= ochassis
->c_index
;
389 memcpy(&entries
, &ochassis
->c_entries
,
391 lldpd_chassis_cleanup(ochassis
, 0);
394 /* WARNING: this is a kludgy hack, we need in-place copy and cannot use
396 memcpy(ochassis
, chassis
, sizeof(struct lldpd_chassis
));
397 TAILQ_INIT(&ochassis
->c_mgmt
);
399 /* Copy of management addresses */
400 for (mgmt
= TAILQ_FIRST(&chassis
->c_mgmt
);
403 mgmt_next
= TAILQ_NEXT(mgmt
, m_entries
);
404 TAILQ_REMOVE(&chassis
->c_mgmt
, mgmt
, m_entries
);
405 TAILQ_INSERT_TAIL(&ochassis
->c_mgmt
, mgmt
, m_entries
);
408 /* Restore saved values */
409 ochassis
->c_refcount
= refcount
;
410 ochassis
->c_index
= index
;
411 memcpy(&ochassis
->c_entries
, &entries
, sizeof(entries
));
413 /* Get rid of the new chassis */
418 lldpd_guess_type(struct lldpd
*cfg
, char *frame
, int s
)
421 if (s
< ETHER_ADDR_LEN
)
423 for (i
=0; cfg
->g_protocols
[i
].mode
!= 0; i
++) {
424 if (!cfg
->g_protocols
[i
].enabled
)
426 if (cfg
->g_protocols
[i
].guess
== NULL
) {
427 if (memcmp(frame
, cfg
->g_protocols
[i
].mac
, ETHER_ADDR_LEN
) == 0) {
428 log_debug("decode", "guessed protocol is %s (from MAC address)",
429 cfg
->g_protocols
[i
].name
);
430 return cfg
->g_protocols
[i
].mode
;
433 if (cfg
->g_protocols
[i
].guess(frame
, s
)) {
434 log_debug("decode", "guessed protocol is %s (from detector function)",
435 cfg
->g_protocols
[i
].name
);
436 return cfg
->g_protocols
[i
].mode
;
444 lldpd_decode(struct lldpd
*cfg
, char *frame
, int s
,
445 struct lldpd_hardware
*hardware
)
448 struct lldpd_chassis
*chassis
, *ochassis
= NULL
;
449 struct lldpd_port
*port
, *oport
= NULL
, *aport
;
450 int guess
= LLDPD_MODE_LLDP
;
452 log_debug("decode", "decode a received frame on %s",
455 if (s
< sizeof(struct ether_header
) + 4)
456 /* Too short, just discard it */
459 /* Decapsulate VLAN frames */
460 struct ether_header eheader
;
461 memcpy(&eheader
, frame
, sizeof(struct ether_header
));
462 if (eheader
.ether_type
== htons(ETHERTYPE_VLAN
)) {
463 /* VLAN decapsulation means to shift 4 bytes left the frame from
464 * offset 2*ETHER_ADDR_LEN */
465 memmove(frame
+ 2*ETHER_ADDR_LEN
, frame
+ 2*ETHER_ADDR_LEN
+ 4, s
- 2*ETHER_ADDR_LEN
);
469 TAILQ_FOREACH(oport
, &hardware
->h_rports
, p_entries
) {
470 if ((oport
->p_lastframe
!= NULL
) &&
471 (oport
->p_lastframe
->size
== s
) &&
472 (memcmp(oport
->p_lastframe
->frame
, frame
, s
) == 0)) {
473 /* Already received the same frame */
474 log_debug("decode", "duplicate frame, no need to decode");
475 oport
->p_lastupdate
= time(NULL
);
480 guess
= lldpd_guess_type(cfg
, frame
, s
);
481 for (i
=0; cfg
->g_protocols
[i
].mode
!= 0; i
++) {
482 if (!cfg
->g_protocols
[i
].enabled
)
484 if (cfg
->g_protocols
[i
].mode
== guess
) {
485 log_debug("decode", "using decode function for %s protocol",
486 cfg
->g_protocols
[i
].name
);
487 if (cfg
->g_protocols
[i
].decode(cfg
, frame
,
488 s
, hardware
, &chassis
, &port
) == -1) {
489 log_debug("decode", "function for %s protocol did not decode this frame",
490 cfg
->g_protocols
[i
].name
);
493 chassis
->c_protocol
= port
->p_protocol
=
494 cfg
->g_protocols
[i
].mode
;
498 if (cfg
->g_protocols
[i
].mode
== 0) {
499 log_debug("decode", "unable to guess frame type on %s",
503 TRACE(LLDPD_FRAME_DECODED(
505 cfg
->g_protocols
[i
].name
,
509 /* Do we already have the same MSAP somewhere? */
511 log_debug("decode", "search for the same MSAP");
512 TAILQ_FOREACH(oport
, &hardware
->h_rports
, p_entries
) {
513 if (port
->p_protocol
== oport
->p_protocol
) {
515 if ((port
->p_id_subtype
== oport
->p_id_subtype
) &&
516 (port
->p_id_len
== oport
->p_id_len
) &&
517 (memcmp(port
->p_id
, oport
->p_id
, port
->p_id_len
) == 0) &&
518 (chassis
->c_id_subtype
== oport
->p_chassis
->c_id_subtype
) &&
519 (chassis
->c_id_len
== oport
->p_chassis
->c_id_len
) &&
520 (memcmp(chassis
->c_id
, oport
->p_chassis
->c_id
,
521 chassis
->c_id_len
) == 0)) {
522 ochassis
= oport
->p_chassis
;
523 log_debug("decode", "MSAP is already known");
528 /* Do we have room for a new MSAP? */
529 if (!oport
&& cfg
->g_config
.c_max_neighbors
) {
530 if (count
== (cfg
->g_config
.c_max_neighbors
- 1)) {
532 "max neighbors %d reached for port %s, "
533 "dropping any new ones silently",
534 cfg
->g_config
.c_max_neighbors
,
536 } else if (count
> cfg
->g_config
.c_max_neighbors
- 1) {
538 "too many neighbors for port %s, drop this new one",
540 lldpd_port_cleanup(port
, 1);
541 lldpd_chassis_cleanup(chassis
, 1);
546 /* No, but do we already know the system? */
548 log_debug("decode", "MSAP is unknown, search for the chassis");
549 TAILQ_FOREACH(ochassis
, &cfg
->g_chassis
, c_entries
) {
550 if ((chassis
->c_protocol
== ochassis
->c_protocol
) &&
551 (chassis
->c_id_subtype
== ochassis
->c_id_subtype
) &&
552 (chassis
->c_id_len
== ochassis
->c_id_len
) &&
553 (memcmp(chassis
->c_id
, ochassis
->c_id
,
554 chassis
->c_id_len
) == 0))
560 /* The port is known, remove it before adding it back */
561 TAILQ_REMOVE(&hardware
->h_rports
, oport
, p_entries
);
562 lldpd_port_cleanup(oport
, 1);
566 lldpd_move_chassis(ochassis
, chassis
);
569 /* Chassis not known, add it */
570 log_debug("decode", "unknown chassis, add it to the list");
571 chassis
->c_index
= ++cfg
->g_lastrid
;
572 chassis
->c_refcount
= 0;
573 TAILQ_INSERT_TAIL(&cfg
->g_chassis
, chassis
, c_entries
);
574 i
= 0; TAILQ_FOREACH(ochassis
, &cfg
->g_chassis
, c_entries
) i
++;
575 log_debug("decode", "%d different systems are known", i
);
578 port
->p_lastchange
= port
->p_lastupdate
= time(NULL
);
579 if ((port
->p_lastframe
= (struct lldpd_frame
*)malloc(s
+
580 sizeof(struct lldpd_frame
))) != NULL
) {
581 port
->p_lastframe
->size
= s
;
582 memcpy(port
->p_lastframe
->frame
, frame
, s
);
584 TAILQ_INSERT_TAIL(&hardware
->h_rports
, port
, p_entries
);
585 port
->p_chassis
= chassis
;
586 port
->p_chassis
->c_refcount
++;
587 /* Several cases are possible :
588 1. chassis is new, its refcount was 0. It is now attached
589 to this port, its refcount is 1.
590 2. chassis already exists and was attached to another
591 port, we increase its refcount accordingly.
592 3. chassis already exists and was attached to the same
593 port, its refcount was decreased with
594 lldpd_port_cleanup() and is now increased again.
596 In all cases, if the port already existed, it has been
597 freed with lldpd_port_cleanup() and therefore, the refcount
598 of the chassis that was attached to it is decreased.
600 /* coverity[use_after_free]
601 TAILQ_REMOVE does the right thing */
602 i
= 0; TAILQ_FOREACH(aport
, &hardware
->h_rports
, p_entries
)
604 log_debug("decode", "%d neighbors for %s", i
,
607 if (!oport
) hardware
->h_insert_cnt
++;
610 log_debug("decode", "send notifications for changes on %s",
613 TRACE(LLDPD_NEIGHBOR_UPDATE(hardware
->h_ifname
,
617 levent_ctl_notify(hardware
->h_ifname
, NEIGHBOR_CHANGE_UPDATED
, port
);
619 agent_notify(hardware
, NEIGHBOR_CHANGE_UPDATED
, port
);
622 TRACE(LLDPD_NEIGHBOR_NEW(hardware
->h_ifname
,
626 levent_ctl_notify(hardware
->h_ifname
, NEIGHBOR_CHANGE_ADDED
, port
);
628 agent_notify(hardware
, NEIGHBOR_CHANGE_ADDED
, port
);
632 #ifdef ENABLE_LLDPMED
633 if (!oport
&& port
->p_chassis
->c_med_type
) {
634 /* New neighbor, fast start */
635 if (hardware
->h_cfg
->g_config
.c_enable_fast_start
&&
636 !hardware
->h_tx_fast
) {
637 log_debug("decode", "%s: entering fast start due to "
638 "new neighbor", hardware
->h_ifname
);
639 hardware
->h_tx_fast
= hardware
->h_cfg
->g_config
.c_tx_fast_init
;
642 levent_schedule_pdu(hardware
);
649 /* Get the output of lsb_release -s -d. This is a slow function. It should be
650 called once. It return NULL if any problem happens. Otherwise, this is a
651 statically allocated buffer. The result includes the trailing \n */
653 lldpd_get_lsb_release() {
654 static char release
[1024];
655 char *const command
[] = { "lsb_release", "-s", "-d", NULL
};
656 int pid
, status
, devnull
, count
;
659 log_debug("localchassis", "grab LSB release");
662 log_warn("localchassis", "unable to get a pair of pipes");
669 log_warn("localchassis", "unable to fork");
672 /* Child, exec lsb_release */
674 if ((devnull
= open("/dev/null", O_RDWR
, 0)) != -1) {
675 dup2(devnull
, STDIN_FILENO
);
676 dup2(devnull
, STDERR_FILENO
);
677 dup2(pipefd
[1], STDOUT_FILENO
);
678 if (devnull
> 2) close(devnull
);
679 if (pipefd
[1] > 2) close(pipefd
[1]);
680 execvp("lsb_release", command
);
685 /* Father, read the output from the children */
689 status
= read(pipefd
[0], release
+count
, sizeof(release
)-count
);
690 if ((status
== -1) && (errno
== EINTR
)) continue;
693 } while (count
< sizeof(release
) && (status
> 0));
695 log_info("localchassis", "unable to read from lsb_release");
697 waitpid(pid
, &status
, 0);
701 if (count
>= sizeof(release
)) {
702 log_info("localchassis", "output of lsb_release is too large");
703 waitpid(pid
, &status
, 0);
707 if (waitpid(pid
, &status
, 0) != pid
)
709 if (!WIFEXITED(status
) || (WEXITSTATUS(status
) != 0)) {
710 log_info("localchassis", "lsb_release information not available");
714 log_info("localchassis", "lsb_release returned an empty string");
717 release
[count
] = '\0';
720 /* Should not be here */
724 /* Same like lldpd_get_lsb_release but reads /etc/os-release for PRETTY_NAME=. */
726 lldpd_get_os_release() {
727 static char release
[1024];
730 char *ptr1
= release
;
732 log_debug("localchassis", "grab OS release");
733 FILE *fp
= fopen("/etc/os-release", "r");
735 log_debug("localchassis", "could not open /etc/os-release");
736 fp
= fopen("/usr/lib/os-release", "r");
739 log_info("localchassis",
740 "could not open either /etc/os-release or /usr/lib/os-release");
744 while ((fgets(line
, sizeof(line
), fp
) != NULL
)) {
745 key
= strtok(line
, "=");
746 val
= strtok(NULL
, "=");
748 if (strncmp(key
, "PRETTY_NAME", sizeof(line
)) == 0) {
749 strlcpy(release
, val
, sizeof(line
));
755 /* Remove trailing newline and all " in the string. */
756 ptr1
= release
+ strlen(release
) - 1;
757 while (ptr1
!= release
&&
758 ((*ptr1
== '"') || (*ptr1
== '\n'))) {
762 if (release
[0] == '"')
768 lldpd_hide_ports(struct lldpd
*cfg
, struct lldpd_hardware
*hardware
, int mask
) {
769 struct lldpd_port
*port
;
770 int protocols
[LLDPD_MODE_MAX
+1];
775 log_debug("smartfilter", "apply smart filter for port %s",
778 /* Compute the number of occurrences of each protocol */
779 for (i
= 0; i
<= LLDPD_MODE_MAX
; i
++) protocols
[i
] = 0;
780 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
)
781 protocols
[port
->p_protocol
]++;
783 /* Turn the protocols[] array into an array of
784 enabled/disabled protocols. 1 means enabled, 0
786 min
= (unsigned int)-1;
787 for (i
= 0; i
<= LLDPD_MODE_MAX
; i
++)
788 if (protocols
[i
] && (protocols
[i
] < min
))
791 for (i
= 0; i
<= LLDPD_MODE_MAX
; i
++)
792 if ((protocols
[i
] == min
) && !found
) {
793 /* If we need a tie breaker, we take
794 the first protocol only */
795 if (cfg
->g_config
.c_smart
& mask
&
796 (SMART_OUTGOING_ONE_PROTO
| SMART_INCOMING_ONE_PROTO
))
799 } else protocols
[i
] = 0;
801 /* We set the p_hidden flag to 1 if the protocol is disabled */
802 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
803 if (mask
== SMART_OUTGOING
)
804 port
->p_hidden_out
= protocols
[port
->p_protocol
]?0:1;
806 port
->p_hidden_in
= protocols
[port
->p_protocol
]?0:1;
809 /* If we want only one neighbor, we take the first one */
810 if (cfg
->g_config
.c_smart
& mask
&
811 (SMART_OUTGOING_ONE_NEIGH
| SMART_INCOMING_ONE_NEIGH
)) {
813 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
814 if (mask
== SMART_OUTGOING
) {
815 if (found
) port
->p_hidden_out
= 1;
816 if (!port
->p_hidden_out
)
819 if (mask
== SMART_INCOMING
) {
820 if (found
) port
->p_hidden_in
= 1;
821 if (!port
->p_hidden_in
)
827 /* Print a debug message summarizing the operation */
828 for (i
= 0; i
<= LLDPD_MODE_MAX
; i
++) protocols
[i
] = 0;
830 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
831 if (!(((mask
== SMART_OUTGOING
) && port
->p_hidden_out
) ||
832 ((mask
== SMART_INCOMING
) && port
->p_hidden_in
))) {
834 protocols
[port
->p_protocol
] = 1;
839 for (i
=0; cfg
->g_protocols
[i
].mode
!= 0; i
++) {
840 if (cfg
->g_protocols
[i
].enabled
&& protocols
[cfg
->g_protocols
[i
].mode
]) {
842 strlen(cfg
->g_protocols
[i
].name
) + 3 > sizeof(buffer
)) {
843 /* Unlikely, our buffer is too small */
844 memcpy(buffer
+ sizeof(buffer
) - 4, "...", 4);
848 strncat(buffer
, ", ", 2);
849 strncat(buffer
, cfg
->g_protocols
[i
].name
, strlen(cfg
->g_protocols
[i
].name
));
852 log_debug("smartfilter", "%s: %s: %d visible neighbors (out of %d)",
854 (mask
== SMART_OUTGOING
)?"out filter":"in filter",
856 log_debug("smartfilter", "%s: protocols: %s",
857 hardware
->h_ifname
, buffer
[0]?buffer
:"(none)");
860 /* Hide unwanted ports depending on smart mode set by the user */
862 lldpd_hide_all(struct lldpd
*cfg
)
864 struct lldpd_hardware
*hardware
;
866 if (!cfg
->g_config
.c_smart
)
868 log_debug("smartfilter", "apply smart filter results on all ports");
869 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
) {
870 if (cfg
->g_config
.c_smart
& SMART_INCOMING_FILTER
)
871 lldpd_hide_ports(cfg
, hardware
, SMART_INCOMING
);
872 if (cfg
->g_config
.c_smart
& SMART_OUTGOING_FILTER
)
873 lldpd_hide_ports(cfg
, hardware
, SMART_OUTGOING
);
878 lldpd_recv(struct lldpd
*cfg
, struct lldpd_hardware
*hardware
, int fd
)
882 log_debug("receive", "receive a frame on %s",
884 if ((buffer
= (char *)malloc(hardware
->h_mtu
)) == NULL
) {
885 log_warn("receive", "failed to alloc reception buffer");
888 if ((n
= hardware
->h_ops
->recv(cfg
, hardware
,
890 hardware
->h_mtu
)) == -1) {
891 log_debug("receive", "discard frame received on %s",
896 if (cfg
->g_config
.c_paused
) {
897 log_debug("receive", "paused, ignore the frame on %s",
902 hardware
->h_rx_cnt
++;
903 log_debug("receive", "decode received frame on %s",
905 TRACE(LLDPD_FRAME_RECEIVED(hardware
->h_ifname
, buffer
, (size_t)n
));
906 lldpd_decode(cfg
, buffer
, n
, hardware
);
907 lldpd_hide_all(cfg
); /* Immediatly hide */
908 lldpd_count_neighbors(cfg
);
913 lldpd_send_shutdown(struct lldpd_hardware
*hardware
)
915 struct lldpd
*cfg
= hardware
->h_cfg
;
916 if (cfg
->g_config
.c_receiveonly
|| cfg
->g_config
.c_paused
) return;
917 if ((hardware
->h_flags
& IFF_RUNNING
) == 0)
920 /* It's safe to call `lldp_send_shutdown()` because shutdown LLDPU will
921 * only be emitted if LLDP was sent on that port. */
922 if (lldp_send_shutdown(hardware
->h_cfg
, hardware
) != 0)
923 log_warnx("send", "unable to send shutdown LLDPDU on %s",
928 lldpd_send(struct lldpd_hardware
*hardware
)
930 struct lldpd
*cfg
= hardware
->h_cfg
;
931 struct lldpd_port
*port
;
934 if (cfg
->g_config
.c_receiveonly
|| cfg
->g_config
.c_paused
) return;
935 if ((hardware
->h_flags
& IFF_RUNNING
) == 0)
938 log_debug("send", "send PDU on %s", hardware
->h_ifname
);
940 for (i
=0; cfg
->g_protocols
[i
].mode
!= 0; i
++) {
941 if (!cfg
->g_protocols
[i
].enabled
)
943 /* We send only if we have at least one remote system
944 * speaking this protocol or if the protocol is forced */
945 if (cfg
->g_protocols
[i
].enabled
> 1) {
946 cfg
->g_protocols
[i
].send(cfg
, hardware
);
950 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
951 /* If this remote port is disabled, we don't
953 if (port
->p_hidden_out
)
955 if (port
->p_protocol
==
956 cfg
->g_protocols
[i
].mode
) {
957 TRACE(LLDPD_FRAME_SEND(hardware
->h_ifname
,
958 cfg
->g_protocols
[i
].name
));
959 log_debug("send", "send PDU on %s with protocol %s",
961 cfg
->g_protocols
[i
].name
);
962 cfg
->g_protocols
[i
].send(cfg
,
971 /* Nothing was sent for this port, let's speak the first
972 * available protocol. */
973 for (i
= 0; cfg
->g_protocols
[i
].mode
!= 0; i
++) {
974 if (!cfg
->g_protocols
[i
].enabled
) continue;
975 TRACE(LLDPD_FRAME_SEND(hardware
->h_ifname
,
976 cfg
->g_protocols
[i
].name
));
977 log_debug("send", "fallback to protocol %s for %s",
978 cfg
->g_protocols
[i
].name
, hardware
->h_ifname
);
979 cfg
->g_protocols
[i
].send(cfg
,
983 if (cfg
->g_protocols
[i
].mode
== 0)
984 log_warnx("send", "no protocol enabled, dunno what to send");
988 #ifdef ENABLE_LLDPMED
990 lldpd_med(struct lldpd_chassis
*chassis
)
992 static short int once
= 0;
994 chassis
->c_med_hw
= dmi_hw();
995 chassis
->c_med_fw
= dmi_fw();
996 chassis
->c_med_sn
= dmi_sn();
997 chassis
->c_med_manuf
= dmi_manuf();
998 chassis
->c_med_model
= dmi_model();
999 chassis
->c_med_asset
= dmi_asset();
1006 lldpd_routing_enabled(struct lldpd
*cfg
)
1010 if ((LOCAL_CHASSIS(cfg
)->c_cap_available
& LLDP_CAP_ROUTER
) == 0)
1013 if ((routing
= interfaces_routing_enabled(cfg
)) == -1) {
1014 log_debug("localchassis", "unable to check if routing is enabled");
1021 lldpd_update_localchassis(struct lldpd
*cfg
)
1026 log_debug("localchassis", "update information for local chassis");
1027 assert(LOCAL_CHASSIS(cfg
) != NULL
);
1029 /* Set system name and description */
1031 fatal("localchassis", "failed to get system information");
1032 if (cfg
->g_config
.c_hostname
) {
1033 log_debug("localchassis", "use overridden system name `%s`", cfg
->g_config
.c_hostname
);
1034 hp
= cfg
->g_config
.c_hostname
;
1036 if ((hp
= priv_gethostname()) == NULL
)
1037 fatal("localchassis", "failed to get system name");
1039 free(LOCAL_CHASSIS(cfg
)->c_name
);
1040 free(LOCAL_CHASSIS(cfg
)->c_descr
);
1041 if ((LOCAL_CHASSIS(cfg
)->c_name
= strdup(hp
)) == NULL
)
1042 fatal("localchassis", NULL
);
1043 if (cfg
->g_config
.c_description
) {
1044 log_debug("localchassis", "use overridden description `%s`", cfg
->g_config
.c_description
);
1045 if (asprintf(&LOCAL_CHASSIS(cfg
)->c_descr
, "%s",
1046 cfg
->g_config
.c_description
) == -1)
1047 fatal("localchassis", "failed to set full system description");
1049 if (cfg
->g_config
.c_advertise_version
) {
1050 log_debug("localchassis", "advertise system version");
1051 if (asprintf(&LOCAL_CHASSIS(cfg
)->c_descr
, "%s %s %s %s %s",
1052 cfg
->g_lsb_release
?cfg
->g_lsb_release
:"",
1053 un
.sysname
, un
.release
, un
.version
, un
.machine
)
1055 fatal("localchassis", "failed to set full system description");
1057 log_debug("localchassis", "do not advertise system version");
1058 if (asprintf(&LOCAL_CHASSIS(cfg
)->c_descr
, "%s",
1059 cfg
->g_lsb_release
?cfg
->g_lsb_release
:un
.sysname
) == -1)
1060 fatal("localchassis", "failed to set minimal system description");
1065 if (lldpd_routing_enabled(cfg
)) {
1066 log_debug("localchassis", "routing is enabled, enable router capability");
1067 LOCAL_CHASSIS(cfg
)->c_cap_enabled
|= LLDP_CAP_ROUTER
;
1069 LOCAL_CHASSIS(cfg
)->c_cap_enabled
&= ~LLDP_CAP_ROUTER
;
1071 #ifdef ENABLE_LLDPMED
1072 if (LOCAL_CHASSIS(cfg
)->c_cap_available
& LLDP_CAP_TELEPHONE
)
1073 LOCAL_CHASSIS(cfg
)->c_cap_enabled
|= LLDP_CAP_TELEPHONE
;
1074 lldpd_med(LOCAL_CHASSIS(cfg
));
1075 free(LOCAL_CHASSIS(cfg
)->c_med_sw
);
1076 if (cfg
->g_config
.c_advertise_version
)
1077 LOCAL_CHASSIS(cfg
)->c_med_sw
= strdup(un
.release
);
1079 LOCAL_CHASSIS(cfg
)->c_med_sw
= strdup("Unknown");
1081 if ((LOCAL_CHASSIS(cfg
)->c_cap_available
& LLDP_CAP_STATION
) &&
1082 (LOCAL_CHASSIS(cfg
)->c_cap_enabled
== 0))
1083 LOCAL_CHASSIS(cfg
)->c_cap_enabled
= LLDP_CAP_STATION
;
1085 /* Set chassis ID if needed. This is only done if chassis ID
1086 has not been set previously (with the MAC address of an
1087 interface for example)
1089 if (LOCAL_CHASSIS(cfg
)->c_id
== NULL
) {
1090 log_debug("localchassis", "no chassis ID is currently set, use chassis name");
1091 if (!(LOCAL_CHASSIS(cfg
)->c_id
= strdup(LOCAL_CHASSIS(cfg
)->c_name
)))
1092 fatal("localchassis", NULL
);
1093 LOCAL_CHASSIS(cfg
)->c_id_len
= strlen(LOCAL_CHASSIS(cfg
)->c_name
);
1094 LOCAL_CHASSIS(cfg
)->c_id_subtype
= LLDP_CHASSISID_SUBTYPE_LOCAL
;
1099 lldpd_update_localports(struct lldpd
*cfg
)
1101 struct lldpd_hardware
*hardware
;
1103 log_debug("localchassis", "update information for local ports");
1105 /* h_flags is set to 0 for each port. If the port is updated, h_flags
1106 * will be set to a non-zero value. This will allow us to clean up any
1107 * non up-to-date port */
1108 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
)
1109 hardware
->h_flags
= 0;
1111 TRACE(LLDPD_INTERFACES_UPDATE());
1112 interfaces_update(cfg
);
1114 lldpd_reset_timer(cfg
);
1118 lldpd_loop(struct lldpd
*cfg
)
1121 1. Update local ports information
1122 2. Update local chassis information
1124 log_debug("loop", "start new loop");
1125 LOCAL_CHASSIS(cfg
)->c_cap_enabled
= 0;
1126 /* Information for local ports is triggered even when it is possible to
1127 * update them on some other event because we want to refresh them if we
1128 * missed something. */
1129 log_debug("loop", "update information for local ports");
1130 lldpd_update_localports(cfg
);
1131 log_debug("loop", "update information for local chassis");
1132 lldpd_update_localchassis(cfg
);
1133 lldpd_count_neighbors(cfg
);
1137 lldpd_exit(struct lldpd
*cfg
)
1139 struct lldpd_hardware
*hardware
, *hardware_next
;
1140 log_debug("main", "exit lldpd");
1142 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
)
1143 lldpd_send_shutdown(hardware
);
1146 priv_ctl_cleanup(cfg
->g_ctlname
);
1147 log_debug("main", "cleanup hardware information");
1148 for (hardware
= TAILQ_FIRST(&cfg
->g_hardware
); hardware
!= NULL
;
1149 hardware
= hardware_next
) {
1150 hardware_next
= TAILQ_NEXT(hardware
, h_entries
);
1151 log_debug("main", "cleanup interface %s", hardware
->h_ifname
);
1152 lldpd_remote_cleanup(hardware
, NULL
, 1);
1153 lldpd_hardware_cleanup(cfg
, hardware
);
1158 * Run lldpcli to configure lldpd.
1160 * @return PID of running lldpcli or -1 if error.
1163 lldpd_configure(int debug
, const char *path
, const char *ctlname
)
1165 pid_t lldpcli
= vfork();
1168 char sdebug
[debug
+ 3];
1169 memset(sdebug
, 'd', debug
+ 3);
1170 sdebug
[debug
+ 2] = '\0';
1171 sdebug
[0] = '-'; sdebug
[1] = 's';
1172 log_debug("main", "invoke %s %s", path
, sdebug
);
1176 log_warn("main", "unable to fork");
1179 /* Child, exec lldpcli */
1180 if ((devnull
= open("/dev/null", O_RDWR
, 0)) != -1) {
1181 dup2(devnull
, STDIN_FILENO
);
1182 dup2(devnull
, STDOUT_FILENO
);
1183 if (devnull
> 2) close(devnull
);
1185 execl(path
, "lldpcli", sdebug
,
1187 "-c", SYSCONFDIR
"/lldpd.conf",
1188 "-c", SYSCONFDIR
"/lldpd.d",
1191 log_warn("main", "unable to execute %s", path
);
1192 log_warnx("main", "configuration is incomplete, lldpd needs to be unpaused");
1197 /* Father, don't do anything stupid */
1200 /* Should not be here */
1204 struct intint
{ int a
; int b
; };
1205 static const struct intint filters
[] = {
1207 { 1, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
|
1208 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_PROTO
},
1209 { 2, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
},
1210 { 3, SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_PROTO
},
1211 { 4, SMART_INCOMING_FILTER
| SMART_OUTGOING_FILTER
},
1212 { 5, SMART_INCOMING_FILTER
},
1213 { 6, SMART_OUTGOING_FILTER
},
1214 { 7, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
| SMART_INCOMING_ONE_NEIGH
|
1215 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_PROTO
},
1216 { 8, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
| SMART_INCOMING_ONE_NEIGH
},
1217 { 9, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_NEIGH
|
1218 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_PROTO
},
1219 { 10, SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_NEIGH
},
1220 { 11, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_NEIGH
},
1221 { 12, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_NEIGH
|
1222 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_NEIGH
},
1223 { 13, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_NEIGH
|
1224 SMART_OUTGOING_FILTER
},
1225 { 14, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
|
1226 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_NEIGH
},
1227 { 15, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
|
1228 SMART_OUTGOING_FILTER
},
1229 { 16, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
| SMART_INCOMING_ONE_NEIGH
|
1230 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_NEIGH
},
1231 { 17, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
| SMART_INCOMING_ONE_NEIGH
|
1232 SMART_OUTGOING_FILTER
},
1233 { 18, SMART_INCOMING_FILTER
|
1234 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_NEIGH
},
1235 { 19, SMART_INCOMING_FILTER
|
1236 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_PROTO
},
1242 * Tell if we have been started by upstart.
1245 lldpd_started_by_upstart()
1247 #ifdef HOST_OS_LINUX
1248 const char *upstartjob
= getenv("UPSTART_JOB");
1249 if (!(upstartjob
&& !strcmp(upstartjob
, "lldpd")))
1251 log_debug("main", "running with upstart, don't fork but stop");
1253 unsetenv("UPSTART_JOB");
1261 * Tell if we have been started by systemd.
1264 lldpd_started_by_systemd()
1266 #ifdef HOST_OS_LINUX
1268 const char *notifysocket
= getenv("NOTIFY_SOCKET");
1269 if (!notifysocket
||
1270 !strchr("@/", notifysocket
[0]) ||
1271 strlen(notifysocket
) < 2)
1274 log_debug("main", "running with systemd, don't fork but signal ready");
1275 if ((fd
= socket(AF_UNIX
, SOCK_DGRAM
, 0)) < 0) {
1276 log_warn("main", "unable to open systemd notification socket %s",
1281 struct sockaddr_un su
= { .sun_family
= AF_UNIX
};
1282 strlcpy(su
.sun_path
, notifysocket
, sizeof(su
.sun_path
));
1283 if (notifysocket
[0] == '@') su
.sun_path
[0] = 0;
1285 struct iovec iov
= {
1286 .iov_base
= "READY=1",
1287 .iov_len
= strlen("READY=1")
1289 struct msghdr hdr
= {
1291 .msg_namelen
= offsetof(struct sockaddr_un
, sun_path
) + strlen(notifysocket
),
1295 unsetenv("NOTIFY_SOCKET");
1296 if (sendmsg(fd
, &hdr
, MSG_NOSIGNAL
) < 0) {
1297 log_warn("main", "unable to send notification to systemd");
1310 lldpd_main(int argc
, char *argv
[], char *envp
[])
1313 struct lldpd_chassis
*lchassis
;
1317 const char *agentx
= NULL
; /* AgentX socket */
1319 const char *ctlname
= NULL
;
1322 char *interfaces
= NULL
;
1323 /* We do not want more options here. Please add them in lldpcli instead
1324 * unless there is a very good reason. Most command-line options will
1325 * get deprecated at some point. */
1326 char *popt
, opts
[] =
1327 "H:vhkrdD:xX:m:u:4:6:I:C:p:M:P:S:iL:@ ";
1328 int i
, found
, advertise_version
= 1;
1329 #ifdef ENABLE_LLDPMED
1330 int lldpmed
= 0, noinventory
= 0;
1331 int enable_fast_start
= 1;
1333 char *descr_override
= NULL
;
1334 char *platform_override
= NULL
;
1335 char *lsb_release
= NULL
;
1336 const char *lldpcli
= LLDPCLI_PATH
;
1338 int receiveonly
= 0;
1341 #ifdef ENABLE_PRIVSEP
1342 /* Non privileged user */
1343 struct passwd
*user
;
1344 struct group
*group
;
1351 #if HAVE_SETPROCTITLE_INIT
1352 setproctitle_init(argc
, argv
, envp
);
1356 * Get and parse command line options
1358 if ((popt
= strchr(opts
, '@')) != NULL
) {
1360 protos
[i
].mode
!= 0 && *popt
!= '\0';
1362 *(popt
++) = protos
[i
].arg
;
1365 while ((ch
= getopt(argc
, argv
, opts
)) != -1) {
1371 fprintf(stdout
, "%s\n", PACKAGE_VERSION
);
1385 fprintf(stderr
, "-m can only be used once\n");
1388 mgmtp
= strdup(optarg
);
1392 fprintf(stderr
, "-u can only be used once\n");
1399 fprintf(stderr
, "-I can only be used once\n");
1402 interfaces
= strdup(optarg
);
1406 fprintf(stderr
, "-C can only be used once\n");
1409 cidp
= strdup(optarg
);
1412 if (strlen(optarg
)) lldpcli
= optarg
;
1413 else lldpcli
= NULL
;
1416 advertise_version
= 0;
1418 #ifdef ENABLE_LLDPMED
1420 lldpmed
= atoi(optarg
);
1421 if ((lldpmed
< 1) || (lldpmed
> 4)) {
1422 fprintf(stderr
, "-M requires an argument between 1 and 4\n");
1432 fprintf(stderr
, "LLDP-MED support is not built-in\n");
1442 fprintf(stderr
, "-X can only be used once\n");
1451 fprintf(stderr
, "SNMP support is not built-in\n");
1456 if (descr_override
) {
1457 fprintf(stderr
, "-S can only be used once\n");
1460 descr_override
= strdup(optarg
);
1463 if (platform_override
) {
1464 fprintf(stderr
, "-P can only be used once\n");
1467 platform_override
= strdup(optarg
);
1470 smart
= atoi(optarg
);
1474 for (i
=0; protos
[i
].mode
!= 0; i
++) {
1475 if (ch
== protos
[i
].arg
) {
1477 protos
[i
].enabled
++;
1485 if (ctlname
== NULL
) ctlname
= LLDPD_CTL_SOCKET
;
1487 /* Set correct smart mode */
1488 for (i
=0; (filters
[i
].a
!= -1) && (filters
[i
].a
!= smart
); i
++);
1489 if (filters
[i
].a
== -1) {
1490 fprintf(stderr
, "Incorrect mode for -H\n");
1493 smart
= filters
[i
].b
;
1495 log_init(debug
, __progname
);
1496 tzset(); /* Get timezone info before chroot */
1498 log_debug("main", "lldpd starting...");
1500 /* Grab uid and gid to use for priv sep */
1501 #ifdef ENABLE_PRIVSEP
1502 if ((user
= getpwnam(PRIVSEP_USER
)) == NULL
)
1503 fatal("main", "no " PRIVSEP_USER
" user for privilege separation");
1505 if ((group
= getgrnam(PRIVSEP_GROUP
)) == NULL
)
1506 fatal("main", "no " PRIVSEP_GROUP
" group for privilege separation");
1507 gid
= group
->gr_gid
;
1510 /* Create and setup socket */
1512 log_debug("main", "creating control socket");
1513 while ((ctl
= ctl_create(ctlname
)) == -1) {
1514 if (retry
-- && errno
== EADDRINUSE
) {
1515 /* Check if a daemon is really listening */
1517 log_info("main", "unable to create control socket because it already exists");
1518 log_info("main", "check if another instance is running");
1519 if ((tfd
= ctl_connect(ctlname
)) != -1) {
1520 /* Another instance is running */
1522 log_warnx("main", "another instance is running, please stop it");
1523 fatalx("main", "giving up");
1524 } else if (errno
== ECONNREFUSED
) {
1525 /* Nobody is listening */
1526 log_info("main", "old control socket is present, clean it");
1527 ctl_cleanup(ctlname
);
1530 log_warn("main", "cannot determine if another daemon is already running");
1531 fatalx("main", "giving up");
1533 log_warn("main", "unable to create control socket");
1534 fatalx("main", "giving up");
1536 #ifdef ENABLE_PRIVSEP
1537 if (chown(ctlname
, uid
, gid
) == -1)
1538 log_warn("main", "unable to chown control socket");
1540 S_IRUSR
| S_IWUSR
| S_IXUSR
|
1541 S_IRGRP
| S_IWGRP
| S_IXGRP
) == -1)
1542 log_warn("main", "unable to chmod control socket");
1545 /* Disable SIGPIPE */
1546 signal(SIGPIPE
, SIG_IGN
);
1548 /* Disable SIGHUP, until handlers are installed */
1549 signal(SIGHUP
, SIG_IGN
);
1551 /* Configuration with lldpcli */
1553 log_debug("main", "invoking lldpcli for configuration");
1554 if (lldpd_configure(debug
, lldpcli
, ctlname
) == -1)
1555 fatal("main", "unable to spawn lldpcli");
1558 /* Daemonization, unless started by upstart, systemd or launchd or debug */
1560 if (!lldpd_started_by_upstart() && !lldpd_started_by_systemd() &&
1564 log_debug("main", "daemonize");
1565 if (daemon(0, 0) != 0)
1566 fatal("main", "failed to detach daemon");
1567 if ((pid
= open(LLDPD_PID_FILE
,
1568 O_TRUNC
| O_CREAT
| O_WRONLY
, 0666)) == -1)
1569 fatal("main", "unable to open pid file " LLDPD_PID_FILE
);
1570 if (asprintf(&spid
, "%d\n", getpid()) == -1)
1571 fatal("main", "unable to create pid file " LLDPD_PID_FILE
);
1572 if (write(pid
, spid
, strlen(spid
)) == -1)
1573 fatal("main", "unable to write pid file " LLDPD_PID_FILE
);
1579 /* Try to read system information from /etc/os-release if possible.
1580 Fall back to lsb_release for compatibility. */
1581 log_debug("main", "get OS/LSB release information");
1582 lsb_release
= lldpd_get_os_release();
1584 lsb_release
= lldpd_get_lsb_release();
1587 log_debug("main", "initialize privilege separation");
1588 #ifdef ENABLE_PRIVSEP
1589 priv_init(PRIVSEP_CHROOT
, ctl
, uid
, gid
);
1591 priv_init(PRIVSEP_CHROOT
, ctl
, 0, 0);
1594 /* Initialization of global configuration */
1595 if ((cfg
= (struct lldpd
*)
1596 calloc(1, sizeof(struct lldpd
))) == NULL
)
1597 fatal("main", NULL
);
1599 cfg
->g_ctlname
= ctlname
;
1601 cfg
->g_config
.c_mgmt_pattern
= mgmtp
;
1602 cfg
->g_config
.c_cid_pattern
= cidp
;
1603 cfg
->g_config
.c_iface_pattern
= interfaces
;
1604 cfg
->g_config
.c_smart
= smart
;
1606 cfg
->g_config
.c_paused
= 1;
1607 cfg
->g_config
.c_receiveonly
= receiveonly
;
1608 cfg
->g_config
.c_tx_interval
= LLDPD_TX_INTERVAL
;
1609 cfg
->g_config
.c_tx_hold
= LLDPD_TX_HOLD
;
1610 cfg
->g_config
.c_max_neighbors
= LLDPD_MAX_NEIGHBORS
;
1611 #ifdef ENABLE_LLDPMED
1612 cfg
->g_config
.c_enable_fast_start
= enable_fast_start
;
1613 cfg
->g_config
.c_tx_fast_init
= LLDPD_FAST_INIT
;
1614 cfg
->g_config
.c_tx_fast_interval
= LLDPD_FAST_TX_INTERVAL
;
1618 cfg
->g_snmp_agentx
= agentx
;
1619 #endif /* USE_SNMP */
1620 cfg
->g_config
.c_bond_slave_src_mac_type
= \
1621 LLDP_BOND_SLAVE_SRC_MAC_TYPE_LOCALLY_ADMINISTERED
;
1623 /* Get ioctl socket */
1624 log_debug("main", "get an ioctl socket");
1625 if ((cfg
->g_sock
= socket(AF_INET
, SOCK_DGRAM
, 0)) == -1)
1626 fatal("main", "failed to get ioctl socket");
1629 if (!(cfg
->g_config
.c_advertise_version
= advertise_version
) &&
1630 lsb_release
&& lsb_release
[strlen(lsb_release
) - 1] == '\n')
1631 lsb_release
[strlen(lsb_release
) - 1] = '\0';
1632 cfg
->g_lsb_release
= lsb_release
;
1634 cfg
->g_config
.c_description
= descr_override
;
1636 if (platform_override
)
1637 cfg
->g_config
.c_platform
= platform_override
;
1639 /* Set system capabilities */
1640 log_debug("main", "set system capabilities");
1641 if ((lchassis
= (struct lldpd_chassis
*)
1642 calloc(1, sizeof(struct lldpd_chassis
))) == NULL
)
1643 fatal("localchassis", NULL
);
1644 cfg
->g_config
.c_cap_advertise
= 1;
1645 lchassis
->c_cap_available
= LLDP_CAP_BRIDGE
| LLDP_CAP_WLAN
|
1646 LLDP_CAP_ROUTER
| LLDP_CAP_STATION
;
1647 cfg
->g_config
.c_mgmt_advertise
= 1;
1648 TAILQ_INIT(&lchassis
->c_mgmt
);
1649 #ifdef ENABLE_LLDPMED
1651 if (lldpmed
== LLDP_MED_CLASS_III
)
1652 lchassis
->c_cap_available
|= LLDP_CAP_TELEPHONE
;
1653 lchassis
->c_med_type
= lldpmed
;
1654 lchassis
->c_med_cap_available
= LLDP_MED_CAP_CAP
|
1655 LLDP_MED_CAP_IV
| LLDP_MED_CAP_LOCATION
|
1656 LLDP_MED_CAP_POLICY
| LLDP_MED_CAP_MDI_PSE
| LLDP_MED_CAP_MDI_PD
;
1657 cfg
->g_config
.c_noinventory
= noinventory
;
1659 cfg
->g_config
.c_noinventory
= 1;
1663 lchassis
->c_ttl
= cfg
->g_config
.c_tx_interval
* cfg
->g_config
.c_tx_hold
;
1665 log_debug("main", "initialize protocols");
1666 cfg
->g_protocols
= protos
;
1667 for (i
=0; protos
[i
].mode
!= 0; i
++) {
1669 /* With -ll, disable LLDP */
1670 if (protos
[i
].mode
== LLDPD_MODE_LLDP
)
1671 protos
[i
].enabled
%= 3;
1672 /* With -ccc force CDPV2, enable CDPV1 */
1673 if (protos
[i
].mode
== LLDPD_MODE_CDPV1
&& protos
[i
].enabled
== 3) {
1674 protos
[i
].enabled
= 1;
1676 /* With -cc force CDPV1, enable CDPV2 */
1677 if (protos
[i
].mode
== LLDPD_MODE_CDPV2
&& protos
[i
].enabled
== 2) {
1678 protos
[i
].enabled
= 1;
1681 /* With -cccc disable CDPV1, enable CDPV2 */
1682 if (protos
[i
].mode
== LLDPD_MODE_CDPV1
&& protos
[i
].enabled
>= 4) {
1683 protos
[i
].enabled
= 0;
1686 /* With -cccc disable CDPV1, enable CDPV2; -ccccc will force CDPv2 */
1687 if (protos
[i
].mode
== LLDPD_MODE_CDPV2
&& protos
[i
].enabled
== 4) {
1688 protos
[i
].enabled
= 1;
1691 if (protos
[i
].enabled
> 1)
1692 log_info("main", "protocol %s enabled and forced", protos
[i
].name
);
1693 else if (protos
[i
].enabled
)
1694 log_info("main", "protocol %s enabled", protos
[i
].name
);
1696 log_info("main", "protocol %s disabled", protos
[i
].name
);
1699 TAILQ_INIT(&cfg
->g_hardware
);
1700 TAILQ_INIT(&cfg
->g_chassis
);
1701 TAILQ_INSERT_TAIL(&cfg
->g_chassis
, lchassis
, c_entries
);
1702 lchassis
->c_refcount
++; /* We should always keep a reference to local chassis */
1705 log_debug("main", "start main loop");