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 levent_hardware_init(hardware
);
178 lldpd_alloc_mgmt(int family
, void *addrptr
, size_t addrsize
, u_int32_t iface
)
180 struct lldpd_mgmt
*mgmt
;
182 log_debug("alloc", "allocate a new management address (family: %d)", family
);
184 if (family
<= LLDPD_AF_UNSPEC
|| family
>= LLDPD_AF_LAST
) {
185 errno
= EAFNOSUPPORT
;
188 if (addrsize
> LLDPD_MGMT_MAXADDRSIZE
) {
192 mgmt
= calloc(1, sizeof(struct lldpd_mgmt
));
197 mgmt
->m_family
= family
;
198 assert(addrsize
<= LLDPD_MGMT_MAXADDRSIZE
);
199 memcpy(&mgmt
->m_addr
, addrptr
, addrsize
);
200 mgmt
->m_addrsize
= addrsize
;
201 mgmt
->m_iface
= iface
;
206 lldpd_hardware_cleanup(struct lldpd
*cfg
, struct lldpd_hardware
*hardware
)
208 log_debug("alloc", "cleanup hardware port %s", hardware
->h_ifname
);
210 lldpd_port_cleanup(&hardware
->h_lport
, 1);
211 if (hardware
->h_ops
->cleanup
)
212 hardware
->h_ops
->cleanup(cfg
, hardware
);
213 levent_hardware_release(hardware
);
218 lldpd_display_neighbors(struct lldpd
*cfg
)
220 if (!cfg
->g_config
.c_set_ifdescr
) return;
221 struct lldpd_hardware
*hardware
;
222 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
) {
223 struct lldpd_port
*port
;
225 const char *neighbor
= NULL
;
226 unsigned neighbors
= 0;
227 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
228 if (SMART_HIDDEN(port
)) continue;
230 neighbor
= port
->p_chassis
->c_name
;
233 priv_iface_description(hardware
->h_ifname
,
235 else if (neighbors
== 1 && neighbor
) {
236 if (asprintf(&description
, "%s",
238 priv_iface_description(hardware
->h_ifname
, description
);
242 if (asprintf(&description
, "%d neighbor%s",
243 neighbors
, (neighbors
> 1)?"s":"") != -1) {
244 priv_iface_description(hardware
->h_ifname
,
253 lldpd_count_neighbors(struct lldpd
*cfg
)
255 #if HAVE_SETPROCTITLE
256 struct lldpd_chassis
*chassis
;
257 const char *neighbor
;
258 unsigned neighbors
= 0;
259 TAILQ_FOREACH(chassis
, &cfg
->g_chassis
, c_entries
) {
261 neighbor
= chassis
->c_name
;
265 setproctitle("no neighbor");
266 else if (neighbors
== 1 && neighbor
)
267 setproctitle("connected to %s", neighbor
);
269 setproctitle("%d neighbor%s", neighbors
,
270 (neighbors
> 1)?"s":"");
272 lldpd_display_neighbors(cfg
);
276 notify_clients_deletion(struct lldpd_hardware
*hardware
,
277 struct lldpd_port
*rport
)
279 TRACE(LLDPD_NEIGHBOR_DELETE(hardware
->h_ifname
,
280 rport
->p_chassis
->c_name
,
282 levent_ctl_notify(hardware
->h_ifname
, NEIGHBOR_CHANGE_DELETED
,
285 agent_notify(hardware
, NEIGHBOR_CHANGE_DELETED
, rport
);
290 lldpd_reset_timer(struct lldpd
*cfg
)
292 /* Reset timer for ports that have been changed. */
293 struct lldpd_hardware
*hardware
;
294 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
) {
295 /* We need to compute a checksum of the local port. To do this,
296 * we zero out fields that are not significant, marshal the
297 * port, compute the checksum, then restore. */
298 struct lldpd_port
*port
= &hardware
->h_lport
;
300 u_int8_t
*output
= NULL
;
302 char save
[offsetof(struct lldpd_port
, p_id_subtype
)];
303 memcpy(save
, port
, sizeof(save
));
304 memset(port
, 0, sizeof(save
));
305 output_len
= lldpd_port_serialize(port
, (void**)&output
);
306 memcpy(port
, save
, sizeof(save
));
307 if (output_len
== -1) {
308 log_warnx("localchassis",
309 "unable to serialize local port %s to check for differences",
313 cksum
= frame_checksum(output
, output_len
, 0);
315 if (cksum
!= hardware
->h_lport_cksum
) {
316 log_info("localchassis",
317 "change detected for port %s, resetting its timer",
319 hardware
->h_lport_cksum
= cksum
;
320 levent_schedule_pdu(hardware
);
322 log_debug("localchassis",
323 "no change detected for port %s",
330 lldpd_cleanup(struct lldpd
*cfg
)
332 struct lldpd_hardware
*hardware
, *hardware_next
;
333 struct lldpd_chassis
*chassis
, *chassis_next
;
335 log_debug("localchassis", "cleanup all ports");
337 for (hardware
= TAILQ_FIRST(&cfg
->g_hardware
); hardware
!= NULL
;
338 hardware
= hardware_next
) {
339 hardware_next
= TAILQ_NEXT(hardware
, h_entries
);
340 if (!hardware
->h_flags
) {
341 TRACE(LLDPD_INTERFACES_DELETE(hardware
->h_ifname
));
342 TAILQ_REMOVE(&cfg
->g_hardware
, hardware
, h_entries
);
343 lldpd_remote_cleanup(hardware
, notify_clients_deletion
, 1);
344 lldpd_hardware_cleanup(cfg
, hardware
);
346 lldpd_remote_cleanup(hardware
, notify_clients_deletion
, 0);
349 log_debug("localchassis", "cleanup all chassis");
351 for (chassis
= TAILQ_FIRST(&cfg
->g_chassis
); chassis
;
352 chassis
= chassis_next
) {
353 chassis_next
= TAILQ_NEXT(chassis
, c_entries
);
354 if (chassis
->c_refcount
== 0) {
355 TAILQ_REMOVE(&cfg
->g_chassis
, chassis
, c_entries
);
356 lldpd_chassis_cleanup(chassis
, 1);
360 lldpd_count_neighbors(cfg
);
361 levent_schedule_cleanup(cfg
);
364 /* Update chassis `ochassis' with values from `chassis'. The later one is not
365 expected to be part of a list! It will also be wiped from memory. */
367 lldpd_move_chassis(struct lldpd_chassis
*ochassis
,
368 struct lldpd_chassis
*chassis
) {
369 struct lldpd_mgmt
*mgmt
, *mgmt_next
;
371 /* We want to keep refcount, index and list stuff from the current
373 TAILQ_ENTRY(lldpd_chassis
) entries
;
374 int refcount
= ochassis
->c_refcount
;
375 int index
= ochassis
->c_index
;
376 memcpy(&entries
, &ochassis
->c_entries
,
378 lldpd_chassis_cleanup(ochassis
, 0);
381 /* WARNING: this is a kludgy hack, we need in-place copy and cannot use
383 memcpy(ochassis
, chassis
, sizeof(struct lldpd_chassis
));
384 TAILQ_INIT(&ochassis
->c_mgmt
);
386 /* Copy of management addresses */
387 for (mgmt
= TAILQ_FIRST(&chassis
->c_mgmt
);
390 mgmt_next
= TAILQ_NEXT(mgmt
, m_entries
);
391 TAILQ_REMOVE(&chassis
->c_mgmt
, mgmt
, m_entries
);
392 TAILQ_INSERT_TAIL(&ochassis
->c_mgmt
, mgmt
, m_entries
);
395 /* Restore saved values */
396 ochassis
->c_refcount
= refcount
;
397 ochassis
->c_index
= index
;
398 memcpy(&ochassis
->c_entries
, &entries
, sizeof(entries
));
400 /* Get rid of the new chassis */
405 lldpd_guess_type(struct lldpd
*cfg
, char *frame
, int s
)
408 if (s
< ETHER_ADDR_LEN
)
410 for (i
=0; cfg
->g_protocols
[i
].mode
!= 0; i
++) {
411 if (!cfg
->g_protocols
[i
].enabled
)
413 if (cfg
->g_protocols
[i
].guess
== NULL
) {
414 if (memcmp(frame
, cfg
->g_protocols
[i
].mac
, ETHER_ADDR_LEN
) == 0) {
415 log_debug("decode", "guessed protocol is %s (from MAC address)",
416 cfg
->g_protocols
[i
].name
);
417 return cfg
->g_protocols
[i
].mode
;
420 if (cfg
->g_protocols
[i
].guess(frame
, s
)) {
421 log_debug("decode", "guessed protocol is %s (from detector function)",
422 cfg
->g_protocols
[i
].name
);
423 return cfg
->g_protocols
[i
].mode
;
431 lldpd_decode(struct lldpd
*cfg
, char *frame
, int s
,
432 struct lldpd_hardware
*hardware
)
435 struct lldpd_chassis
*chassis
, *ochassis
= NULL
;
436 struct lldpd_port
*port
, *oport
= NULL
, *aport
;
437 int guess
= LLDPD_MODE_LLDP
;
439 log_debug("decode", "decode a received frame on %s",
442 if (s
< sizeof(struct ether_header
) + 4)
443 /* Too short, just discard it */
446 /* Decapsulate VLAN frames */
447 struct ether_header eheader
;
448 memcpy(&eheader
, frame
, sizeof(struct ether_header
));
449 if (eheader
.ether_type
== htons(ETHERTYPE_VLAN
)) {
450 /* VLAN decapsulation means to shift 4 bytes left the frame from
451 * offset 2*ETHER_ADDR_LEN */
452 memmove(frame
+ 2*ETHER_ADDR_LEN
, frame
+ 2*ETHER_ADDR_LEN
+ 4, s
- 2*ETHER_ADDR_LEN
);
456 TAILQ_FOREACH(oport
, &hardware
->h_rports
, p_entries
) {
457 if ((oport
->p_lastframe
!= NULL
) &&
458 (oport
->p_lastframe
->size
== s
) &&
459 (memcmp(oport
->p_lastframe
->frame
, frame
, s
) == 0)) {
460 /* Already received the same frame */
461 log_debug("decode", "duplicate frame, no need to decode");
462 oport
->p_lastupdate
= time(NULL
);
467 guess
= lldpd_guess_type(cfg
, frame
, s
);
468 for (i
=0; cfg
->g_protocols
[i
].mode
!= 0; i
++) {
469 if (!cfg
->g_protocols
[i
].enabled
)
471 if (cfg
->g_protocols
[i
].mode
== guess
) {
472 log_debug("decode", "using decode function for %s protocol",
473 cfg
->g_protocols
[i
].name
);
474 if (cfg
->g_protocols
[i
].decode(cfg
, frame
,
475 s
, hardware
, &chassis
, &port
) == -1) {
476 log_debug("decode", "function for %s protocol did not decode this frame",
477 cfg
->g_protocols
[i
].name
);
480 chassis
->c_protocol
= port
->p_protocol
=
481 cfg
->g_protocols
[i
].mode
;
485 if (cfg
->g_protocols
[i
].mode
== 0) {
486 log_debug("decode", "unable to guess frame type on %s",
490 TRACE(LLDPD_FRAME_DECODED(
492 cfg
->g_protocols
[i
].name
,
496 /* Do we already have the same MSAP somewhere? */
498 log_debug("decode", "search for the same MSAP");
499 TAILQ_FOREACH(oport
, &hardware
->h_rports
, p_entries
) {
500 if (port
->p_protocol
== oport
->p_protocol
) {
502 if ((port
->p_id_subtype
== oport
->p_id_subtype
) &&
503 (port
->p_id_len
== oport
->p_id_len
) &&
504 (memcmp(port
->p_id
, oport
->p_id
, port
->p_id_len
) == 0) &&
505 (chassis
->c_id_subtype
== oport
->p_chassis
->c_id_subtype
) &&
506 (chassis
->c_id_len
== oport
->p_chassis
->c_id_len
) &&
507 (memcmp(chassis
->c_id
, oport
->p_chassis
->c_id
,
508 chassis
->c_id_len
) == 0)) {
509 ochassis
= oport
->p_chassis
;
510 log_debug("decode", "MSAP is already known");
515 /* Do we have room for a new MSAP? */
516 if (!oport
&& cfg
->g_config
.c_max_neighbors
&&
517 count
> cfg
->g_config
.c_max_neighbors
- 1) {
519 "too many neighbors for port %s, drop this new one",
521 lldpd_port_cleanup(port
, 1);
522 lldpd_chassis_cleanup(chassis
, 1);
526 /* No, but do we already know the system? */
528 log_debug("decode", "MSAP is unknown, search for the chassis");
529 TAILQ_FOREACH(ochassis
, &cfg
->g_chassis
, c_entries
) {
530 if ((chassis
->c_protocol
== ochassis
->c_protocol
) &&
531 (chassis
->c_id_subtype
== ochassis
->c_id_subtype
) &&
532 (chassis
->c_id_len
== ochassis
->c_id_len
) &&
533 (memcmp(chassis
->c_id
, ochassis
->c_id
,
534 chassis
->c_id_len
) == 0))
540 /* The port is known, remove it before adding it back */
541 TAILQ_REMOVE(&hardware
->h_rports
, oport
, p_entries
);
542 lldpd_port_cleanup(oport
, 1);
546 lldpd_move_chassis(ochassis
, chassis
);
549 /* Chassis not known, add it */
550 log_debug("decode", "unknown chassis, add it to the list");
551 chassis
->c_index
= ++cfg
->g_lastrid
;
552 chassis
->c_refcount
= 0;
553 TAILQ_INSERT_TAIL(&cfg
->g_chassis
, chassis
, c_entries
);
554 i
= 0; TAILQ_FOREACH(ochassis
, &cfg
->g_chassis
, c_entries
) i
++;
555 log_debug("decode", "%d different systems are known", i
);
558 port
->p_lastchange
= port
->p_lastupdate
= time(NULL
);
559 if ((port
->p_lastframe
= (struct lldpd_frame
*)malloc(s
+
560 sizeof(struct lldpd_frame
))) != NULL
) {
561 port
->p_lastframe
->size
= s
;
562 memcpy(port
->p_lastframe
->frame
, frame
, s
);
564 TAILQ_INSERT_TAIL(&hardware
->h_rports
, port
, p_entries
);
565 port
->p_chassis
= chassis
;
566 port
->p_chassis
->c_refcount
++;
567 /* Several cases are possible :
568 1. chassis is new, its refcount was 0. It is now attached
569 to this port, its refcount is 1.
570 2. chassis already exists and was attached to another
571 port, we increase its refcount accordingly.
572 3. chassis already exists and was attached to the same
573 port, its refcount was decreased with
574 lldpd_port_cleanup() and is now increased again.
576 In all cases, if the port already existed, it has been
577 freed with lldpd_port_cleanup() and therefore, the refcount
578 of the chassis that was attached to it is decreased.
580 i
= 0; TAILQ_FOREACH(aport
, &hardware
->h_rports
, p_entries
)
582 log_debug("decode", "%d neighbors for %s", i
,
585 if (!oport
) hardware
->h_insert_cnt
++;
588 log_debug("decode", "send notifications for changes on %s",
591 TRACE(LLDPD_NEIGHBOR_UPDATE(hardware
->h_ifname
,
595 levent_ctl_notify(hardware
->h_ifname
, NEIGHBOR_CHANGE_UPDATED
, port
);
597 agent_notify(hardware
, NEIGHBOR_CHANGE_UPDATED
, port
);
600 TRACE(LLDPD_NEIGHBOR_NEW(hardware
->h_ifname
,
604 levent_ctl_notify(hardware
->h_ifname
, NEIGHBOR_CHANGE_ADDED
, port
);
606 agent_notify(hardware
, NEIGHBOR_CHANGE_ADDED
, port
);
610 #ifdef ENABLE_LLDPMED
611 if (!oport
&& port
->p_chassis
->c_med_type
) {
612 /* New neighbor, fast start */
613 if (hardware
->h_cfg
->g_config
.c_enable_fast_start
&&
614 !hardware
->h_tx_fast
) {
615 log_debug("decode", "%s: entering fast start due to "
616 "new neighbor", hardware
->h_ifname
);
617 hardware
->h_tx_fast
= hardware
->h_cfg
->g_config
.c_tx_fast_init
;
620 levent_schedule_pdu(hardware
);
627 /* Get the output of lsb_release -s -d. This is a slow function. It should be
628 called once. It return NULL if any problem happens. Otherwise, this is a
629 statically allocated buffer. The result includes the trailing \n */
631 lldpd_get_lsb_release() {
632 static char release
[1024];
633 char *const command
[] = { "lsb_release", "-s", "-d", NULL
};
634 int pid
, status
, devnull
, count
;
637 log_debug("localchassis", "grab LSB release");
640 log_warn("localchassis", "unable to get a pair of pipes");
644 if ((pid
= fork()) < 0) {
645 log_warn("localchassis", "unable to fork");
650 /* Child, exec lsb_release */
652 if ((devnull
= open("/dev/null", O_RDWR
, 0)) != -1) {
653 dup2(devnull
, STDIN_FILENO
);
654 dup2(devnull
, STDERR_FILENO
);
655 dup2(pipefd
[1], STDOUT_FILENO
);
656 if (devnull
> 2) close(devnull
);
657 if (pipefd
[1] > 2) close(pipefd
[1]);
658 execvp("lsb_release", command
);
663 /* Father, read the output from the children */
667 status
= read(pipefd
[0], release
+count
, sizeof(release
)-count
);
668 if ((status
== -1) && (errno
== EINTR
)) continue;
671 } while (count
< sizeof(release
) && (status
> 0));
673 log_info("localchassis", "unable to read from lsb_release");
675 waitpid(pid
, &status
, 0);
679 if (count
>= sizeof(release
)) {
680 log_info("localchassis", "output of lsb_release is too large");
681 waitpid(pid
, &status
, 0);
685 if (waitpid(pid
, &status
, 0) != pid
)
687 if (!WIFEXITED(status
) || (WEXITSTATUS(status
) != 0)) {
688 log_info("localchassis", "lsb_release information not available");
692 log_info("localchassis", "lsb_release returned an empty string");
695 release
[count
] = '\0';
698 /* Should not be here */
702 /* Same like lldpd_get_lsb_release but reads /etc/os-release for PRETTY_NAME=. */
704 lldpd_get_os_release() {
705 static char release
[1024];
708 char *ptr1
= release
;
710 FILE *fp
= fopen("/etc/os-release", "r");
711 log_debug("localchassis", "grab OS release");
713 log_info("localchassis", "could not open /etc/os-release");
717 while ((fgets(line
, 1024, fp
) != NULL
)) {
718 key
= strtok(line
, "=");
719 val
= strtok(NULL
, "=");
721 if (strncmp(key
, "PRETTY_NAME", 1024) == 0) {
722 strncpy(release
, val
, 1024);
728 /* Remove trailing newline and all " in the string. */
729 ptr1
= release
+ strlen(release
) - 1;
730 while (ptr1
!= release
&&
731 ((*ptr1
== '"') || (*ptr1
== '\n'))) {
735 if (release
[0] == '"')
741 lldpd_hide_ports(struct lldpd
*cfg
, struct lldpd_hardware
*hardware
, int mask
) {
742 struct lldpd_port
*port
;
743 int protocols
[LLDPD_MODE_MAX
+1];
748 log_debug("smartfilter", "apply smart filter for port %s",
751 /* Compute the number of occurrences of each protocol */
752 for (i
= 0; i
<= LLDPD_MODE_MAX
; i
++) protocols
[i
] = 0;
753 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
)
754 protocols
[port
->p_protocol
]++;
756 /* Turn the protocols[] array into an array of
757 enabled/disabled protocols. 1 means enabled, 0
759 min
= (unsigned int)-1;
760 for (i
= 0; i
<= LLDPD_MODE_MAX
; i
++)
761 if (protocols
[i
] && (protocols
[i
] < min
))
764 for (i
= 0; i
<= LLDPD_MODE_MAX
; i
++)
765 if ((protocols
[i
] == min
) && !found
) {
766 /* If we need a tie breaker, we take
767 the first protocol only */
768 if (cfg
->g_config
.c_smart
& mask
&
769 (SMART_OUTGOING_ONE_PROTO
| SMART_INCOMING_ONE_PROTO
))
772 } else protocols
[i
] = 0;
774 /* We set the p_hidden flag to 1 if the protocol is disabled */
775 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
776 if (mask
== SMART_OUTGOING
)
777 port
->p_hidden_out
= protocols
[port
->p_protocol
]?0:1;
779 port
->p_hidden_in
= protocols
[port
->p_protocol
]?0:1;
782 /* If we want only one neighbor, we take the first one */
783 if (cfg
->g_config
.c_smart
& mask
&
784 (SMART_OUTGOING_ONE_NEIGH
| SMART_INCOMING_ONE_NEIGH
)) {
786 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
787 if (mask
== SMART_OUTGOING
) {
788 if (found
) port
->p_hidden_out
= 1;
789 if (!port
->p_hidden_out
)
792 if (mask
== SMART_INCOMING
) {
793 if (found
) port
->p_hidden_in
= 1;
794 if (!port
->p_hidden_in
)
800 /* Print a debug message summarizing the operation */
801 for (i
= 0; i
<= LLDPD_MODE_MAX
; i
++) protocols
[i
] = 0;
803 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
804 if (!(((mask
== SMART_OUTGOING
) && port
->p_hidden_out
) ||
805 ((mask
== SMART_INCOMING
) && port
->p_hidden_in
))) {
807 protocols
[port
->p_protocol
] = 1;
812 for (i
=0; cfg
->g_protocols
[i
].mode
!= 0; i
++) {
813 if (cfg
->g_protocols
[i
].enabled
&& protocols
[cfg
->g_protocols
[i
].mode
]) {
815 strlen(cfg
->g_protocols
[i
].name
) + 3 > sizeof(buffer
)) {
816 /* Unlikely, our buffer is too small */
817 memcpy(buffer
+ sizeof(buffer
) - 4, "...", 4);
821 strncat(buffer
, ", ", 2);
822 strncat(buffer
, cfg
->g_protocols
[i
].name
, strlen(cfg
->g_protocols
[i
].name
));
825 log_debug("smartfilter", "%s: %s: %d visible neighbors (out of %d)",
827 (mask
== SMART_OUTGOING
)?"out filter":"in filter",
829 log_debug("smartfilter", "%s: protocols: %s",
830 hardware
->h_ifname
, buffer
[0]?buffer
:"(none)");
833 /* Hide unwanted ports depending on smart mode set by the user */
835 lldpd_hide_all(struct lldpd
*cfg
)
837 struct lldpd_hardware
*hardware
;
839 if (!cfg
->g_config
.c_smart
)
841 log_debug("smartfilter", "apply smart filter results on all ports");
842 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
) {
843 if (cfg
->g_config
.c_smart
& SMART_INCOMING_FILTER
)
844 lldpd_hide_ports(cfg
, hardware
, SMART_INCOMING
);
845 if (cfg
->g_config
.c_smart
& SMART_OUTGOING_FILTER
)
846 lldpd_hide_ports(cfg
, hardware
, SMART_OUTGOING
);
851 lldpd_recv(struct lldpd
*cfg
, struct lldpd_hardware
*hardware
, int fd
)
855 log_debug("receive", "receive a frame on %s",
857 if ((buffer
= (char *)malloc(hardware
->h_mtu
)) == NULL
) {
858 log_warn("receive", "failed to alloc reception buffer");
861 if ((n
= hardware
->h_ops
->recv(cfg
, hardware
,
863 hardware
->h_mtu
)) == -1) {
864 log_debug("receive", "discard frame received on %s",
869 if (cfg
->g_config
.c_paused
) {
870 log_debug("receive", "paused, ignore the frame on %s",
875 hardware
->h_rx_cnt
++;
876 log_debug("receive", "decode received frame on %s",
878 TRACE(LLDPD_FRAME_RECEIVED(hardware
->h_ifname
, buffer
, (size_t)n
));
879 lldpd_decode(cfg
, buffer
, n
, hardware
);
880 lldpd_hide_all(cfg
); /* Immediatly hide */
881 lldpd_count_neighbors(cfg
);
886 lldpd_send(struct lldpd_hardware
*hardware
)
888 struct lldpd
*cfg
= hardware
->h_cfg
;
889 struct lldpd_port
*port
;
892 if (cfg
->g_config
.c_receiveonly
|| cfg
->g_config
.c_paused
) return;
893 if ((hardware
->h_flags
& IFF_RUNNING
) == 0)
896 log_debug("send", "send PDU on %s", hardware
->h_ifname
);
898 for (i
=0; cfg
->g_protocols
[i
].mode
!= 0; i
++) {
899 if (!cfg
->g_protocols
[i
].enabled
)
901 /* We send only if we have at least one remote system
902 * speaking this protocol or if the protocol is forced */
903 if (cfg
->g_protocols
[i
].enabled
> 1) {
904 cfg
->g_protocols
[i
].send(cfg
, hardware
);
908 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
909 /* If this remote port is disabled, we don't
911 if (port
->p_hidden_out
)
913 if (port
->p_protocol
==
914 cfg
->g_protocols
[i
].mode
) {
915 TRACE(LLDPD_FRAME_SEND(hardware
->h_ifname
,
916 cfg
->g_protocols
[i
].name
));
917 log_debug("send", "send PDU on %s with protocol %s",
919 cfg
->g_protocols
[i
].name
);
920 cfg
->g_protocols
[i
].send(cfg
,
929 /* Nothing was sent for this port, let's speak the first
930 * available protocol. */
931 for (i
= 0; cfg
->g_protocols
[i
].mode
!= 0; i
++) {
932 if (!cfg
->g_protocols
[i
].enabled
) continue;
933 TRACE(LLDPD_FRAME_SEND(hardware
->h_ifname
,
934 cfg
->g_protocols
[i
].name
));
935 log_debug("send", "fallback to protocol %s for %s",
936 cfg
->g_protocols
[i
].name
, hardware
->h_ifname
);
937 cfg
->g_protocols
[i
].send(cfg
,
941 if (cfg
->g_protocols
[i
].mode
== 0)
942 log_warnx("send", "no protocol enabled, dunno what to send");
946 #ifdef ENABLE_LLDPMED
948 lldpd_med(struct lldpd_chassis
*chassis
)
950 static short int once
= 0;
952 chassis
->c_med_hw
= dmi_hw();
953 chassis
->c_med_fw
= dmi_fw();
954 chassis
->c_med_sn
= dmi_sn();
955 chassis
->c_med_manuf
= dmi_manuf();
956 chassis
->c_med_model
= dmi_model();
957 chassis
->c_med_asset
= dmi_asset();
964 lldpd_routing_enabled(struct lldpd
*cfg
)
967 if ((routing
= interfaces_routing_enabled(cfg
)) == -1) {
968 log_debug("localchassis", "unable to check if routing is enabled");
975 lldpd_update_localchassis(struct lldpd
*cfg
)
980 log_debug("localchassis", "update information for local chassis");
981 assert(LOCAL_CHASSIS(cfg
) != NULL
);
983 /* Set system name and description */
985 fatal("localchassis", "failed to get system information");
986 if ((hp
= priv_gethostbyname()) == NULL
)
987 fatal("localchassis", "failed to get system name");
988 free(LOCAL_CHASSIS(cfg
)->c_name
);
989 free(LOCAL_CHASSIS(cfg
)->c_descr
);
990 if ((LOCAL_CHASSIS(cfg
)->c_name
= strdup(hp
)) == NULL
)
991 fatal("localchassis", NULL
);
992 if (cfg
->g_config
.c_description
) {
993 log_debug("localchassis", "use overridden description `%s`", cfg
->g_config
.c_description
);
994 if (asprintf(&LOCAL_CHASSIS(cfg
)->c_descr
, "%s",
995 cfg
->g_config
.c_description
) == -1)
996 fatal("localchassis", "failed to set full system description");
998 if (cfg
->g_config
.c_advertise_version
) {
999 log_debug("localchassis", "advertise system version");
1000 if (asprintf(&LOCAL_CHASSIS(cfg
)->c_descr
, "%s %s %s %s %s",
1001 cfg
->g_lsb_release
?cfg
->g_lsb_release
:"",
1002 un
.sysname
, un
.release
, un
.version
, un
.machine
)
1004 fatal("localchassis", "failed to set full system description");
1006 log_debug("localchassis", "do not advertise system version");
1007 if (asprintf(&LOCAL_CHASSIS(cfg
)->c_descr
, "%s",
1008 cfg
->g_lsb_release
?cfg
->g_lsb_release
:un
.sysname
) == -1)
1009 fatal("localchassis", "failed to set minimal system description");
1014 if (lldpd_routing_enabled(cfg
)) {
1015 log_debug("localchassis", "routing is enabled, enable router capability");
1016 LOCAL_CHASSIS(cfg
)->c_cap_enabled
|= LLDP_CAP_ROUTER
;
1018 LOCAL_CHASSIS(cfg
)->c_cap_enabled
&= ~LLDP_CAP_ROUTER
;
1020 #ifdef ENABLE_LLDPMED
1021 if (LOCAL_CHASSIS(cfg
)->c_cap_available
& LLDP_CAP_TELEPHONE
)
1022 LOCAL_CHASSIS(cfg
)->c_cap_enabled
|= LLDP_CAP_TELEPHONE
;
1023 lldpd_med(LOCAL_CHASSIS(cfg
));
1024 free(LOCAL_CHASSIS(cfg
)->c_med_sw
);
1025 if (cfg
->g_config
.c_advertise_version
)
1026 LOCAL_CHASSIS(cfg
)->c_med_sw
= strdup(un
.release
);
1028 LOCAL_CHASSIS(cfg
)->c_med_sw
= strdup("Unknown");
1031 /* Set chassis ID if needed. This is only done if chassis ID
1032 has not been set previously (with the MAC address of an
1033 interface for example)
1035 if (LOCAL_CHASSIS(cfg
)->c_id
== NULL
) {
1036 log_debug("localchassis", "no chassis ID is currently set, use chassis name");
1037 if (!(LOCAL_CHASSIS(cfg
)->c_id
= strdup(LOCAL_CHASSIS(cfg
)->c_name
)))
1038 fatal("localchassis", NULL
);
1039 LOCAL_CHASSIS(cfg
)->c_id_len
= strlen(LOCAL_CHASSIS(cfg
)->c_name
);
1040 LOCAL_CHASSIS(cfg
)->c_id_subtype
= LLDP_CHASSISID_SUBTYPE_LOCAL
;
1045 lldpd_update_localports(struct lldpd
*cfg
)
1047 struct lldpd_hardware
*hardware
;
1049 log_debug("localchassis", "update information for local ports");
1051 /* h_flags is set to 0 for each port. If the port is updated, h_flags
1052 * will be set to a non-zero value. This will allow us to clean up any
1053 * non up-to-date port */
1054 TAILQ_FOREACH(hardware
, &cfg
->g_hardware
, h_entries
)
1055 hardware
->h_flags
= 0;
1057 TRACE(LLDPD_INTERFACES_UPDATE());
1058 interfaces_update(cfg
);
1060 lldpd_reset_timer(cfg
);
1064 lldpd_loop(struct lldpd
*cfg
)
1067 1. Update local ports information
1068 2. Update local chassis information
1070 log_debug("loop", "start new loop");
1071 LOCAL_CHASSIS(cfg
)->c_cap_enabled
= 0;
1072 /* Information for local ports is triggered even when it is possible to
1073 * update them on some other event because we want to refresh them if we
1074 * missed something. */
1075 log_debug("loop", "update information for local ports");
1076 lldpd_update_localports(cfg
);
1077 log_debug("loop", "update information for local chassis");
1078 lldpd_update_localchassis(cfg
);
1079 lldpd_count_neighbors(cfg
);
1083 lldpd_exit(struct lldpd
*cfg
)
1085 struct lldpd_hardware
*hardware
, *hardware_next
;
1086 log_debug("main", "exit lldpd");
1088 priv_ctl_cleanup(cfg
->g_ctlname
);
1089 log_debug("main", "cleanup hardware information");
1090 for (hardware
= TAILQ_FIRST(&cfg
->g_hardware
); hardware
!= NULL
;
1091 hardware
= hardware_next
) {
1092 hardware_next
= TAILQ_NEXT(hardware
, h_entries
);
1093 log_debug("main", "cleanup interface %s", hardware
->h_ifname
);
1094 lldpd_remote_cleanup(hardware
, NULL
, 1);
1095 lldpd_hardware_cleanup(cfg
, hardware
);
1100 * Run lldpcli to configure lldpd.
1102 * @return PID of running lldpcli or -1 if error.
1105 lldpd_configure(int debug
, const char *path
)
1107 pid_t lldpcli
= fork();
1112 log_warn("main", "unable to fork");
1115 /* Child, exec lldpcli */
1116 if ((devnull
= open("/dev/null", O_RDWR
, 0)) != -1) {
1117 char sdebug
[debug
+ 3];
1118 memset(sdebug
, 'd', debug
+ 3);
1119 sdebug
[debug
+ 2] = '\0';
1120 sdebug
[0] = '-'; sdebug
[1] = 's';
1122 dup2(devnull
, STDIN_FILENO
);
1123 dup2(devnull
, STDOUT_FILENO
);
1124 if (devnull
> 2) close(devnull
);
1126 log_debug("main", "invoke %s %s", path
, sdebug
);
1127 if (execl(path
, "lldpcli", sdebug
,
1128 "-c", SYSCONFDIR
"/lldpd.conf",
1129 "-c", SYSCONFDIR
"/lldpd.d",
1132 log_warn("main", "unable to execute %s", path
);
1133 log_warnx("main", "configuration is incomplete, lldpd needs to be unpaused");
1139 /* Father, don't do anything stupid */
1142 /* Should not be here */
1146 struct intint
{ int a
; int b
; };
1147 static const struct intint filters
[] = {
1149 { 1, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
|
1150 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_PROTO
},
1151 { 2, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
},
1152 { 3, SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_PROTO
},
1153 { 4, SMART_INCOMING_FILTER
| SMART_OUTGOING_FILTER
},
1154 { 5, SMART_INCOMING_FILTER
},
1155 { 6, SMART_OUTGOING_FILTER
},
1156 { 7, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
| SMART_INCOMING_ONE_NEIGH
|
1157 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_PROTO
},
1158 { 8, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
| SMART_INCOMING_ONE_NEIGH
},
1159 { 9, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_NEIGH
|
1160 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_PROTO
},
1161 { 10, SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_NEIGH
},
1162 { 11, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_NEIGH
},
1163 { 12, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_NEIGH
|
1164 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_NEIGH
},
1165 { 13, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_NEIGH
|
1166 SMART_OUTGOING_FILTER
},
1167 { 14, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
|
1168 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_NEIGH
},
1169 { 15, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
|
1170 SMART_OUTGOING_FILTER
},
1171 { 16, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
| SMART_INCOMING_ONE_NEIGH
|
1172 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_NEIGH
},
1173 { 17, SMART_INCOMING_FILTER
| SMART_INCOMING_ONE_PROTO
| SMART_INCOMING_ONE_NEIGH
|
1174 SMART_OUTGOING_FILTER
},
1175 { 18, SMART_INCOMING_FILTER
|
1176 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_NEIGH
},
1177 { 19, SMART_INCOMING_FILTER
|
1178 SMART_OUTGOING_FILTER
| SMART_OUTGOING_ONE_PROTO
},
1184 * Tell if we have been started by upstart.
1187 lldpd_started_by_upstart()
1189 #ifdef HOST_OS_LINUX
1190 const char *upstartjob
= getenv("UPSTART_JOB");
1191 if (!(upstartjob
&& !strcmp(upstartjob
, "lldpd")))
1193 log_debug("main", "running with upstart, don't fork but stop");
1202 * Tell if we have been started by systemd.
1205 lldpd_started_by_systemd()
1207 #ifdef HOST_OS_LINUX
1209 const char *notifysocket
= getenv("NOTIFY_SOCKET");
1210 if (!notifysocket
||
1211 !strchr("@/", notifysocket
[0]) ||
1212 strlen(notifysocket
) < 2)
1215 log_debug("main", "running with systemd, don't fork but signal ready");
1216 if ((fd
= socket(AF_UNIX
, SOCK_DGRAM
, 0)) < 0) {
1217 log_warn("main", "unable to open systemd notification socket %s",
1222 struct sockaddr_un su
= { .sun_family
= AF_UNIX
};
1223 strlcpy(su
.sun_path
, notifysocket
, sizeof(su
.sun_path
));
1224 if (notifysocket
[0] == '@') su
.sun_path
[0] = 0;
1226 struct iovec iov
= {
1227 .iov_base
= "READY=1",
1228 .iov_len
= strlen("READY=1")
1230 struct msghdr hdr
= {
1232 .msg_namelen
= offsetof(struct sockaddr_un
, sun_path
) + strlen(notifysocket
),
1236 if (sendmsg(fd
, &hdr
, MSG_NOSIGNAL
) < 0) {
1237 log_warn("main", "unable to send notification to systemd");
1250 lldpd_main(int argc
, char *argv
[], char *envp
[])
1253 struct lldpd_chassis
*lchassis
;
1257 char *agentx
= NULL
; /* AgentX socket */
1259 char *ctlname
= LLDPD_CTL_SOCKET
;
1262 char *interfaces
= NULL
;
1263 char *popt
, opts
[] =
1264 "H:vhkrdD:xX:m:u:4:6:I:C:p:M:P:S:iL:@ ";
1265 int i
, found
, advertise_version
= 1;
1266 #ifdef ENABLE_LLDPMED
1267 int lldpmed
= 0, noinventory
= 0;
1268 int enable_fast_start
= 1;
1270 char *descr_override
= NULL
;
1271 char *platform_override
= NULL
;
1272 char *lsb_release
= NULL
;
1273 const char *lldpcli
= LLDPCLI_PATH
;
1275 int receiveonly
= 0;
1278 /* Non privileged user */
1279 struct passwd
*user
;
1280 struct group
*group
;
1286 #if HAVE_SETPROCTITLE_INIT
1287 setproctitle_init(argc
, argv
, envp
);
1291 * Get and parse command line options
1293 popt
= strchr(opts
, '@');
1294 for (i
=0; protos
[i
].mode
!= 0; i
++)
1295 *(popt
++) = protos
[i
].arg
;
1297 while ((ch
= getopt(argc
, argv
, opts
)) != -1) {
1303 fprintf(stdout
, "%s\n", PACKAGE_VERSION
);
1322 interfaces
= optarg
;
1328 if (strlen(optarg
)) lldpcli
= optarg
;
1329 else lldpcli
= NULL
;
1331 advertise_version
= 0;
1333 #ifdef ENABLE_LLDPMED
1335 lldpmed
= atoi(optarg
);
1336 if ((lldpmed
< 1) || (lldpmed
> 4)) {
1337 fprintf(stderr
, "-M requires an argument between 1 and 4\n");
1347 fprintf(stderr
, "LLDP-MED support is not built-in\n");
1362 fprintf(stderr
, "SNMP support is not built-in\n");
1367 descr_override
= strdup(optarg
);
1370 platform_override
= strdup(optarg
);
1373 smart
= atoi(optarg
);
1377 for (i
=0; protos
[i
].mode
!= 0; i
++) {
1378 if (ch
== protos
[i
].arg
) {
1379 if (protos
[i
].enabled
< 3) {
1381 if (protos
[i
].enabled
++ == 1)
1391 /* Set correct smart mode */
1392 for (i
=0; (filters
[i
].a
!= -1) && (filters
[i
].a
!= smart
); i
++);
1393 if (filters
[i
].a
== -1) {
1394 fprintf(stderr
, "Incorrect mode for -H\n");
1397 smart
= filters
[i
].b
;
1399 log_init(debug
, __progname
);
1400 tzset(); /* Get timezone info before chroot */
1402 log_debug("main", "lldpd starting...");
1404 /* Grab uid and gid to use for priv sep */
1405 if ((user
= getpwnam(PRIVSEP_USER
)) == NULL
)
1406 fatal("main", "no " PRIVSEP_USER
" user for privilege separation");
1408 if ((group
= getgrnam(PRIVSEP_GROUP
)) == NULL
)
1409 fatal("main", "no " PRIVSEP_GROUP
" group for privilege separation");
1410 gid
= group
->gr_gid
;
1412 /* Create and setup socket */
1414 log_debug("main", "creating control socket");
1415 while ((ctl
= ctl_create(ctlname
)) == -1) {
1416 if (retry
-- && errno
== EADDRINUSE
) {
1417 /* Check if a daemon is really listening */
1419 log_info("main", "unable to create control socket because it already exists");
1420 log_info("main", "check if another instance is running");
1421 if ((tfd
= ctl_connect(ctlname
)) != -1) {
1422 /* Another instance is running */
1424 log_warnx("main", "another instance is running, please stop it");
1425 fatalx("giving up");
1426 } else if (errno
== ECONNREFUSED
) {
1427 /* Nobody is listening */
1428 log_info("main", "old control socket is present, clean it");
1429 ctl_cleanup(ctlname
);
1432 log_warn("main", "cannot determine if another daemon is already running");
1433 fatalx("giving up");
1435 log_warn("main", "unable to create control socket");
1436 fatalx("giving up");
1438 if (chown(ctlname
, uid
, gid
) == -1)
1439 log_warn("main", "unable to chown control socket");
1441 S_IRUSR
| S_IWUSR
| S_IXUSR
|
1442 S_IRGRP
| S_IWGRP
| S_IXGRP
) == -1)
1443 log_warn("main", "unable to chmod control socket");
1445 /* Disable SIGPIPE */
1446 signal(SIGPIPE
, SIG_IGN
);
1448 /* Configuration with lldpcli */
1450 log_debug("main", "invoking lldpcli for configuration");
1451 if (lldpd_configure(debug
, lldpcli
) == -1)
1452 fatal("main", "unable to spawn lldpcli");
1455 /* Daemonization, unless started by upstart, systemd or launchd or debug */
1457 if (!lldpd_started_by_upstart() && !lldpd_started_by_systemd() &&
1461 log_debug("main", "daemonize");
1462 if (daemon(0, 0) != 0)
1463 fatal("main", "failed to detach daemon");
1464 if ((pid
= open(LLDPD_PID_FILE
,
1465 O_TRUNC
| O_CREAT
| O_WRONLY
, 0644)) == -1)
1466 fatal("main", "unable to open pid file " LLDPD_PID_FILE
);
1467 if (asprintf(&spid
, "%d\n", getpid()) == -1)
1468 fatal("main", "unable to create pid file " LLDPD_PID_FILE
);
1469 if (write(pid
, spid
, strlen(spid
)) == -1)
1470 fatal("main", "unable to write pid file " LLDPD_PID_FILE
);
1476 /* Try to read system information from /etc/os-release if possible.
1477 Fall back to lsb_release for compatibility. */
1478 log_debug("main", "get OS/LSB release information");
1479 lsb_release
= lldpd_get_os_release();
1481 lsb_release
= lldpd_get_lsb_release();
1484 log_debug("main", "initialize privilege separation");
1485 priv_init(PRIVSEP_CHROOT
, ctl
, uid
, gid
);
1487 /* Initialization of global configuration */
1488 if ((cfg
= (struct lldpd
*)
1489 calloc(1, sizeof(struct lldpd
))) == NULL
)
1490 fatal("main", NULL
);
1492 cfg
->g_ctlname
= ctlname
;
1494 cfg
->g_config
.c_mgmt_pattern
= mgmtp
;
1495 cfg
->g_config
.c_cid_pattern
= cidp
;
1496 cfg
->g_config
.c_iface_pattern
= interfaces
;
1497 cfg
->g_config
.c_smart
= smart
;
1499 cfg
->g_config
.c_paused
= 1;
1500 cfg
->g_config
.c_receiveonly
= receiveonly
;
1501 cfg
->g_config
.c_tx_interval
= LLDPD_TX_INTERVAL
;
1502 cfg
->g_config
.c_tx_hold
= LLDPD_TX_HOLD
;
1503 cfg
->g_config
.c_max_neighbors
= LLDPD_MAX_NEIGHBORS
;
1504 #ifdef ENABLE_LLDPMED
1505 cfg
->g_config
.c_enable_fast_start
= enable_fast_start
;
1506 cfg
->g_config
.c_tx_fast_init
= LLDPD_FAST_INIT
;
1507 cfg
->g_config
.c_tx_fast_interval
= LLDPD_FAST_TX_INTERVAL
;
1511 cfg
->g_snmp_agentx
= agentx
;
1512 #endif /* USE_SNMP */
1513 cfg
->g_config
.c_bond_slave_src_mac_type
= \
1514 LLDP_BOND_SLAVE_SRC_MAC_TYPE_FIXED
;
1516 /* Get ioctl socket */
1517 log_debug("main", "get an ioctl socket");
1518 if ((cfg
->g_sock
= socket(AF_INET
, SOCK_DGRAM
, 0)) == -1)
1519 fatal("main", "failed to get ioctl socket");
1522 if (!(cfg
->g_config
.c_advertise_version
= advertise_version
) &&
1523 lsb_release
&& lsb_release
[strlen(lsb_release
) - 1] == '\n')
1524 lsb_release
[strlen(lsb_release
) - 1] = '\0';
1525 cfg
->g_lsb_release
= lsb_release
;
1527 cfg
->g_config
.c_description
= descr_override
;
1529 if (platform_override
)
1530 cfg
->g_config
.c_platform
= platform_override
;
1532 /* Set system capabilities */
1533 log_debug("main", "set system capabilities");
1534 if ((lchassis
= (struct lldpd_chassis
*)
1535 calloc(1, sizeof(struct lldpd_chassis
))) == NULL
)
1536 fatal("localchassis", NULL
);
1537 lchassis
->c_cap_available
= LLDP_CAP_BRIDGE
| LLDP_CAP_WLAN
|
1539 TAILQ_INIT(&lchassis
->c_mgmt
);
1540 #ifdef ENABLE_LLDPMED
1542 if (lldpmed
== LLDP_MED_CLASS_III
)
1543 lchassis
->c_cap_available
|= LLDP_CAP_TELEPHONE
;
1544 lchassis
->c_med_type
= lldpmed
;
1545 lchassis
->c_med_cap_available
= LLDP_MED_CAP_CAP
|
1546 LLDP_MED_CAP_IV
| LLDP_MED_CAP_LOCATION
|
1547 LLDP_MED_CAP_POLICY
| LLDP_MED_CAP_MDI_PSE
| LLDP_MED_CAP_MDI_PD
;
1548 cfg
->g_config
.c_noinventory
= noinventory
;
1550 cfg
->g_config
.c_noinventory
= 1;
1554 lchassis
->c_ttl
= cfg
->g_config
.c_tx_interval
* cfg
->g_config
.c_tx_hold
;
1556 log_debug("main", "initialize protocols");
1557 cfg
->g_protocols
= protos
;
1558 for (i
=0; protos
[i
].mode
!= 0; i
++)
1559 if (protos
[i
].enabled
> 1)
1560 log_info("main", "protocol %s enabled and forced", protos
[i
].name
);
1561 else if (protos
[i
].enabled
)
1562 log_info("main", "protocol %s enabled", protos
[i
].name
);
1564 log_info("main", "protocol %s disabled", protos
[i
].name
);
1566 TAILQ_INIT(&cfg
->g_hardware
);
1567 TAILQ_INIT(&cfg
->g_chassis
);
1568 TAILQ_INSERT_TAIL(&cfg
->g_chassis
, lchassis
, c_entries
);
1569 lchassis
->c_refcount
++; /* We should always keep a reference to local chassis */
1572 log_debug("main", "start main loop");