]>
git.ipfire.org Git - thirdparty/lldpd.git/blob - src/daemon/lldpd.h
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.
26 #ifdef HAVE_VALGRIND_VALGRIND_H
27 # include <valgrind/valgrind.h>
29 # define RUNNING_ON_VALGRIND 0
35 #include <sys/queue.h>
36 #include <sys/types.h>
37 #include <netinet/if_ether.h>
38 #include <netinet/in.h>
42 #if defined (ENABLE_CDP) || defined (ENABLE_FDP)
52 #include "../compat/compat.h"
53 #include "../marshal.h"
56 #include "../lldpd-structs.h"
58 /* We don't want to import event2/event.h. We only need those as
63 #define SYSFS_CLASS_NET "/sys/class/net/"
64 #define SYSFS_CLASS_DMI "/sys/class/dmi/id/"
66 #define LLDPD_TX_INTERVAL 30
67 #define LLDPD_TX_MSGDELAY 1
68 #define LLDPD_PID_FILE "/var/run/lldpd.pid"
70 #define USING_AGENTX_SUBAGENT_MODULE 1
72 #define PROTO_SEND_SIG struct lldpd *, struct lldpd_hardware *
73 #define PROTO_DECODE_SIG struct lldpd *, char *, int, struct lldpd_hardware *, struct lldpd_chassis **, struct lldpd_port **
74 #define PROTO_GUESS_SIG char *, int
77 int mode
; /* > 0 mode identifier (unique per protocol) */
78 int enabled
; /* Is this protocol enabled? */
79 char *name
; /* Name of protocol */
80 char arg
; /* Argument to enable this protocol */
81 int(*send
)(PROTO_SEND_SIG
); /* How to send a frame */
82 int(*decode
)(PROTO_DECODE_SIG
); /* How to decode a frame */
83 int(*guess
)(PROTO_GUESS_SIG
); /* Can be NULL, use MAC address in this case */
84 u_int8_t mac
[ETHER_ADDR_LEN
]; /* Destination MAC address used by this protocol */
87 #define SMART_HIDDEN(port) (port->p_hidden_in)
91 struct event_base
*g_base
;
95 struct lldpd_config g_config
;
97 struct protocol
*g_protocols
;
99 struct event
*g_main_loop
;
102 struct event
*g_snmp_timeout
;
105 #endif /* USE_SNMP */
107 /* Unix socket handling */
109 struct event
*g_ctl_event
;
110 struct event
*g_iface_event
; /* Triggered when there is an interface change */
111 struct event
*g_iface_timer_event
; /* Triggered one second after last interface change */
115 #define LOCAL_CHASSIS(cfg) ((struct lldpd_chassis *)(TAILQ_FIRST(&cfg->g_chassis)))
116 TAILQ_HEAD(, lldpd_chassis
) g_chassis
;
117 TAILQ_HEAD(, lldpd_hardware
) g_hardware
;
121 struct lldpd_hardware
*lldpd_get_hardware(struct lldpd
*,
122 char *, int, struct lldpd_ops
*);
123 struct lldpd_hardware
*lldpd_alloc_hardware(struct lldpd
*, char *, int);
124 void lldpd_hardware_cleanup(struct lldpd
*, struct lldpd_hardware
*);
125 struct lldpd_mgmt
*lldpd_alloc_mgmt(int family
, void *addr
, size_t addrsize
, u_int32_t iface
);
126 void lldpd_recv(struct lldpd
*, struct lldpd_hardware
*, int);
127 void lldpd_send(struct lldpd_hardware
*);
128 void lldpd_loop(struct lldpd
*);
129 int lldpd_main(int, char **);
130 void lldpd_update_localports(struct lldpd
*);
133 u_int16_t
frame_checksum(const u_int8_t
*, int, int);
136 void levent_loop(struct lldpd
*);
137 void levent_hardware_init(struct lldpd_hardware
*);
138 void levent_hardware_add_fd(struct lldpd_hardware
*, int);
139 void levent_hardware_release(struct lldpd_hardware
*);
140 void levent_ctl_notify(char *, int, struct lldpd_port
*);
141 void levent_send_now(struct lldpd
*);
142 int levent_iface_subscribe(struct lldpd
*, int);
143 void levent_schedule_pdu(struct lldpd_hardware
*);
146 int lldp_send(PROTO_SEND_SIG
);
147 int lldp_decode(PROTO_DECODE_SIG
);
151 int cdpv1_send(PROTO_SEND_SIG
);
152 int cdpv2_send(PROTO_SEND_SIG
);
153 int cdpv1_guess(PROTO_GUESS_SIG
);
154 int cdpv2_guess(PROTO_GUESS_SIG
);
156 #if defined (ENABLE_CDP) || defined (ENABLE_FDP)
157 int cdp_decode(PROTO_DECODE_SIG
);
160 int fdp_send(PROTO_SEND_SIG
);
165 int sonmp_send(PROTO_SEND_SIG
);
166 int sonmp_decode(PROTO_DECODE_SIG
);
171 int edp_send(PROTO_SEND_SIG
);
172 int edp_decode(PROTO_DECODE_SIG
);
176 #ifdef ENABLE_LLDPMED
180 char *dmi_manuf(void);
181 char *dmi_model(void);
182 char *dmi_asset(void);
187 void agent_shutdown(void);
188 void agent_init(struct lldpd
*, char *);
189 void agent_notify(struct lldpd_hardware
*, int, struct lldpd_port
*);
193 void agent_priv_register_domain(void);
197 client_handle_client(struct lldpd
*cfg
,
198 ssize_t(*send
)(void *, int, void *, size_t),
200 enum hmsg_type type
, void *buffer
, size_t n
,
204 void priv_init(char*, int, uid_t
, gid_t
);
205 void priv_ctl_cleanup(void);
206 char *priv_gethostbyname(void);
208 int priv_open(char*);
209 int priv_ethtool(char*, void*, size_t);
211 int priv_iface_init(int, char *);
212 int priv_iface_multicast(const char *, u_int8_t
*, int);
213 int priv_snmp_socket(struct sockaddr_un
*);
215 /* privsep_fdpass.c */
217 void send_fd(int, int);
221 /* BPF filter to get revelant information from interfaces */
222 /* LLDP: "ether proto 0x88cc and ether dst 01:80:c2:00:00:0e" */
223 /* FDP: "ether dst 01:e0:52:cc:cc:cc" */
224 /* CDP: "ether dst 01:00:0c:cc:cc:cc" */
225 /* SONMP: "ether dst 01:00:81:00:01:00" */
226 /* EDP: "ether dst 00:e0:2b:00:00:00" */
227 /* For optimization purpose, we first check if the first bit of the
228 first byte is 1. if not, this can only be an EDP packet:
230 tcpdump -dd "(ether[0] & 1 = 1 and
231 ((ether proto 0x88cc and ether dst 01:80:c2:00:00:0e) or
232 (ether dst 01:e0:52:cc:cc:cc) or
233 (ether dst 01:00:0c:cc:cc:cc) or
234 (ether dst 01:00:81:00:01:00))) or
235 (ether dst 00:e0:2b:00:00:00)"
238 #define LLDPD_FILTER_F \
239 { 0x30, 0, 0, 0x00000000 }, \
240 { 0x54, 0, 0, 0x00000001 }, \
241 { 0x15, 0, 14, 0x00000001 }, \
242 { 0x28, 0, 0, 0x0000000c }, \
243 { 0x15, 0, 4, 0x000088cc }, \
244 { 0x20, 0, 0, 0x00000002 }, \
245 { 0x15, 0, 2, 0xc200000e }, \
246 { 0x28, 0, 0, 0x00000000 }, \
247 { 0x15, 12, 13, 0x00000180 }, \
248 { 0x20, 0, 0, 0x00000002 }, \
249 { 0x15, 0, 2, 0x52cccccc }, \
250 { 0x28, 0, 0, 0x00000000 }, \
251 { 0x15, 8, 9, 0x000001e0 }, \
252 { 0x15, 1, 0, 0x0ccccccc }, \
253 { 0x15, 0, 2, 0x81000100 }, \
254 { 0x28, 0, 0, 0x00000000 }, \
255 { 0x15, 4, 5, 0x00000100 }, \
256 { 0x20, 0, 0, 0x00000002 }, \
257 { 0x15, 0, 3, 0x2b000000 }, \
258 { 0x28, 0, 0, 0x00000000 }, \
259 { 0x15, 0, 1, 0x000000e0 }, \
260 { 0x6, 0, 0, 0x0000ffff }, \
261 { 0x6, 0, 0, 0x00000000 },
263 /* This function is responsible to refresh information about interfaces. It is
264 * OS specific but should be present for each OS. It can use the functions in
265 * `interfaces.c` as helper by providing a list of OS-independent interface
267 void interfaces_update(struct lldpd
*);
270 /* An interface cannot be both physical and (bridge or bond or vlan) */
271 #define IFACE_PHYSICAL_T (1 << 0) /* Physical interface */
272 #define IFACE_BRIDGE_T (1 << 1) /* Bridge interface */
273 #define IFACE_BOND_T (1 << 2) /* Bond interface */
274 #define IFACE_VLAN_T (1 << 3) /* VLAN interface */
275 #define IFACE_WIRELESS_T (1 << 4) /* Wireless interface */
276 struct interfaces_device
{
277 TAILQ_ENTRY(interfaces_device
) next
;
278 int index
; /* Index */
279 char *name
; /* Name */
280 char *alias
; /* Alias */
281 char *address
; /* MAC address */
282 char *driver
; /* Driver (for whitelisting purpose) */
283 int flags
; /* Flags (IFF_*) */
285 int type
; /* Type (see IFACE_*_T) */
286 int vlanid
; /* If a VLAN, what is the VLAN ID? */
287 struct interfaces_device
*lower
; /* Lower interface (for a VLAN for example) */
288 struct interfaces_device
*upper
; /* Upper interface (for a bridge or a bond) */
290 /* The following are OS specific. Should be static (no free function) */
292 int lower_idx
; /* Index to lower interface */
293 int upper_idx
; /* Index to upper interface */
294 int txqueue
; /* Transmit queue length */
297 struct interfaces_address
{
298 TAILQ_ENTRY(interfaces_address
) next
;
299 int index
; /* Index */
300 int flags
; /* Flags */
301 struct sockaddr_storage address
; /* Address */
303 /* The following are OS specific. */
306 TAILQ_HEAD(interfaces_device_list
, interfaces_device
);
307 TAILQ_HEAD(interfaces_address_list
, interfaces_address
);
308 void interfaces_free_device(struct interfaces_device
*);
309 void interfaces_free_address(struct interfaces_address
*);
310 void interfaces_free_devices(struct interfaces_device_list
*);
311 void interfaces_free_addresses(struct interfaces_address_list
*);
312 struct interfaces_device
* interfaces_indextointerface(
313 struct interfaces_device_list
*,
315 struct interfaces_device
* interfaces_nametointerface(
316 struct interfaces_device_list
*,
319 void interfaces_helper_whitelist(struct lldpd
*,
320 struct interfaces_device_list
*);
321 void interfaces_helper_chassis(struct lldpd
*,
322 struct interfaces_device_list
*);
323 void interfaces_helper_physical(struct lldpd
*,
324 struct interfaces_device_list
*,
326 int(*init
)(struct lldpd
*, struct lldpd_hardware
*));
327 void interfaces_helper_port_name_desc(struct lldpd_hardware
*,
328 struct interfaces_device
*);
329 void interfaces_helper_mgmt(struct lldpd
*,
330 struct interfaces_address_list
*);
332 void interfaces_helper_vlan(struct lldpd
*,
333 struct interfaces_device_list
*);
336 void interfaces_setup_multicast(struct lldpd
*, const char *, int);
340 struct interfaces_device_list
*netlink_get_interfaces(void);
341 struct interfaces_address_list
*netlink_get_addresses(void);
342 int netlink_subscribe_changes(void);
345 #endif /* _LLDPD_H */