]> git.ipfire.org Git - thirdparty/lldpd.git/blame - src/lldpd.h
Don't free statically allocated port.
[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
43c02e7b
VB
209struct lldpd_hardware {
210 TAILQ_ENTRY(lldpd_hardware) h_entries;
211
6e75df87
VB
212 fd_set h_recvfds; /* FD for reception */
213 int h_sendfd; /* FD for sending, only used by h_ops */
214 struct lldpd_ops *h_ops; /* Hardware-dependent functions */
215 void *h_data; /* Hardware-dependent data */
43c02e7b 216
43c02e7b 217 int h_mtu;
6e75df87
VB
218 int h_flags; /* Packets will be sent only
219 if IFF_RUNNING. Will be
220 removed if this is left
221 to 0. */
222 int h_ifindex; /* Interface index, used by SNMP */
223 char h_ifname[IFNAMSIZ]; /* Should be unique */
43c02e7b
VB
224 u_int8_t h_lladdr[ETHER_ADDR_LEN];
225
226 u_int64_t h_tx_cnt;
227 u_int64_t h_rx_cnt;
228 u_int64_t h_rx_discarded_cnt;
229 u_int64_t h_rx_ageout_cnt;
37387046 230 u_int64_t h_rx_unrecognized_cnt;
43c02e7b 231
75068724
VB
232 struct lldpd_port h_lport; /* Port attached to this hardware port */
233 TAILQ_HEAD(, lldpd_port) h_rports; /* Remote ports */
43c02e7b
VB
234};
235
236struct lldpd_interface {
237 TAILQ_ENTRY(lldpd_interface) next;
238 char *name;
239};
0c8f36f3 240#define STRUCT_LLDPD_INTERFACE "(Ls)"
43c02e7b
VB
241
242struct lldpd_client {
243 TAILQ_ENTRY(lldpd_client) next;
244 int fd;
245};
246
77507b69 247#define PROTO_SEND_SIG struct lldpd *, struct lldpd_hardware *
43c02e7b
VB
248#define PROTO_DECODE_SIG struct lldpd *, char *, int, struct lldpd_hardware *, struct lldpd_chassis **, struct lldpd_port **
249#define PROTO_GUESS_SIG char *, int
250
43c02e7b 251struct protocol {
f2dcb180
VB
252#define LLDPD_MODE_LLDP 1
253#define LLDPD_MODE_CDPV1 2
254#define LLDPD_MODE_CDPV2 3
255#define LLDPD_MODE_SONMP 4
256#define LLDPD_MODE_EDP 5
257#define LLDPD_MODE_FDP 6
43c02e7b
VB
258 int mode; /* > 0 mode identifier (unique per protocol) */
259 int enabled; /* Is this protocol enabled? */
260 char *name; /* Name of protocol */
261 char arg; /* Argument to enable this protocol */
262 int(*send)(PROTO_SEND_SIG); /* How to send a frame */
263 int(*decode)(PROTO_DECODE_SIG); /* How to decode a frame */
264 int(*guess)(PROTO_GUESS_SIG); /* Can be NULL, use MAC address in this case */
265 u_int8_t mac[ETH_ALEN]; /* Destination MAC address used by this protocol */
266 struct sock_filter *filter; /* BPF filter */
267 size_t filterlen; /* Size of BPF filter */
268};
269
270struct lldpd {
271 int g_sock;
272 int g_delay;
273
274 struct protocol *g_protocols;
740593ff
VB
275#ifdef ENABLE_LLDPMED
276 int g_noinventory;
277#endif
43c02e7b
VB
278
279 time_t g_lastsent;
280 int g_lastrid;
281#ifdef USE_SNMP
282 int g_snmp;
283#endif /* USE_SNMP */
284
285 /* Unix socket handling */
286 int g_ctl;
287 TAILQ_HEAD(, lldpd_client) g_clients;
288
289 char *g_mgmt_pattern;
290
77507b69 291#define LOCAL_CHASSIS(cfg) ((struct lldpd_chassis *)(TAILQ_FIRST(&cfg->g_chassis)))
75068724 292 TAILQ_HEAD(, lldpd_chassis) g_chassis;
43c02e7b
VB
293 TAILQ_HEAD(, lldpd_hardware) g_hardware;
294};
295
6e75df87
VB
296typedef void(*lldpd_ifhandlers)(struct lldpd *, struct ifaddrs *);
297
43c02e7b
VB
298enum hmsg_type {
299 HMSG_NONE,
300 HMSG_GET_INTERFACES,
84853b92 301 HMSG_GET_NB_PORTS,
43c02e7b 302 HMSG_GET_PORT,
84853b92 303 HMSG_GET_CHASSIS,
43c02e7b 304 HMSG_GET_VLANS,
740593ff 305 HMSG_SET_LOCATION,
43c02e7b
VB
306 HMSG_SHUTDOWN
307};
308
309struct hmsg_hdr {
310 enum hmsg_type type;
311 int16_t len;
312 pid_t pid;
313} __attribute__ ((__packed__));
314
315struct hmsg {
316 struct hmsg_hdr hdr;
317 void *data;
318} __attribute__ ((__packed__));
319
320#define HMSG_HEADER_SIZE sizeof(struct hmsg_hdr)
321#define MAX_HMSGSIZE 8192
322
323/* lldpd.c */
6e75df87
VB
324struct lldpd_hardware *lldpd_get_hardware(struct lldpd *, char *);
325struct lldpd_hardware *lldpd_alloc_hardware(struct lldpd *, char *);
326void lldpd_hardware_cleanup(struct lldpd*, struct lldpd_hardware *);
a1347cd8 327#ifdef ENABLE_DOT1
43c02e7b 328void lldpd_vlan_cleanup(struct lldpd_port *);
a1347cd8 329#endif
43c02e7b 330void lldpd_remote_cleanup(struct lldpd *, struct lldpd_hardware *, int);
a0edeaf8 331void lldpd_port_cleanup(struct lldpd_port *, int);
77507b69 332void lldpd_chassis_cleanup(struct lldpd_chassis *, int);
43c02e7b
VB
333
334/* lldp.c */
335int lldp_send(PROTO_SEND_SIG);
336int lldp_decode(PROTO_DECODE_SIG);
337
338/* cdp.c */
4bad1937 339#ifdef ENABLE_CDP
43c02e7b
VB
340int cdpv1_send(PROTO_SEND_SIG);
341int cdpv2_send(PROTO_SEND_SIG);
43c02e7b
VB
342int cdpv1_guess(PROTO_GUESS_SIG);
343int cdpv2_guess(PROTO_GUESS_SIG);
4bad1937
VB
344#endif
345#if defined (ENABLE_CDP) || defined (ENABLE_FDP)
346int cdp_decode(PROTO_DECODE_SIG);
347#endif
348#ifdef ENABLE_FDP
349int fdp_send(PROTO_SEND_SIG);
350#endif
43c02e7b 351
4bad1937 352#ifdef ENABLE_SONMP
43c02e7b
VB
353/* sonmp.c */
354int sonmp_send(PROTO_SEND_SIG);
355int sonmp_decode(PROTO_DECODE_SIG);
4bad1937 356#endif
43c02e7b 357
4bad1937 358#ifdef ENABLE_EDP
43c02e7b
VB
359/* edp.c */
360int edp_send(PROTO_SEND_SIG);
361int edp_decode(PROTO_DECODE_SIG);
4bad1937 362#endif
43c02e7b
VB
363
364/* ctl.c */
b5562b23 365int ctl_create(char *);
43c02e7b 366int ctl_connect(char *);
b5562b23 367void ctl_cleanup(char *);
43c02e7b
VB
368int ctl_accept(struct lldpd *, int);
369int ctl_close(struct lldpd *, int);
370void ctl_msg_init(struct hmsg *, enum hmsg_type);
371int ctl_msg_send(int, struct hmsg *);
372int ctl_msg_recv(int, struct hmsg *);
373int ctl_msg_pack_list(char *, void *, unsigned int, struct hmsg *, void **);
374int ctl_msg_unpack_list(char *, void *, unsigned int, struct hmsg *, void **);
375int ctl_msg_pack_structure(char *, void *, unsigned int, struct hmsg *, void **);
376int ctl_msg_unpack_structure(char *, void *, unsigned int, struct hmsg *, void **);
377
6e75df87
VB
378/* interfaces.c */
379void lldpd_ifh_eth(struct lldpd *, struct ifaddrs *);
380void lldpd_ifh_vlan(struct lldpd *, struct ifaddrs *);
381void lldpd_ifh_mgmt(struct lldpd *, struct ifaddrs *);
382
383/* dmi.c */
89840df0
VB
384#ifdef ENABLE_LLDPMED
385char *dmi_hw();
386char *dmi_fw();
387char *dmi_sn();
388char *dmi_manuf();
389char *dmi_model();
390char *dmi_asset();
391#endif
43c02e7b
VB
392
393/* log.c */
394void log_init(int);
395void log_warn(const char *, ...);
396#define LLOG_WARN(x,...) log_warn("%s: " x, __FUNCTION__, ##__VA_ARGS__)
397void log_warnx(const char *, ...);
398#define LLOG_WARNX(x,...) log_warnx("%s: " x, __FUNCTION__, ##__VA_ARGS__)
399void log_info(const char *, ...);
400#define LLOG_INFO(x,...) log_info("%s: " x, __FUNCTION__, ##__VA_ARGS__)
401void log_debug(const char *, ...);
402#define LLOG_DEBUG(x,...) log_debug("%s: " x, __FUNCTION__, ##__VA_ARGS__)
403void fatal(const char *);
404void fatalx(const char *);
405
406/* agent.c */
407void agent_shutdown();
408void agent_init(struct lldpd *, int);
409
d72a05d4
VB
410/* agent_priv.c */
411void agent_priv_register_domain();
412
43c02e7b
VB
413/* strlcpy.c */
414size_t strlcpy(char *, const char *, size_t);
415
a552a72e
VB
416/* client.c */
417struct client_handle {
418 enum hmsg_type type;
419 void (*handle)(struct lldpd*, struct hmsg*, struct hmsg*);
420};
421
422void client_handle_client(struct lldpd *, struct lldpd_client *,
423 char *, int);
424void client_handle_none(struct lldpd *, struct hmsg *,
425 struct hmsg *);
426void client_handle_get_interfaces(struct lldpd *, struct hmsg *,
427 struct hmsg *);
740593ff 428void client_handle_port_related(struct lldpd *, struct hmsg *,
a552a72e
VB
429 struct hmsg *);
430void client_handle_shutdown(struct lldpd *, struct hmsg *,
431 struct hmsg *);
432
b5562b23 433/* priv.c */
a2993d83 434void priv_init(char*);
a7502371
VB
435int priv_ctl_create();
436void priv_ctl_cleanup();
437char *priv_gethostbyname();
438int priv_open(char*);
439int priv_ethtool(char*, struct ethtool_cmd*);
6e75df87 440int priv_iface_eth_init(struct lldpd_hardware *);
ef76f920 441int priv_iface_multicast(const char *, u_int8_t *, int);
d72a05d4 442int priv_snmp_socket(struct sockaddr_un *);
4afe659e
VB
443
444/* privsep_fdpass.c */
445int receive_fd(int);
446void send_fd(int, int);
b5562b23 447
43c02e7b 448#endif /* _LLDPD_H */