summaryrefslogtreecommitdiffstats
path: root/src/lib/atoms/mgmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/atoms/mgmt.c')
-rw-r--r--src/lib/atoms/mgmt.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/lib/atoms/mgmt.c b/src/lib/atoms/mgmt.c
new file mode 100644
index 0000000..095de76
--- /dev/null
+++ b/src/lib/atoms/mgmt.c
@@ -0,0 +1,149 @@
+/* -*- 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"
+
+static int
+_lldpctl_atom_new_mgmts_list(lldpctl_atom_t *atom, va_list ap)
+{
+ struct _lldpctl_atom_mgmts_list_t *plist =
+ (struct _lldpctl_atom_mgmts_list_t *)atom;
+ plist->parent = va_arg(ap, lldpctl_atom_t *);
+ plist->chassis = va_arg(ap, struct lldpd_chassis *);
+ lldpctl_atom_inc_ref(plist->parent);
+ return 1;
+}
+
+static void
+_lldpctl_atom_free_mgmts_list(lldpctl_atom_t *atom)
+{
+ struct _lldpctl_atom_mgmts_list_t *plist =
+ (struct _lldpctl_atom_mgmts_list_t *)atom;
+ lldpctl_atom_dec_ref(plist->parent);
+}
+
+static lldpctl_atom_iter_t *
+_lldpctl_atom_iter_mgmts_list(lldpctl_atom_t *atom)
+{
+ struct _lldpctl_atom_mgmts_list_t *plist =
+ (struct _lldpctl_atom_mgmts_list_t *)atom;
+ return (lldpctl_atom_iter_t *)TAILQ_FIRST(&plist->chassis->c_mgmt);
+}
+
+static lldpctl_atom_iter_t *
+_lldpctl_atom_next_mgmts_list(lldpctl_atom_t *atom, lldpctl_atom_iter_t *iter)
+{
+ struct lldpd_mgmt *mgmt = (struct lldpd_mgmt *)iter;
+ return (lldpctl_atom_iter_t *)TAILQ_NEXT(mgmt, m_entries);
+}
+
+static lldpctl_atom_t *
+_lldpctl_atom_value_mgmts_list(lldpctl_atom_t *atom, lldpctl_atom_iter_t *iter)
+{
+ struct _lldpctl_atom_mgmts_list_t *plist =
+ (struct _lldpctl_atom_mgmts_list_t *)atom;
+ struct lldpd_mgmt *mgmt = (struct lldpd_mgmt *)iter;
+ return _lldpctl_new_atom(atom->conn, atom_mgmt, plist->parent, mgmt);
+}
+
+static int
+_lldpctl_atom_new_mgmt(lldpctl_atom_t *atom, va_list ap)
+{
+ struct _lldpctl_atom_mgmt_t *mgmt = (struct _lldpctl_atom_mgmt_t *)atom;
+ mgmt->parent = va_arg(ap, lldpctl_atom_t *);
+ mgmt->mgmt = va_arg(ap, struct lldpd_mgmt *);
+ lldpctl_atom_inc_ref(mgmt->parent);
+ return 1;
+}
+
+static void
+_lldpctl_atom_free_mgmt(lldpctl_atom_t *atom)
+{
+ struct _lldpctl_atom_mgmt_t *mgmt = (struct _lldpctl_atom_mgmt_t *)atom;
+ lldpctl_atom_dec_ref(mgmt->parent);
+}
+
+static long int
+_lldpctl_atom_get_int_mgmt(lldpctl_atom_t *atom, lldpctl_key_t key)
+{
+ struct _lldpctl_atom_mgmt_t *m = (struct _lldpctl_atom_mgmt_t *)atom;
+
+ /* Local and remote port */
+ switch (key) {
+ case lldpctl_k_mgmt_iface_index:
+ return m->mgmt->m_iface;
+ default:
+ return SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST);
+ }
+}
+
+static const char *
+_lldpctl_atom_get_str_mgmt(lldpctl_atom_t *atom, lldpctl_key_t key)
+{
+ char *ipaddress = NULL;
+ size_t len;
+ int af;
+ struct _lldpctl_atom_mgmt_t *m = (struct _lldpctl_atom_mgmt_t *)atom;
+
+ /* Local and remote port */
+ switch (key) {
+ case lldpctl_k_mgmt_ip:
+ switch (m->mgmt->m_family) {
+ case LLDPD_AF_IPV4:
+ len = INET_ADDRSTRLEN + 1;
+ af = AF_INET;
+ break;
+ case LLDPD_AF_IPV6:
+ len = INET6_ADDRSTRLEN + 1;
+ af = AF_INET6;
+ break;
+ default:
+ len = 0;
+ }
+ if (len == 0) break;
+ ipaddress = _lldpctl_alloc_in_atom(atom, len);
+ if (!ipaddress) return NULL;
+ if (inet_ntop(af, &m->mgmt->m_addr, ipaddress, len) == NULL) break;
+ return ipaddress;
+ default:
+ SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST);
+ return NULL;
+ }
+ SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST);
+ return NULL;
+}
+
+static struct atom_builder mgmts_list = { atom_mgmts_list,
+ sizeof(struct _lldpctl_atom_mgmts_list_t), .init = _lldpctl_atom_new_mgmts_list,
+ .free = _lldpctl_atom_free_mgmts_list, .iter = _lldpctl_atom_iter_mgmts_list,
+ .next = _lldpctl_atom_next_mgmts_list,
+ .value = _lldpctl_atom_value_mgmts_list };
+
+static struct atom_builder mgmt = { atom_mgmt, sizeof(struct _lldpctl_atom_mgmt_t),
+ .init = _lldpctl_atom_new_mgmt, .free = _lldpctl_atom_free_mgmt,
+ .get_int = _lldpctl_atom_get_int_mgmt, .get_str = _lldpctl_atom_get_str_mgmt };
+
+ATOM_BUILDER_REGISTER(mgmts_list, 6);
+ATOM_BUILDER_REGISTER(mgmt, 7);