]> git.ipfire.org Git - thirdparty/lldpd.git/blame - src/daemon/lldpd.h
build: use version sort for changelog
[thirdparty/lldpd.git] / src / daemon / lldpd.h
CommitLineData
4b292b55
VB
1/* -*- mode: c; c-file-style: "openbsd" -*- */
2/*
3 * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef _LLDPD_H
19#define _LLDPD_H
20
21#if HAVE_CONFIG_H
22# include <config.h>
23#endif
24
25#ifdef HAVE_VALGRIND_VALGRIND_H
26# include <valgrind/valgrind.h>
27#else
28# define RUNNING_ON_VALGRIND 0
29#endif
30
4b292b55
VB
31#include <stdlib.h>
32#include <stddef.h>
33#include <string.h>
34#include <sys/queue.h>
e12c2365 35#include <sys/types.h>
690b944c 36#include <netinet/if_ether.h>
4b292b55 37#include <netinet/in.h>
4b292b55
VB
38#include <sys/un.h>
39
45bf0bd0
VB
40#if HAVE_VFORK_H
41# include <vfork.h>
42#endif
43#if HAVE_WORKING_FORK
44# define vfork fork
45#endif
46
4b292b55
VB
47#include "lldp-tlv.h"
48#if defined (ENABLE_CDP) || defined (ENABLE_FDP)
49# include "cdp.h"
50#endif
51#ifdef ENABLE_SONMP
52# include "sonmp.h"
53#endif
54#ifdef ENABLE_EDP
55# include "edp.h"
56#endif
57
58#include "../compat/compat.h"
59#include "../marshal.h"
60#include "../log.h"
61#include "../ctl.h"
62#include "../lldpd-structs.h"
63
64/* We don't want to import event2/event.h. We only need those as
65 opaque structs. */
66struct event;
67struct event_base;
68
69#define SYSFS_CLASS_NET "/sys/class/net/"
70#define SYSFS_CLASS_DMI "/sys/class/dmi/id/"
8843f168 71#define LLDPD_TX_INTERVAL 30
c10302a3 72#define LLDPD_TX_HOLD 4
73#define LLDPD_TTL LLDPD_TX_INTERVAL * LLDPD_TX_HOLD
4b292b55 74#define LLDPD_TX_MSGDELAY 1
42589660 75#define LLDPD_MAX_NEIGHBORS 4
b9de0ca6 76#define LLDPD_FAST_TX_INTERVAL 1
77#define LLDPD_FAST_INIT 4
4b292b55
VB
78
79#define USING_AGENTX_SUBAGENT_MODULE 1
80
81#define PROTO_SEND_SIG struct lldpd *, struct lldpd_hardware *
82#define PROTO_DECODE_SIG struct lldpd *, char *, int, struct lldpd_hardware *, struct lldpd_chassis **, struct lldpd_port **
83#define PROTO_GUESS_SIG char *, int
84
3d596bbe
VB
85#define ALIGNED_CAST(TYPE, ATTR) ((TYPE) (void *) (ATTR))
86
4b292b55
VB
87struct protocol {
88 int mode; /* > 0 mode identifier (unique per protocol) */
89 int enabled; /* Is this protocol enabled? */
90 char *name; /* Name of protocol */
91 char arg; /* Argument to enable this protocol */
92 int(*send)(PROTO_SEND_SIG); /* How to send a frame */
93 int(*decode)(PROTO_DECODE_SIG); /* How to decode a frame */
94 int(*guess)(PROTO_GUESS_SIG); /* Can be NULL, use MAC address in this case */
4e5f34c5 95 u_int8_t mac[ETHER_ADDR_LEN]; /* Destination MAC address used by this protocol */
4b292b55
VB
96};
97
4b292b55
VB
98#define SMART_HIDDEN(port) (port->p_hidden_in)
99
100struct lldpd {
101 int g_sock;
4b292b55
VB
102 struct event_base *g_base;
103#ifdef USE_SNMP
104#endif
105
8ec333bd
VB
106 struct lldpd_config g_config;
107
4b292b55 108 struct protocol *g_protocols;
4b292b55 109 int g_lastrid;
4b292b55 110 struct event *g_main_loop;
3333d2a8 111 struct event *g_cleanup_timer;
4b292b55
VB
112#ifdef USE_SNMP
113 int g_snmp;
114 struct event *g_snmp_timeout;
115 void *g_snmp_fds;
abc04205 116 const char *g_snmp_agentx;
4b292b55
VB
117#endif /* USE_SNMP */
118
119 /* Unix socket handling */
0262adbb 120 const char *g_ctlname;
4b292b55
VB
121 int g_ctl;
122 struct event *g_ctl_event;
0484f180
VB
123 struct event *g_iface_event; /* Triggered when there is an interface change */
124 struct event *g_iface_timer_event; /* Triggered one second after last interface change */
4b292b55 125
4b292b55 126 char *g_lsb_release;
4b292b55
VB
127
128#define LOCAL_CHASSIS(cfg) ((struct lldpd_chassis *)(TAILQ_FIRST(&cfg->g_chassis)))
129 TAILQ_HEAD(, lldpd_chassis) g_chassis;
130 TAILQ_HEAD(, lldpd_hardware) g_hardware;
131};
132
4b292b55
VB
133/* lldpd.c */
134struct lldpd_hardware *lldpd_get_hardware(struct lldpd *,
135 char *, int, struct lldpd_ops *);
e12c2365 136struct lldpd_hardware *lldpd_alloc_hardware(struct lldpd *, char *, int);
4b292b55
VB
137void lldpd_hardware_cleanup(struct lldpd*, struct lldpd_hardware *);
138struct lldpd_mgmt *lldpd_alloc_mgmt(int family, void *addr, size_t addrsize, u_int32_t iface);
139void lldpd_recv(struct lldpd *, struct lldpd_hardware *, int);
579bedd5 140void lldpd_send(struct lldpd_hardware *);
4b292b55 141void lldpd_loop(struct lldpd *);
1e0d651f 142int lldpd_main(int, char **, char **);
0484f180 143void lldpd_update_localports(struct lldpd *);
3333d2a8 144void lldpd_cleanup(struct lldpd *);
0484f180 145
579bedd5
VB
146/* frame.c */
147u_int16_t frame_checksum(const u_int8_t *, int, int);
4b292b55
VB
148
149/* event.c */
150void levent_loop(struct lldpd *);
151void levent_hardware_init(struct lldpd_hardware *);
152void levent_hardware_add_fd(struct lldpd_hardware *, int);
153void levent_hardware_release(struct lldpd_hardware *);
4e90a9e0 154void levent_ctl_notify(char *, int, struct lldpd_port *);
47287a61 155void levent_send_now(struct lldpd *);
e681c859 156void levent_update_now(struct lldpd *);
aa313f2a 157int levent_iface_subscribe(struct lldpd *, int);
579bedd5 158void levent_schedule_pdu(struct lldpd_hardware *);
3333d2a8 159void levent_schedule_cleanup(struct lldpd *);
bec75f84 160int levent_make_socket_nonblocking(int);
4b292b55
VB
161
162/* lldp.c */
e770b720 163int lldp_send_shutdown(PROTO_SEND_SIG);
4b292b55
VB
164int lldp_send(PROTO_SEND_SIG);
165int lldp_decode(PROTO_DECODE_SIG);
166
167/* cdp.c */
168#ifdef ENABLE_CDP
169int cdpv1_send(PROTO_SEND_SIG);
170int cdpv2_send(PROTO_SEND_SIG);
171int cdpv1_guess(PROTO_GUESS_SIG);
172int cdpv2_guess(PROTO_GUESS_SIG);
173#endif
174#if defined (ENABLE_CDP) || defined (ENABLE_FDP)
175int cdp_decode(PROTO_DECODE_SIG);
176#endif
177#ifdef ENABLE_FDP
178int fdp_send(PROTO_SEND_SIG);
179#endif
180
181#ifdef ENABLE_SONMP
182/* sonmp.c */
183int sonmp_send(PROTO_SEND_SIG);
184int sonmp_decode(PROTO_DECODE_SIG);
185#endif
186
187#ifdef ENABLE_EDP
188/* edp.c */
189int edp_send(PROTO_SEND_SIG);
190int edp_decode(PROTO_DECODE_SIG);
191#endif
192
4b292b55
VB
193/* dmi.c */
194#ifdef ENABLE_LLDPMED
4b292b55
VB
195char *dmi_hw(void);
196char *dmi_fw(void);
197char *dmi_sn(void);
198char *dmi_manuf(void);
199char *dmi_model(void);
200char *dmi_asset(void);
201#endif
4b292b55 202
25de85a4 203#ifdef USE_SNMP
4b292b55
VB
204/* agent.c */
205void agent_shutdown(void);
83d4b776 206void agent_init(struct lldpd *, const char *);
25de85a4
VB
207void agent_notify(struct lldpd_hardware *, int, struct lldpd_port *);
208#endif
4b292b55 209
71a7dbb3 210#ifdef ENABLE_PRIVSEP
4b292b55
VB
211/* agent_priv.c */
212void agent_priv_register_domain(void);
71a7dbb3 213#endif
4b292b55
VB
214
215/* client.c */
e0478a46
VB
216int
217client_handle_client(struct lldpd *cfg,
218 ssize_t(*send)(void *, int, void *, size_t),
219 void *,
4e90a9e0
VB
220 enum hmsg_type type, void *buffer, size_t n,
221 int*);
4b292b55
VB
222
223/* priv.c */
6fd393a2 224void priv_init(const char*, int, uid_t, gid_t);
71a7dbb3 225void priv_wait(void);
0262adbb 226void priv_ctl_cleanup(const char *ctlname);
4b292b55 227char *priv_gethostbyname(void);
e12c2365 228#ifdef HOST_OS_LINUX
70c9cb05 229int priv_open(char*);
4ea0565e 230void asroot_open(void);
e12c2365 231int priv_ethtool(char*, void*, size_t);
4ea0565e 232void asroot_ethtool(void);
e12c2365 233#endif
e735a319 234int priv_iface_init(int, char *);
4ea0565e 235int asroot_iface_init_os(int, char *, int *);
4b292b55 236int priv_iface_multicast(const char *, u_int8_t *, int);
47820fc4
VB
237int priv_iface_description(const char *, const char *);
238int asroot_iface_description_os(const char *, const char *);
f84199dd
VB
239int priv_iface_promisc(const char*);
240int asroot_iface_promisc_os(const char *);
4b292b55
VB
241int priv_snmp_socket(struct sockaddr_un *);
242
065732ca 243enum priv_cmd {
4ea0565e
VB
244 PRIV_PING,
245 PRIV_DELETE_CTL_SOCKET,
246 PRIV_GET_HOSTNAME,
247 PRIV_OPEN,
248 PRIV_ETHTOOL,
249 PRIV_IFACE_INIT,
250 PRIV_IFACE_MULTICAST,
47820fc4 251 PRIV_IFACE_DESCRIPTION,
f84199dd 252 PRIV_IFACE_PROMISC,
4ea0565e 253 PRIV_SNMP_SOCKET,
065732ca 254};
4ea0565e 255
00e40dba 256/* priv-seccomp.c */
71a7dbb3 257#if defined USE_SECCOMP && defined ENABLE_PRIVSEP
00e40dba
VB
258int priv_seccomp_init(int, int);
259#endif
4ea0565e
VB
260
261/* privsep_io.c */
d2a289bb
VB
262enum priv_context {
263 PRIV_PRIVILEGED,
264 PRIV_UNPRIVILEGED
265};
266int may_read(enum priv_context, void *, size_t);
267void must_read(enum priv_context, void *, size_t);
268void must_write(enum priv_context, const void *, size_t);
269void priv_privileged_fd(int);
270void priv_unprivileged_fd(int);
271int receive_fd(enum priv_context);
272void send_fd(enum priv_context, int);
4b292b55 273
e12c2365 274/* interfaces-*.c */
e12c2365 275
adbb6e54
VB
276/* BPF filter to get revelant information from interfaces */
277/* LLDP: "ether proto 0x88cc and ether dst 01:80:c2:00:00:0e" */
278/* FDP: "ether dst 01:e0:52:cc:cc:cc" */
279/* CDP: "ether dst 01:00:0c:cc:cc:cc" */
280/* SONMP: "ether dst 01:00:81:00:01:00" */
281/* EDP: "ether dst 00:e0:2b:00:00:00" */
282/* For optimization purpose, we first check if the first bit of the
283 first byte is 1. if not, this can only be an EDP packet:
284
285 tcpdump -dd "(ether[0] & 1 = 1 and
286 ((ether proto 0x88cc and ether dst 01:80:c2:00:00:0e) or
287 (ether dst 01:e0:52:cc:cc:cc) or
288 (ether dst 01:00:0c:cc:cc:cc) or
289 (ether dst 01:00:81:00:01:00))) or
290 (ether dst 00:e0:2b:00:00:00)"
291*/
292
293#define LLDPD_FILTER_F \
294 { 0x30, 0, 0, 0x00000000 }, \
295 { 0x54, 0, 0, 0x00000001 }, \
296 { 0x15, 0, 14, 0x00000001 }, \
297 { 0x28, 0, 0, 0x0000000c }, \
298 { 0x15, 0, 4, 0x000088cc }, \
299 { 0x20, 0, 0, 0x00000002 }, \
300 { 0x15, 0, 2, 0xc200000e }, \
301 { 0x28, 0, 0, 0x00000000 }, \
302 { 0x15, 12, 13, 0x00000180 }, \
303 { 0x20, 0, 0, 0x00000002 }, \
304 { 0x15, 0, 2, 0x52cccccc }, \
305 { 0x28, 0, 0, 0x00000000 }, \
306 { 0x15, 8, 9, 0x000001e0 }, \
307 { 0x15, 1, 0, 0x0ccccccc }, \
308 { 0x15, 0, 2, 0x81000100 }, \
309 { 0x28, 0, 0, 0x00000000 }, \
310 { 0x15, 4, 5, 0x00000100 }, \
311 { 0x20, 0, 0, 0x00000002 }, \
312 { 0x15, 0, 3, 0x2b000000 }, \
313 { 0x28, 0, 0, 0x00000000 }, \
314 { 0x15, 0, 1, 0x000000e0 }, \
315 { 0x6, 0, 0, 0x0000ffff }, \
316 { 0x6, 0, 0, 0x00000000 },
317
318/* This function is responsible to refresh information about interfaces. It is
319 * OS specific but should be present for each OS. It can use the functions in
320 * `interfaces.c` as helper by providing a list of OS-independent interface
321 * devices. */
322void interfaces_update(struct lldpd *);
adbb6e54
VB
323
324/* interfaces.c */
325/* An interface cannot be both physical and (bridge or bond or vlan) */
326#define IFACE_PHYSICAL_T (1 << 0) /* Physical interface */
327#define IFACE_BRIDGE_T (1 << 1) /* Bridge interface */
328#define IFACE_BOND_T (1 << 2) /* Bond interface */
329#define IFACE_VLAN_T (1 << 3) /* VLAN interface */
330#define IFACE_WIRELESS_T (1 << 4) /* Wireless interface */
331struct interfaces_device {
332 TAILQ_ENTRY(interfaces_device) next;
e12c2365
VB
333 int index; /* Index */
334 char *name; /* Name */
335 char *alias; /* Alias */
e12c2365 336 char *address; /* MAC address */
adbb6e54
VB
337 char *driver; /* Driver (for whitelisting purpose) */
338 int flags; /* Flags (IFF_*) */
339 int mtu; /* MTU */
340 int type; /* Type (see IFACE_*_T) */
341 int vlanid; /* If a VLAN, what is the VLAN ID? */
342 struct interfaces_device *lower; /* Lower interface (for a VLAN for example) */
343 struct interfaces_device *upper; /* Upper interface (for a bridge or a bond) */
344
345 /* The following are OS specific. Should be static (no free function) */
346#ifdef HOST_OS_LINUX
347 int lower_idx; /* Index to lower interface */
348 int upper_idx; /* Index to upper interface */
349 int txqueue; /* Transmit queue length */
350#endif
e12c2365 351};
adbb6e54
VB
352struct interfaces_address {
353 TAILQ_ENTRY(interfaces_address) next;
354 int index; /* Index */
355 int flags; /* Flags */
e12c2365 356 struct sockaddr_storage address; /* Address */
adbb6e54
VB
357
358 /* The following are OS specific. */
359 /* Nothing yet. */
e12c2365 360};
adbb6e54
VB
361TAILQ_HEAD(interfaces_device_list, interfaces_device);
362TAILQ_HEAD(interfaces_address_list, interfaces_address);
363void interfaces_free_device(struct interfaces_device *);
364void interfaces_free_address(struct interfaces_address *);
365void interfaces_free_devices(struct interfaces_device_list *);
366void interfaces_free_addresses(struct interfaces_address_list *);
367struct interfaces_device* interfaces_indextointerface(
368 struct interfaces_device_list *,
369 int);
370struct interfaces_device* interfaces_nametointerface(
371 struct interfaces_device_list *,
372 const char *);
373
f84199dd
VB
374void interfaces_helper_promisc(struct lldpd *,
375 struct lldpd_hardware *);
adbb6e54
VB
376void interfaces_helper_whitelist(struct lldpd *,
377 struct interfaces_device_list *);
378void interfaces_helper_chassis(struct lldpd *,
379 struct interfaces_device_list *);
bdfe4193
VB
380void interfaces_helper_add_hardware(struct lldpd *,
381 struct lldpd_hardware *);
adbb6e54 382void interfaces_helper_physical(struct lldpd *,
88bc404f 383 struct interfaces_device_list *,
22e8cd65 384 struct lldpd_ops *,
88bc404f 385 int(*init)(struct lldpd *, struct lldpd_hardware *));
8fbd3195
ST
386void interfaces_helper_port_name_desc(struct lldpd *,
387 struct lldpd_hardware *,
adbb6e54
VB
388 struct interfaces_device *);
389void interfaces_helper_mgmt(struct lldpd *,
390 struct interfaces_address_list *);
391#ifdef ENABLE_DOT1
392void interfaces_helper_vlan(struct lldpd *,
393 struct interfaces_device_list *);
394#endif
5347914e
VB
395int interfaces_send_helper(struct lldpd *,
396 struct lldpd_hardware *, char *, size_t);
adbb6e54
VB
397
398void interfaces_setup_multicast(struct lldpd *, const char *, int);
c3e340b6 399int interfaces_routing_enabled(struct lldpd *);
adbb6e54
VB
400
401#ifdef HOST_OS_LINUX
402/* netlink.c */
403struct interfaces_device_list *netlink_get_interfaces(void);
404struct interfaces_address_list *netlink_get_addresses(void);
0484f180 405int netlink_subscribe_changes(void);
e12c2365
VB
406#endif
407
c3e340b6
VB
408#ifndef HOST_OS_LINUX
409int ifbpf_phys_init(struct lldpd *, struct lldpd_hardware *);
410#endif
411
d5e69431
VB
412/* pattern.c */
413int pattern_match(char *, char *, int);
414
4b292b55 415#endif /* _LLDPD_H */