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