1 /* -*- mode: c; c-file-style: "openbsd" -*- */
3 * Copyright (c) 2012 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.
18 #include <sys/queue.h>
19 #include "../lldpd-structs.h"
20 #include "../compat/compat.h"
21 #include "../marshal.h"
25 struct lldpctl_conn_t
{
26 /* the Unix-domain socket to connect to lldpd */
29 /* Callback handling */
30 lldpctl_recv_callback recv
; /* Receive callback */
31 lldpctl_send_callback send
; /* Send callback */
32 void *user_data
; /* Callback user data */
34 /* IO state handling. */
35 uint8_t *input_buffer
; /* Current input/output buffer */
36 uint8_t *output_buffer
; /* Current input/output buffer */
37 size_t input_buffer_len
;
38 size_t output_buffer_len
;
40 #define CONN_STATE_IDLE 0
41 #define CONN_STATE_GET_INTERFACES_SEND 1
42 #define CONN_STATE_GET_INTERFACES_RECV 2
43 #define CONN_STATE_GET_PORT_SEND 3
44 #define CONN_STATE_GET_PORT_RECV 4
45 #define CONN_STATE_SET_PORT_SEND 5
46 #define CONN_STATE_SET_PORT_RECV 6
47 #define CONN_STATE_SET_WATCH_SEND 7
48 #define CONN_STATE_SET_WATCH_RECV 8
49 #define CONN_STATE_GET_CONFIG_SEND 9
50 #define CONN_STATE_GET_CONFIG_RECV 10
51 #define CONN_STATE_SET_CONFIG_SEND 11
52 #define CONN_STATE_SET_CONFIG_RECV 12
53 #define CONN_STATE_GET_CHASSIS_SEND 13
54 #define CONN_STATE_GET_CHASSIS_RECV 14
55 #define CONN_STATE_GET_DEFAULT_PORT_SEND 15
56 #define CONN_STATE_GET_DEFAULT_PORT_RECV 16
57 int state
; /* Current state */
58 /* Data attached to the state. It is used to check that we are using the
59 * same data as a previous call until the state machine goes to
61 char state_data
[IFNAMSIZ
+ 64];
63 lldpctl_error_t error
; /* Last error */
65 /* Handling notifications */
66 lldpctl_change_callback watch_cb
;
71 /* User data for synchronous callbacks. */
72 struct lldpctl_conn_sync_t
{
73 int fd
; /* File descriptor to the socket. */
76 ssize_t
_lldpctl_needs(lldpctl_conn_t
*lldpctl
, size_t length
);
77 int _lldpctl_do_something(lldpctl_conn_t
*conn
,
78 int state_send
, int state_recv
, const char *state_data
,
80 void *to_send
, struct marshal_info
*mi_send
,
81 void **to_recv
, struct marshal_info
*mi_recv
);
84 #define SET_ERROR(conn, x) ((conn)->error = x)
85 #define RESET_ERROR(conn) SET_ERROR((conn), LLDPCTL_NO_ERROR)
88 /* atom.c and atom-private.c */
108 #ifdef ENABLE_LLDPMED
109 atom_med_policies_list
,
111 atom_med_locations_list
,
113 atom_med_caelements_list
,
124 void *_lldpctl_alloc_in_atom(lldpctl_atom_t
*, size_t);
125 const char *_lldpctl_dump_in_atom(lldpctl_atom_t
*, const uint8_t *, size_t, char, size_t);
128 TAILQ_ENTRY(atom_buffer
) next
;
132 struct lldpctl_atom_t
{
135 lldpctl_conn_t
*conn
;
136 TAILQ_HEAD(, atom_buffer
) buffers
; /* List of buffers */
139 void (*free
)(lldpctl_atom_t
*);
142 lldpctl_atom_iter_t
*(*iter
)(lldpctl_atom_t
*);
143 lldpctl_atom_iter_t
*(*next
)(lldpctl_atom_t
*, lldpctl_atom_iter_t
*);
144 lldpctl_atom_t
*(*value
)(lldpctl_atom_t
*, lldpctl_atom_iter_t
*);
147 lldpctl_atom_t
*(*get
)(lldpctl_atom_t
*, lldpctl_key_t
);
148 const char *(*get_str
)(lldpctl_atom_t
*, lldpctl_key_t
);
149 const u_int8_t
*(*get_buffer
)(lldpctl_atom_t
*, lldpctl_key_t
, size_t *);
150 long int (*get_int
)(lldpctl_atom_t
*, lldpctl_key_t
);
153 lldpctl_atom_t
*(*set
)(lldpctl_atom_t
*, lldpctl_key_t
, lldpctl_atom_t
*);
154 lldpctl_atom_t
*(*set_str
)(lldpctl_atom_t
*, lldpctl_key_t
, const char *);
155 lldpctl_atom_t
*(*set_buffer
)(lldpctl_atom_t
*, lldpctl_key_t
, const u_int8_t
*, size_t);
156 lldpctl_atom_t
*(*set_int
)(lldpctl_atom_t
*, lldpctl_key_t
, long int);
157 lldpctl_atom_t
*(*create
)(lldpctl_atom_t
*);
160 struct _lldpctl_atom_config_t
{
162 struct lldpd_config
*config
;
165 struct _lldpctl_atom_interfaces_list_t
{
167 struct lldpd_interface_list
*ifs
;
170 struct _lldpctl_atom_interface_t
{
175 struct _lldpctl_atom_chassis_t
{
177 struct lldpd_chassis
*chassis
;
178 struct _lldpctl_atom_port_t
*parent
; /* Optional: parent of this atom (owning our reference) */
179 int embedded
; /* This atom is "embedded" (not refcounted) */
182 struct _lldpctl_atom_port_t
{
184 int local
; /* Local or remote port? */
185 struct lldpd_hardware
*hardware
; /* Local port only (but optional) */
186 struct lldpd_port
*port
; /* Local and remote */
187 struct _lldpctl_atom_port_t
*parent
; /* Local port if we are a remote port */
188 lldpctl_atom_t
*chassis
; /* Internal atom for chassis */
191 /* Can represent any simple list holding just a reference to a port. */
192 struct _lldpctl_atom_any_list_t
{
194 struct _lldpctl_atom_port_t
*parent
;
197 struct _lldpctl_atom_mgmts_list_t
{
199 lldpctl_atom_t
*parent
;
200 struct lldpd_chassis
*chassis
; /* Chassis containing the list of IP addresses */
203 struct _lldpctl_atom_mgmt_t
{
205 lldpctl_atom_t
*parent
;
206 struct lldpd_mgmt
*mgmt
;
210 struct _lldpctl_atom_dot3_power_t
{
212 struct _lldpctl_atom_port_t
*parent
;
217 struct _lldpctl_atom_vlan_t
{
219 struct _lldpctl_atom_port_t
*parent
;
220 struct lldpd_vlan
*vlan
;
223 struct _lldpctl_atom_ppvid_t
{
225 struct _lldpctl_atom_port_t
*parent
;
226 struct lldpd_ppvid
*ppvid
;
229 struct _lldpctl_atom_pi_t
{
231 struct _lldpctl_atom_port_t
*parent
;
236 #ifdef ENABLE_LLDPMED
237 struct _lldpctl_atom_med_policy_t
{
239 struct _lldpctl_atom_port_t
*parent
;
240 struct lldpd_med_policy
*policy
;
243 struct _lldpctl_atom_med_location_t
{
245 struct _lldpctl_atom_port_t
*parent
;
246 struct lldpd_med_loc
*location
;
249 /* This list should have the same structure than _llpdctl_atom_any_list_t */
250 struct _lldpctl_atom_med_caelements_list_t
{
252 struct _lldpctl_atom_med_location_t
*parent
;
255 struct _lldpctl_atom_med_caelement_t
{
257 struct _lldpctl_atom_med_location_t
*parent
;
263 struct _lldpctl_atom_med_power_t
{
265 struct _lldpctl_atom_port_t
*parent
;
270 struct _lldpctl_atom_custom_list_t
{
272 struct _lldpctl_atom_port_t
*parent
;
273 struct lldpd_custom_list
*list
;
276 struct _lldpctl_atom_custom_t
{
278 struct _lldpctl_atom_port_t
*parent
;
280 struct lldpd_custom
*tlv
;
284 struct lldpctl_atom_t
*_lldpctl_new_atom(lldpctl_conn_t
*conn
, atom_t type
, ...);
288 struct atom_map
*next
;
292 void atom_map_register(struct atom_map
*map
, int);
293 void init_atom_map(void);
295 #define ATOM_MAP_REGISTER(NAME, PRIO) void init_atom_map_ ## NAME() { atom_map_register(& NAME, PRIO); }
297 struct atom_builder
{
298 atom_t type
; /* Atom type */
299 size_t size
; /* Size of structure to allocate */
300 int (*init
)(lldpctl_atom_t
*, va_list); /* Optional additional init steps */
301 void (*free
)(lldpctl_atom_t
*); /* Optional deallocation steps */
303 lldpctl_atom_iter_t
* (*iter
)(lldpctl_atom_t
*); /* Optional, return an iterator for this object */
304 lldpctl_atom_iter_t
* (*next
)(lldpctl_atom_t
*, lldpctl_atom_iter_t
*); /* Return the next object for the provided iterator */
305 lldpctl_atom_t
* (*value
)(lldpctl_atom_t
*, lldpctl_atom_iter_t
*); /* Return the current object for the provided iterator */
307 lldpctl_atom_t
* (*get
)(lldpctl_atom_t
*, lldpctl_key_t
);
308 const char* (*get_str
)(lldpctl_atom_t
*, lldpctl_key_t
);
309 const u_int8_t
* (*get_buffer
)(lldpctl_atom_t
*, lldpctl_key_t
, size_t *);
310 long int (*get_int
)(lldpctl_atom_t
*, lldpctl_key_t
);
312 lldpctl_atom_t
* (*set
)(lldpctl_atom_t
*, lldpctl_key_t
, lldpctl_atom_t
*);
313 lldpctl_atom_t
* (*set_str
)(lldpctl_atom_t
*, lldpctl_key_t
, const char *);
314 lldpctl_atom_t
* (*set_buffer
)(lldpctl_atom_t
*, lldpctl_key_t
, const u_int8_t
*, size_t);
315 lldpctl_atom_t
* (*set_int
)(lldpctl_atom_t
*, lldpctl_key_t
, long int);
316 lldpctl_atom_t
* (*create
)(lldpctl_atom_t
*);
317 struct atom_builder
*nextb
;
320 void atom_builder_register(struct atom_builder
*builder
, int);
321 void init_atom_builder(void);
323 #define ATOM_BUILDER_REGISTER(NAME, PRIO) void init_atom_builder_ ## NAME() { atom_builder_register(& NAME, PRIO); }