diff options
Diffstat (limited to 'src/lib/atoms/dot1.c')
-rw-r--r-- | src/lib/atoms/dot1.c | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/src/lib/atoms/dot1.c b/src/lib/atoms/dot1.c new file mode 100644 index 0000000..c2feda0 --- /dev/null +++ b/src/lib/atoms/dot1.c @@ -0,0 +1,250 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2015 Vincent Bernat <vincent@bernat.im> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <arpa/inet.h> + +#include "../lldpctl.h" +#include "../../log.h" +#include "../atom.h" +#include "../helpers.h" + +#ifdef ENABLE_DOT1 + +static lldpctl_atom_iter_t * +_lldpctl_atom_iter_vlans_list(lldpctl_atom_t *atom) +{ + struct _lldpctl_atom_any_list_t *vlist = + (struct _lldpctl_atom_any_list_t *)atom; + return (lldpctl_atom_iter_t *)TAILQ_FIRST(&vlist->parent->port->p_vlans); +} + +static lldpctl_atom_iter_t * +_lldpctl_atom_next_vlans_list(lldpctl_atom_t *atom, lldpctl_atom_iter_t *iter) +{ + struct lldpd_vlan *vlan = (struct lldpd_vlan *)iter; + return (lldpctl_atom_iter_t *)TAILQ_NEXT(vlan, v_entries); +} + +static lldpctl_atom_t * +_lldpctl_atom_value_vlans_list(lldpctl_atom_t *atom, lldpctl_atom_iter_t *iter) +{ + struct _lldpctl_atom_any_list_t *vlist = + (struct _lldpctl_atom_any_list_t *)atom; + struct lldpd_vlan *vlan = (struct lldpd_vlan *)iter; + return _lldpctl_new_atom(atom->conn, atom_vlan, vlist->parent, vlan); +} + +static int +_lldpctl_atom_new_vlan(lldpctl_atom_t *atom, va_list ap) +{ + struct _lldpctl_atom_vlan_t *vlan = (struct _lldpctl_atom_vlan_t *)atom; + vlan->parent = va_arg(ap, struct _lldpctl_atom_port_t *); + vlan->vlan = va_arg(ap, struct lldpd_vlan *); + lldpctl_atom_inc_ref((lldpctl_atom_t *)vlan->parent); + return 1; +} + +static void +_lldpctl_atom_free_vlan(lldpctl_atom_t *atom) +{ + struct _lldpctl_atom_vlan_t *vlan = (struct _lldpctl_atom_vlan_t *)atom; + lldpctl_atom_dec_ref((lldpctl_atom_t *)vlan->parent); +} + +static const char * +_lldpctl_atom_get_str_vlan(lldpctl_atom_t *atom, lldpctl_key_t key) +{ + struct _lldpctl_atom_vlan_t *m = (struct _lldpctl_atom_vlan_t *)atom; + + /* Local and remote port */ + switch (key) { + case lldpctl_k_vlan_name: + return m->vlan->v_name; + default: + SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); + return NULL; + } +} + +static long int +_lldpctl_atom_get_int_vlan(lldpctl_atom_t *atom, lldpctl_key_t key) +{ + struct _lldpctl_atom_vlan_t *m = (struct _lldpctl_atom_vlan_t *)atom; + + /* Local and remote port */ + switch (key) { + case lldpctl_k_vlan_id: + return m->vlan->v_vid; + default: + return SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); + } +} + +static lldpctl_atom_iter_t * +_lldpctl_atom_iter_ppvids_list(lldpctl_atom_t *atom) +{ + struct _lldpctl_atom_any_list_t *vlist = + (struct _lldpctl_atom_any_list_t *)atom; + return (lldpctl_atom_iter_t *)TAILQ_FIRST(&vlist->parent->port->p_ppvids); +} + +static lldpctl_atom_iter_t * +_lldpctl_atom_next_ppvids_list(lldpctl_atom_t *atom, lldpctl_atom_iter_t *iter) +{ + struct lldpd_ppvid *ppvid = (struct lldpd_ppvid *)iter; + return (lldpctl_atom_iter_t *)TAILQ_NEXT(ppvid, p_entries); +} + +static lldpctl_atom_t * +_lldpctl_atom_value_ppvids_list(lldpctl_atom_t *atom, lldpctl_atom_iter_t *iter) +{ + struct _lldpctl_atom_any_list_t *vlist = + (struct _lldpctl_atom_any_list_t *)atom; + struct lldpd_ppvid *ppvid = (struct lldpd_ppvid *)iter; + return _lldpctl_new_atom(atom->conn, atom_ppvid, vlist->parent, ppvid); +} + +static int +_lldpctl_atom_new_ppvid(lldpctl_atom_t *atom, va_list ap) +{ + struct _lldpctl_atom_ppvid_t *ppvid = (struct _lldpctl_atom_ppvid_t *)atom; + ppvid->parent = va_arg(ap, struct _lldpctl_atom_port_t *); + ppvid->ppvid = va_arg(ap, struct lldpd_ppvid *); + lldpctl_atom_inc_ref((lldpctl_atom_t *)ppvid->parent); + return 1; +} + +static void +_lldpctl_atom_free_ppvid(lldpctl_atom_t *atom) +{ + struct _lldpctl_atom_ppvid_t *ppvid = (struct _lldpctl_atom_ppvid_t *)atom; + lldpctl_atom_dec_ref((lldpctl_atom_t *)ppvid->parent); +} + +static long int +_lldpctl_atom_get_int_ppvid(lldpctl_atom_t *atom, lldpctl_key_t key) +{ + struct _lldpctl_atom_ppvid_t *m = (struct _lldpctl_atom_ppvid_t *)atom; + + /* Local and remote port */ + switch (key) { + case lldpctl_k_ppvid_id: + return m->ppvid->p_ppvid; + case lldpctl_k_ppvid_status: + return m->ppvid->p_cap_status; + default: + return SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); + } +} + +static lldpctl_atom_iter_t * +_lldpctl_atom_iter_pis_list(lldpctl_atom_t *atom) +{ + struct _lldpctl_atom_any_list_t *vlist = + (struct _lldpctl_atom_any_list_t *)atom; + return (lldpctl_atom_iter_t *)TAILQ_FIRST(&vlist->parent->port->p_pids); +} + +static lldpctl_atom_iter_t * +_lldpctl_atom_next_pis_list(lldpctl_atom_t *atom, lldpctl_atom_iter_t *iter) +{ + struct lldpd_pi *pi = (struct lldpd_pi *)iter; + return (lldpctl_atom_iter_t *)TAILQ_NEXT(pi, p_entries); +} + +static lldpctl_atom_t * +_lldpctl_atom_value_pis_list(lldpctl_atom_t *atom, lldpctl_atom_iter_t *iter) +{ + struct _lldpctl_atom_any_list_t *vlist = + (struct _lldpctl_atom_any_list_t *)atom; + struct lldpd_pi *pi = (struct lldpd_pi *)iter; + return _lldpctl_new_atom(atom->conn, atom_pi, vlist->parent, pi); +} + +static int +_lldpctl_atom_new_pi(lldpctl_atom_t *atom, va_list ap) +{ + struct _lldpctl_atom_pi_t *pi = (struct _lldpctl_atom_pi_t *)atom; + pi->parent = va_arg(ap, struct _lldpctl_atom_port_t *); + pi->pi = va_arg(ap, struct lldpd_pi *); + lldpctl_atom_inc_ref((lldpctl_atom_t *)pi->parent); + return 1; +} + +static void +_lldpctl_atom_free_pi(lldpctl_atom_t *atom) +{ + struct _lldpctl_atom_pi_t *pi = (struct _lldpctl_atom_pi_t *)atom; + lldpctl_atom_dec_ref((lldpctl_atom_t *)pi->parent); +} + +static const uint8_t * +_lldpctl_atom_get_buf_pi(lldpctl_atom_t *atom, lldpctl_key_t key, size_t *n) +{ + struct _lldpctl_atom_pi_t *m = (struct _lldpctl_atom_pi_t *)atom; + + /* Local and remote port */ + switch (key) { + case lldpctl_k_pi_id: + *n = m->pi->p_pi_len; + return (const uint8_t *)m->pi->p_pi; + default: + SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); + return NULL; + } +} + +static struct atom_builder vlans_list = { atom_vlans_list, + sizeof(struct _lldpctl_atom_any_list_t), .init = _lldpctl_atom_new_any_list, + .free = _lldpctl_atom_free_any_list, .iter = _lldpctl_atom_iter_vlans_list, + .next = _lldpctl_atom_next_vlans_list, + .value = _lldpctl_atom_value_vlans_list }; + +static struct atom_builder vlan = { atom_vlan, sizeof(struct _lldpctl_atom_vlan_t), + .init = _lldpctl_atom_new_vlan, .free = _lldpctl_atom_free_vlan, + .get_str = _lldpctl_atom_get_str_vlan, .get_int = _lldpctl_atom_get_int_vlan }; + +static struct atom_builder ppvids_list = { atom_ppvids_list, + sizeof(struct _lldpctl_atom_any_list_t), .init = _lldpctl_atom_new_any_list, + .free = _lldpctl_atom_free_any_list, .iter = _lldpctl_atom_iter_ppvids_list, + .next = _lldpctl_atom_next_ppvids_list, + .value = _lldpctl_atom_value_ppvids_list }; + +static struct atom_builder ppvid = { atom_ppvid, sizeof(struct _lldpctl_atom_ppvid_t), + .init = _lldpctl_atom_new_ppvid, .free = _lldpctl_atom_free_ppvid, + .get_int = _lldpctl_atom_get_int_ppvid }; + +static struct atom_builder pis_list = { atom_pis_list, + sizeof(struct _lldpctl_atom_any_list_t), .init = _lldpctl_atom_new_any_list, + .free = _lldpctl_atom_free_any_list, .iter = _lldpctl_atom_iter_pis_list, + .next = _lldpctl_atom_next_pis_list, .value = _lldpctl_atom_value_pis_list }; + +static struct atom_builder pi = { atom_pi, sizeof(struct _lldpctl_atom_pi_t), + .init = _lldpctl_atom_new_pi, .free = _lldpctl_atom_free_pi, + .get_buffer = _lldpctl_atom_get_buf_pi }; + +ATOM_BUILDER_REGISTER(vlans_list, 9); +ATOM_BUILDER_REGISTER(vlan, 10); +ATOM_BUILDER_REGISTER(ppvids_list, 11); +ATOM_BUILDER_REGISTER(ppvid, 12); +ATOM_BUILDER_REGISTER(pis_list, 13); +ATOM_BUILDER_REGISTER(pi, 14); + +#endif |