2 * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx>
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.
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.
27 #include <sys/queue.h>
28 #ifndef INCLUDE_LINUX_IF_H
31 #include <arpa/inet.h>
34 #include <net/ethernet.h>
35 #include <netinet/in.h>
36 #include <linux/ethtool.h>
45 #define LLDPD_TX_DELAY 30
46 #define LLDPD_TX_MSGDELAY 1
47 #define LLDPD_CTL_SOCKET "/var/run/lldpd.socket"
48 #define LLDPD_PID_FILE "/var/run/lldpd.pid"
50 #define UNIX_PATH_MAX 108
52 #define USING_AGENTX_SUBAGENT_MODULE 1
55 TAILQ_ENTRY(lldpd_vlan
) v_entries
;
59 #define STRUCT_LLDPD_VLAN "Lsw"
61 struct lldpd_chassis
{
62 u_int8_t c_id_subtype
;
68 u_int16_t c_cap_available
;
69 u_int16_t c_cap_enabled
;
73 struct in_addr c_mgmt
;
76 #define STRUCT_LLDPD_CHASSIS "bCsswwwll"
79 u_int8_t p_id_subtype
;
86 u_int8_t p_autoneg_support
;
87 u_int8_t p_autoneg_enabled
;
88 u_int16_t p_autoneg_advertised
;
91 TAILQ_HEAD(, lldpd_vlan
) p_vlans
;
93 #define STRUCT_LLDPD_PORT "bCslbbwwPP"
97 unsigned char frame
[];
100 struct lldpd_hardware
{
101 TAILQ_ENTRY(lldpd_hardware
) h_entries
;
103 #define INTERFACE_OPENED(x) ((x)->h_raw != -1)
106 int h_raw_real
; /* For bonding */
107 int h_master
; /* For bonding */
109 #define LLDPD_MODE_ANY 0
110 #define LLDPD_MODE_LLDP 1
111 #define LLDPD_MODE_CDPV1 2
112 #define LLDPD_MODE_CDPV2 3
113 #define LLDPD_MODE_SONMP 4
114 #define LLDPD_MODE_EDP 5
115 #define LLDPD_MODE_FDP 6
120 char h_ifname
[IFNAMSIZ
];
121 u_int8_t h_lladdr
[ETHER_ADDR_LEN
];
125 u_int64_t h_rx_discarded_cnt
;
126 u_int64_t h_rx_ageout_cnt
;
127 u_int64_t h_rx_unrecognized_cnt
;
129 u_int8_t
*h_proto_macs
;
130 time_t h_start_probe
;
132 struct lldpd_port h_lport
;
133 time_t h_llastchange
;
134 struct lldpd_frame
*h_llastframe
;
136 time_t h_rlastchange
;
137 time_t h_rlastupdate
;
139 struct lldpd_frame
*h_rlastframe
;
140 struct lldpd_port
*h_rport
;
141 struct lldpd_chassis
*h_rchassis
;
144 /* lldpd_vif can be casted to lldpd_hardware on some cases */
146 TAILQ_ENTRY(lldpd_vif
) vif_entries
;
148 int vif_raw_real
; /* Not used */
149 int vif_master
; /* Not used */
150 int vif_mode
; /* Not used */
153 char vif_ifname
[IFNAMSIZ
];
155 /* No more compatibility with struct lldpd_hardware from here */
156 struct lldpd_hardware
*vif_real
;
159 struct lldpd_interface
{
160 TAILQ_ENTRY(lldpd_interface
) next
;
163 #define STRUCT_LLDPD_INTERFACE "Ls"
165 struct lldpd_client
{
166 TAILQ_ENTRY(lldpd_client
) next
;
170 #define PROTO_SEND_SIG struct lldpd *, struct lldpd_chassis *, struct lldpd_hardware *
171 #define PROTO_DECODE_SIG struct lldpd *, char *, int, struct lldpd_hardware *, struct lldpd_chassis **, struct lldpd_port **
172 #define PROTO_GUESS_SIG char *, int
176 int mode
; /* > 0 mode identifier (unique per protocol) */
177 int enabled
; /* Is this protocol enabled? */
178 char *name
; /* Name of protocol */
179 char arg
; /* Argument to enable this protocol */
180 int(*send
)(PROTO_SEND_SIG
); /* How to send a frame */
181 int(*decode
)(PROTO_DECODE_SIG
); /* How to decode a frame */
182 int(*guess
)(PROTO_GUESS_SIG
); /* Can be NULL, use MAC address in this case */
183 u_int8_t mac
[ETH_ALEN
]; /* Destination MAC address used by this protocol */
184 struct sock_filter
*filter
; /* BPF filter */
185 size_t filterlen
; /* Size of BPF filter */
192 struct protocol
*g_protocols
;
193 int g_multi
; /* Set to 1 if multiple protocols */
201 #endif /* USE_SNMP */
203 /* Unix socket handling */
205 TAILQ_HEAD(, lldpd_client
) g_clients
;
207 char *g_mgmt_pattern
;
209 struct lldpd_chassis g_lchassis
;
211 TAILQ_HEAD(, lldpd_hardware
) g_hardware
;
212 TAILQ_HEAD(, lldpd_vif
) g_vif
;
228 } __attribute__ ((__packed__
));
233 } __attribute__ ((__packed__
));
235 #define HMSG_HEADER_SIZE sizeof(struct hmsg_hdr)
236 #define MAX_HMSGSIZE 8192
239 void lldpd_cleanup(struct lldpd
*);
240 void lldpd_vlan_cleanup(struct lldpd_port
*);
241 void lldpd_remote_cleanup(struct lldpd
*, struct lldpd_hardware
*, int);
242 void lldpd_port_cleanup(struct lldpd_port
*);
243 void lldpd_chassis_cleanup(struct lldpd_chassis
*);
246 int lldp_send(PROTO_SEND_SIG
);
247 int lldp_decode(PROTO_DECODE_SIG
);
250 int cdpv1_send(PROTO_SEND_SIG
);
251 int cdpv2_send(PROTO_SEND_SIG
);
252 int fdp_send(PROTO_SEND_SIG
);
253 int cdp_decode(PROTO_DECODE_SIG
);
254 int cdpv1_guess(PROTO_GUESS_SIG
);
255 int cdpv2_guess(PROTO_GUESS_SIG
);
258 int sonmp_send(PROTO_SEND_SIG
);
259 int sonmp_decode(PROTO_DECODE_SIG
);
262 int edp_send(PROTO_SEND_SIG
);
263 int edp_decode(PROTO_DECODE_SIG
);
266 int ctl_create(char *);
267 int ctl_connect(char *);
268 void ctl_cleanup(char *);
269 int ctl_accept(struct lldpd
*, int);
270 int ctl_close(struct lldpd
*, int);
271 void ctl_msg_init(struct hmsg
*, enum hmsg_type
);
272 int ctl_msg_send(int, struct hmsg
*);
273 int ctl_msg_recv(int, struct hmsg
*);
274 int ctl_msg_pack_list(char *, void *, unsigned int, struct hmsg
*, void **);
275 int ctl_msg_unpack_list(char *, void *, unsigned int, struct hmsg
*, void **);
276 int ctl_msg_pack_structure(char *, void *, unsigned int, struct hmsg
*, void **);
277 int ctl_msg_unpack_structure(char *, void *, unsigned int, struct hmsg
*, void **);
280 int iface_is_bridge(struct lldpd
*, const char *);
281 int iface_is_bridged(struct lldpd
*, const char *);
282 int iface_is_wireless(struct lldpd
*, const char *);
283 int iface_is_vlan(struct lldpd
*, const char *);
284 int iface_is_bond(struct lldpd
*, const char *);
285 int iface_is_bond_slave(struct lldpd
*,
286 const char *, const char *);
287 int iface_is_enslaved(struct lldpd
*, const char *);
291 void log_warn(const char *, ...);
292 #define LLOG_WARN(x,...) log_warn("%s: " x, __FUNCTION__, ##__VA_ARGS__)
293 void log_warnx(const char *, ...);
294 #define LLOG_WARNX(x,...) log_warnx("%s: " x, __FUNCTION__, ##__VA_ARGS__)
295 void log_info(const char *, ...);
296 #define LLOG_INFO(x,...) log_info("%s: " x, __FUNCTION__, ##__VA_ARGS__)
297 void log_debug(const char *, ...);
298 #define LLOG_DEBUG(x,...) log_debug("%s: " x, __FUNCTION__, ##__VA_ARGS__)
299 void fatal(const char *);
300 void fatalx(const char *);
303 void agent_shutdown();
304 void agent_init(struct lldpd
*, int);
307 void agent_priv_register_domain();
310 size_t strlcpy(char *, const char *, size_t);
313 void iov_dump(struct lldpd_frame
**, struct iovec
*, int);
314 u_int16_t
iov_checksum(struct iovec
*, int, int);
317 struct client_handle
{
319 void (*handle
)(struct lldpd
*, struct hmsg
*, struct hmsg
*);
322 void client_handle_client(struct lldpd
*, struct lldpd_client
*,
324 void client_handle_none(struct lldpd
*, struct hmsg
*,
326 void client_handle_get_interfaces(struct lldpd
*, struct hmsg
*,
328 void client_handle_get_port_related(struct lldpd
*, struct hmsg
*,
330 void client_handle_shutdown(struct lldpd
*, struct hmsg
*,
334 void priv_init(char*);
335 int priv_ctl_create();
336 void priv_ctl_cleanup();
337 char *priv_gethostbyname();
338 int priv_open(char*);
339 int priv_ethtool(char*, struct ethtool_cmd
*);
340 int priv_iface_init(struct lldpd_hardware
*, int);
341 int priv_iface_multicast(char *, u_int8_t
*, int);
342 int priv_snmp_socket(struct sockaddr_un
*);
344 /* privsep_fdpass.c */
346 void send_fd(int, int);
348 #endif /* _LLDPD_H */