]> git.ipfire.org Git - thirdparty/lldpd.git/blame - src/lldpd.h
Set h_ifindex correctly.
[thirdparty/lldpd.git] / src / lldpd.h
CommitLineData
43c02e7b
VB
1/*
2 * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _LLDPD_H
18#define _LLDPD_H
19
20#if HAVE_CONFIG_H
21 #include <config.h>
22#endif
23
24#define _GNU_SOURCE 1
25#include <stdlib.h>
26#include <string.h>
27#include <sys/queue.h>
28#ifndef INCLUDE_LINUX_IF_H
29#include <net/if.h>
30#else
31#include <arpa/inet.h>
32#include <linux/if.h>
33#endif
6e75df87 34#include <ifaddrs.h>
43c02e7b
VB
35#include <net/ethernet.h>
36#include <netinet/in.h>
4afe659e 37#include <linux/ethtool.h>
43c02e7b
VB
38
39#include "compat.h"
40#include "lldp.h"
4bad1937 41#if defined (ENABLE_CDP) || defined (ENABLE_FDP)
43c02e7b 42#include "cdp.h"
4bad1937
VB
43#endif
44#ifdef ENABLE_SONMP
43c02e7b 45#include "sonmp.h"
4bad1937
VB
46#endif
47#ifdef ENABLE_EDP
43c02e7b 48#include "edp.h"
4bad1937 49#endif
43c02e7b 50
89840df0
VB
51#define SYSFS_CLASS_NET "/sys/class/net/"
52#define SYSFS_CLASS_DMI "/sys/class/dmi/id/"
43c02e7b
VB
53#define LLDPD_TTL 120
54#define LLDPD_TX_DELAY 30
55#define LLDPD_TX_MSGDELAY 1
56#define LLDPD_CTL_SOCKET "/var/run/lldpd.socket"
57#define LLDPD_PID_FILE "/var/run/lldpd.pid"
58
59#define UNIX_PATH_MAX 108
60
61#define USING_AGENTX_SUBAGENT_MODULE 1
62
a1347cd8 63#ifdef ENABLE_DOT1
43c02e7b
VB
64struct lldpd_vlan {
65 TAILQ_ENTRY(lldpd_vlan) v_entries;
66 char *v_name;
67 u_int16_t v_vid;
68};
0c8f36f3 69#define STRUCT_LLDPD_VLAN "(Lsw)"
a1347cd8 70#endif
43c02e7b 71
e3a44efb 72#ifdef ENABLE_LLDPMED
0c8f36f3 73#define STRUCT_LLDPD_MED_POLICY "(bbbwbb)"
e3a44efb
VB
74struct lldpd_med_policy {
75 u_int8_t type;
76 u_int8_t unknown;
77 u_int8_t tagged;
78 u_int16_t vid;
79 u_int8_t priority;
80 u_int8_t dscp;
e3a44efb
VB
81};
82
0c8f36f3 83#define STRUCT_LLDPD_MED_LOC "(bC)"
e3a44efb
VB
84struct lldpd_med_loc {
85 u_int8_t format;
86 char *data;
87 int data_len;
e3a44efb
VB
88};
89#endif
90
43c02e7b 91struct lldpd_chassis {
75068724
VB
92 TAILQ_ENTRY(lldpd_chassis) c_entries;
93 u_int16_t c_refcount; /* Reference count by ports */
94 u_int16_t c_index; /* Monotonic index */
95 u_int8_t c_protocol; /* Protocol used to get this chassis */
43c02e7b
VB
96 u_int8_t c_id_subtype;
97 char *c_id;
98 int c_id_len;
99 char *c_name;
100 char *c_descr;
101
102 u_int16_t c_cap_available;
103 u_int16_t c_cap_enabled;
104
105 u_int16_t c_ttl;
106
107 struct in_addr c_mgmt;
108 u_int32_t c_mgmt_if;
89840df0
VB
109
110#ifdef ENABLE_LLDPMED
34602f3b 111#define STRUCT_LLDPD_CHASSIS_MED "wbsssssss"
40ecae87 112 u_int16_t c_med_cap_available;
89840df0
VB
113 u_int8_t c_med_type;
114 char *c_med_hw;
115 char *c_med_fw;
116 char *c_med_sw;
117 char *c_med_sn;
118 char *c_med_manuf;
119 char *c_med_model;
120 char *c_med_asset;
89840df0 121#else
a1347cd8 122#define STRUCT_LLDPD_CHASSIS_MED ""
89840df0 123#endif
1531f7f3
VB
124
125};
75068724 126#define STRUCT_LLDPD_CHASSIS "(LwwbbCsswwwll" STRUCT_LLDPD_CHASSIS_MED ")"
43c02e7b
VB
127
128struct lldpd_port {
75068724
VB
129 TAILQ_ENTRY(lldpd_port) p_entries;
130 struct lldpd_chassis *p_chassis; /* Attached chassis */
131 time_t p_lastchange; /* Time of last change of values */
132 time_t p_lastupdate; /* Time of last update received */
133 struct lldpd_frame *p_lastframe; /* Frame received during last update */
134 u_int8_t p_protocol; /* Protocol used to get this port */
43c02e7b
VB
135 u_int8_t p_id_subtype;
136 char *p_id;
137 int p_id_len;
138 char *p_descr;
548109b2 139 u_int16_t p_mfs;
43c02e7b 140
a1347cd8 141#ifdef ENABLE_DOT3
1531f7f3 142#define STRUCT_LLDPD_PORT_DOT3 "lbbww"
43c02e7b
VB
143 /* Dot3 stuff */
144 u_int32_t p_aggregid;
145 u_int8_t p_autoneg_support;
146 u_int8_t p_autoneg_enabled;
147 u_int16_t p_autoneg_advertised;
148 u_int16_t p_mau_type;
a1347cd8
VB
149#else
150#define STRUCT_LLDPD_PORT_DOT3 ""
151#endif
1531f7f3 152
740593ff
VB
153#ifdef ENABLE_LLDPMED
154#define STRUCT_LLDPD_PORT_MED "w" \
155 STRUCT_LLDPD_MED_POLICY \
156 STRUCT_LLDPD_MED_POLICY \
157 STRUCT_LLDPD_MED_POLICY \
158 STRUCT_LLDPD_MED_POLICY \
159 STRUCT_LLDPD_MED_POLICY \
160 STRUCT_LLDPD_MED_POLICY \
161 STRUCT_LLDPD_MED_POLICY \
162 STRUCT_LLDPD_MED_POLICY \
163 STRUCT_LLDPD_MED_LOC \
164 STRUCT_LLDPD_MED_LOC \
165 STRUCT_LLDPD_MED_LOC \
166 "bbbw"
167 u_int16_t p_med_cap_enabled;
168 struct lldpd_med_policy p_med_policy[LLDPMED_APPTYPE_LAST];
169 struct lldpd_med_loc p_med_location[LLDPMED_LOCFORMAT_LAST];
170 u_int8_t p_med_pow_devicetype; /* PD or PSE */
171 u_int8_t p_med_pow_source;
172 u_int8_t p_med_pow_priority;
173 u_int16_t p_med_pow_val;
174#else
175#define STRUCT_LLDPD_PORT_MED ""
176#endif
177
a1347cd8 178#ifdef ENABLE_DOT1
75b3469d
VB
179#define STRUCT_LLDPD_PORT_DOT1 "wPP"
180 u_int16_t p_pvid;
1531f7f3 181 TAILQ_HEAD(, lldpd_vlan) p_vlans;
a1347cd8
VB
182#else
183#define STRUCT_LLDPD_PORT_DOT1 ""
184#endif
1531f7f3
VB
185};
186
84853b92 187#define STRUCT_LLDPD_PORT "(LPttPbbCsw" \
740593ff
VB
188 STRUCT_LLDPD_PORT_DOT3 \
189 STRUCT_LLDPD_PORT_MED \
190 STRUCT_LLDPD_PORT_DOT1 ")"
43c02e7b
VB
191
192struct lldpd_frame {
193 int size;
194 unsigned char frame[];
195};
196
6e75df87
VB
197struct lldpd_hardware;
198struct lldpd;
199struct lldpd_ops {
200 int(*send)(struct lldpd *,
201 struct lldpd_hardware*,
202 char *, size_t); /* Function to send a frame */
203 int(*recv)(struct lldpd *,
204 struct lldpd_hardware*,
205 int, char *, size_t); /* Function to receive a frame */
206 int(*cleanup)(struct lldpd *, struct lldpd_hardware *); /* Cleanup function. */
207};
208
44002d66
VB
209/* An interface is uniquely identified by h_ifindex, h_ifname and h_ops. This
210 * means if an interface becomes enslaved, it will be considered as a new
211 * interface. The same applies for renaming and we include the index in case of
212 * renaming to an existing interface. */
43c02e7b
VB
213struct lldpd_hardware {
214 TAILQ_ENTRY(lldpd_hardware) h_entries;
215
6e75df87
VB
216 fd_set h_recvfds; /* FD for reception */
217 int h_sendfd; /* FD for sending, only used by h_ops */
218 struct lldpd_ops *h_ops; /* Hardware-dependent functions */
219 void *h_data; /* Hardware-dependent data */
43c02e7b 220
43c02e7b 221 int h_mtu;
6e75df87
VB
222 int h_flags; /* Packets will be sent only
223 if IFF_RUNNING. Will be
224 removed if this is left
225 to 0. */
226 int h_ifindex; /* Interface index, used by SNMP */
227 char h_ifname[IFNAMSIZ]; /* Should be unique */
43c02e7b
VB
228 u_int8_t h_lladdr[ETHER_ADDR_LEN];
229
230 u_int64_t h_tx_cnt;
231 u_int64_t h_rx_cnt;
232 u_int64_t h_rx_discarded_cnt;
233 u_int64_t h_rx_ageout_cnt;
37387046 234 u_int64_t h_rx_unrecognized_cnt;
43c02e7b 235
75068724
VB
236 struct lldpd_port h_lport; /* Port attached to this hardware port */
237 TAILQ_HEAD(, lldpd_port) h_rports; /* Remote ports */
43c02e7b
VB
238};
239
240struct lldpd_interface {
241 TAILQ_ENTRY(lldpd_interface) next;
242 char *name;
243};
0c8f36f3 244#define STRUCT_LLDPD_INTERFACE "(Ls)"
43c02e7b 245
77507b69 246#define PROTO_SEND_SIG struct lldpd *, struct lldpd_hardware *
43c02e7b
VB
247#define PROTO_DECODE_SIG struct lldpd *, char *, int, struct lldpd_hardware *, struct lldpd_chassis **, struct lldpd_port **
248#define PROTO_GUESS_SIG char *, int
249
43c02e7b 250struct protocol {
f2dcb180
VB
251#define LLDPD_MODE_LLDP 1
252#define LLDPD_MODE_CDPV1 2
253#define LLDPD_MODE_CDPV2 3
254#define LLDPD_MODE_SONMP 4
255#define LLDPD_MODE_EDP 5
256#define LLDPD_MODE_FDP 6
43c02e7b
VB
257 int mode; /* > 0 mode identifier (unique per protocol) */
258 int enabled; /* Is this protocol enabled? */
259 char *name; /* Name of protocol */
260 char arg; /* Argument to enable this protocol */
261 int(*send)(PROTO_SEND_SIG); /* How to send a frame */
262 int(*decode)(PROTO_DECODE_SIG); /* How to decode a frame */
263 int(*guess)(PROTO_GUESS_SIG); /* Can be NULL, use MAC address in this case */
264 u_int8_t mac[ETH_ALEN]; /* Destination MAC address used by this protocol */
265 struct sock_filter *filter; /* BPF filter */
266 size_t filterlen; /* Size of BPF filter */
267};
268
77d7090e
VB
269#define CALLBACK_SIG struct lldpd*, struct lldpd_callback*
270struct lldpd_callback {
271 TAILQ_ENTRY(lldpd_callback) next;
272 int fd; /* FD that will trigger this callback */
273 void(*function)(CALLBACK_SIG); /* Function called */
274 void *data; /* Optional data for this callback*/
275};
276
43c02e7b
VB
277struct lldpd {
278 int g_sock;
279 int g_delay;
280
281 struct protocol *g_protocols;
993a6e50 282#ifdef ENABLE_LISTENVLAN
6a2fa591 283 int g_listen_vlans;
993a6e50 284#endif
740593ff
VB
285#ifdef ENABLE_LLDPMED
286 int g_noinventory;
287#endif
43c02e7b
VB
288
289 time_t g_lastsent;
290 int g_lastrid;
291#ifdef USE_SNMP
292 int g_snmp;
293#endif /* USE_SNMP */
294
295 /* Unix socket handling */
296 int g_ctl;
77d7090e
VB
297
298 TAILQ_HEAD(, lldpd_callback) g_callbacks;
43c02e7b
VB
299
300 char *g_mgmt_pattern;
301
77507b69 302#define LOCAL_CHASSIS(cfg) ((struct lldpd_chassis *)(TAILQ_FIRST(&cfg->g_chassis)))
75068724 303 TAILQ_HEAD(, lldpd_chassis) g_chassis;
43c02e7b
VB
304 TAILQ_HEAD(, lldpd_hardware) g_hardware;
305};
306
6e75df87
VB
307typedef void(*lldpd_ifhandlers)(struct lldpd *, struct ifaddrs *);
308
43c02e7b
VB
309enum hmsg_type {
310 HMSG_NONE,
311 HMSG_GET_INTERFACES,
84853b92 312 HMSG_GET_NB_PORTS,
43c02e7b 313 HMSG_GET_PORT,
84853b92 314 HMSG_GET_CHASSIS,
43c02e7b 315 HMSG_GET_VLANS,
740593ff 316 HMSG_SET_LOCATION,
43c02e7b
VB
317 HMSG_SHUTDOWN
318};
319
320struct hmsg_hdr {
321 enum hmsg_type type;
322 int16_t len;
323 pid_t pid;
324} __attribute__ ((__packed__));
325
326struct hmsg {
327 struct hmsg_hdr hdr;
328 void *data;
329} __attribute__ ((__packed__));
330
331#define HMSG_HEADER_SIZE sizeof(struct hmsg_hdr)
332#define MAX_HMSGSIZE 8192
333
334/* lldpd.c */
44002d66
VB
335struct lldpd_hardware *lldpd_get_hardware(struct lldpd *,
336 char *, int, struct lldpd_ops *);
6e75df87
VB
337struct lldpd_hardware *lldpd_alloc_hardware(struct lldpd *, char *);
338void lldpd_hardware_cleanup(struct lldpd*, struct lldpd_hardware *);
a1347cd8 339#ifdef ENABLE_DOT1
43c02e7b 340void lldpd_vlan_cleanup(struct lldpd_port *);
a1347cd8 341#endif
43c02e7b 342void lldpd_remote_cleanup(struct lldpd *, struct lldpd_hardware *, int);
a0edeaf8 343void lldpd_port_cleanup(struct lldpd_port *, int);
77507b69 344void lldpd_chassis_cleanup(struct lldpd_chassis *, int);
77d7090e
VB
345int lldpd_callback_add(struct lldpd *, int, void(*fn)(CALLBACK_SIG), void *);
346void lldpd_callback_del(struct lldpd *, int, void(*fn)(CALLBACK_SIG));
43c02e7b
VB
347
348/* lldp.c */
349int lldp_send(PROTO_SEND_SIG);
350int lldp_decode(PROTO_DECODE_SIG);
351
352/* cdp.c */
4bad1937 353#ifdef ENABLE_CDP
43c02e7b
VB
354int cdpv1_send(PROTO_SEND_SIG);
355int cdpv2_send(PROTO_SEND_SIG);
43c02e7b
VB
356int cdpv1_guess(PROTO_GUESS_SIG);
357int cdpv2_guess(PROTO_GUESS_SIG);
4bad1937
VB
358#endif
359#if defined (ENABLE_CDP) || defined (ENABLE_FDP)
360int cdp_decode(PROTO_DECODE_SIG);
361#endif
362#ifdef ENABLE_FDP
363int fdp_send(PROTO_SEND_SIG);
364#endif
43c02e7b 365
4bad1937 366#ifdef ENABLE_SONMP
43c02e7b
VB
367/* sonmp.c */
368int sonmp_send(PROTO_SEND_SIG);
369int sonmp_decode(PROTO_DECODE_SIG);
4bad1937 370#endif
43c02e7b 371
4bad1937 372#ifdef ENABLE_EDP
43c02e7b
VB
373/* edp.c */
374int edp_send(PROTO_SEND_SIG);
375int edp_decode(PROTO_DECODE_SIG);
4bad1937 376#endif
43c02e7b
VB
377
378/* ctl.c */
b5562b23 379int ctl_create(char *);
43c02e7b 380int ctl_connect(char *);
b5562b23 381void ctl_cleanup(char *);
77d7090e
VB
382#ifndef CLIENT_ONLY
383void ctl_accept(struct lldpd *, struct lldpd_callback *);
384#endif
43c02e7b
VB
385void ctl_msg_init(struct hmsg *, enum hmsg_type);
386int ctl_msg_send(int, struct hmsg *);
387int ctl_msg_recv(int, struct hmsg *);
388int ctl_msg_pack_list(char *, void *, unsigned int, struct hmsg *, void **);
389int ctl_msg_unpack_list(char *, void *, unsigned int, struct hmsg *, void **);
390int ctl_msg_pack_structure(char *, void *, unsigned int, struct hmsg *, void **);
391int ctl_msg_unpack_structure(char *, void *, unsigned int, struct hmsg *, void **);
392
6e75df87 393/* interfaces.c */
849954d7 394void lldpd_ifh_bond(struct lldpd *, struct ifaddrs *);
6e75df87 395void lldpd_ifh_eth(struct lldpd *, struct ifaddrs *);
5994b27d 396#ifdef ENABLE_DOT1
6e75df87 397void lldpd_ifh_vlan(struct lldpd *, struct ifaddrs *);
5994b27d 398#endif
6e75df87
VB
399void lldpd_ifh_mgmt(struct lldpd *, struct ifaddrs *);
400
401/* dmi.c */
89840df0
VB
402#ifdef ENABLE_LLDPMED
403char *dmi_hw();
404char *dmi_fw();
405char *dmi_sn();
406char *dmi_manuf();
407char *dmi_model();
408char *dmi_asset();
409#endif
43c02e7b
VB
410
411/* log.c */
412void log_init(int);
413void log_warn(const char *, ...);
414#define LLOG_WARN(x,...) log_warn("%s: " x, __FUNCTION__, ##__VA_ARGS__)
415void log_warnx(const char *, ...);
416#define LLOG_WARNX(x,...) log_warnx("%s: " x, __FUNCTION__, ##__VA_ARGS__)
417void log_info(const char *, ...);
418#define LLOG_INFO(x,...) log_info("%s: " x, __FUNCTION__, ##__VA_ARGS__)
419void log_debug(const char *, ...);
420#define LLOG_DEBUG(x,...) log_debug("%s: " x, __FUNCTION__, ##__VA_ARGS__)
421void fatal(const char *);
422void fatalx(const char *);
423
424/* agent.c */
425void agent_shutdown();
426void agent_init(struct lldpd *, int);
427
d72a05d4
VB
428/* agent_priv.c */
429void agent_priv_register_domain();
430
43c02e7b
VB
431/* strlcpy.c */
432size_t strlcpy(char *, const char *, size_t);
433
a552a72e
VB
434/* client.c */
435struct client_handle {
436 enum hmsg_type type;
437 void (*handle)(struct lldpd*, struct hmsg*, struct hmsg*);
438};
439
77d7090e
VB
440void client_handle_client(struct lldpd *, struct lldpd_callback *,
441 char *, int);
a552a72e
VB
442void client_handle_none(struct lldpd *, struct hmsg *,
443 struct hmsg *);
444void client_handle_get_interfaces(struct lldpd *, struct hmsg *,
445 struct hmsg *);
740593ff 446void client_handle_port_related(struct lldpd *, struct hmsg *,
a552a72e
VB
447 struct hmsg *);
448void client_handle_shutdown(struct lldpd *, struct hmsg *,
449 struct hmsg *);
450
b5562b23 451/* priv.c */
a2993d83 452void priv_init(char*);
a7502371
VB
453int priv_ctl_create();
454void priv_ctl_cleanup();
455char *priv_gethostbyname();
456int priv_open(char*);
457int priv_ethtool(char*, struct ethtool_cmd*);
849954d7 458int priv_iface_init(const char *);
ef76f920 459int priv_iface_multicast(const char *, u_int8_t *, int);
d72a05d4 460int priv_snmp_socket(struct sockaddr_un *);
4afe659e
VB
461
462/* privsep_fdpass.c */
463int receive_fd(int);
464void send_fd(int, int);
b5562b23 465
43c02e7b 466#endif /* _LLDPD_H */