Three random picked mib object from ptpbase_mib is initialized in sub
agent and data is received from ptp4l.
All different MIBs should be placed in separate .c files and use the
combined .h file (snmpd_mib.h) for their global initialization function.

Signed-off-by: Anders Selhammer <anders.selham...@est.tech>
---
 makefile      |   2 +-
 optprg.sh     |   2 +-
 ptpbase_mib.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 snmpd.c       |  39 ++++++++++
 snmpd_mib.h   |  32 ++++++++
 5 files changed, 304 insertions(+), 2 deletions(-)
 create mode 100644 ptpbase_mib.c
 create mode 100644 snmpd_mib.h

diff --git a/makefile b/makefile
index fdf3747..5c28059 100644
--- a/makefile
+++ b/makefile
@@ -52,7 +52,7 @@ ptp4l: $(OBJ)
 nsm: config.o filter.o hash.o mave.o mmedian.o msg.o nsm.o print.o raw.o \
  rtnl.o sk.o transport.o tlv.o tsproc.o udp.o udp6.o uds.o util.o version.o
 
-snmpd: config.o hash.o msg.o pmc_common.o print.o raw.o sk.o \
+snmpd: config.o hash.o msg.o pmc_common.o print.o ptpbase_mib.o raw.o sk.o \
  snmpd.o tlv.o transport.o udp.o udp6.o uds.o util.o
 
 pmc: config.o hash.o msg.o pmc.o pmc_common.o print.o raw.o sk.o tlv.o \
diff --git a/optprg.sh b/optprg.sh
index dda04dc..3074dd3 100755
--- a/optprg.sh
+++ b/optprg.sh
@@ -25,7 +25,7 @@ snmp_files()
 {
        libsnmp=/usr/include/net-snmp/
        if [ -d ${libsnmp} ]; then
-               printf " snmpd snmpd.o"
+               printf " snmpd snmpd.o ptpbase_mib.o"
        fi
 }
 
diff --git a/ptpbase_mib.c b/ptpbase_mib.c
new file mode 100644
index 0000000..9ee2a07
--- /dev/null
+++ b/ptpbase_mib.c
@@ -0,0 +1,231 @@
+/**
+ * @file ptpbase_mib.c
+ * @brief Implements PTPv2 Management Information Base (RFC 8173)
+ * @note Copyright (C) 2018 Anders Selhammer <anders.selham...@est.tech>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+#include "print.h"
+#include "snmpd_mib.h"
+
+/*
+ * ptp base oid values
+ */
+#define SNMP_OID_PTPBASE_MIB                    1, 3, 6, 1, 2, 1, 241
+#define SNMP_OID_PTPBASE_OBJ_CLOCKINFO          SNMP_OID_PTPBASE_MIB, 1, 2
+#define SNMP_OID_PTPBASE_CLOCK_DEFAULT_DS_ENTRY 
SNMP_OID_PTPBASE_OBJ_CLOCKINFO, 3, 1
+#define SNMP_OID_PTPBASE_CLOCK_PORT_DS_ENTRY    
SNMP_OID_PTPBASE_OBJ_CLOCKINFO, 8, 1
+
+/*
+ * other internal defines and types
+ */
+#define CMD_MAX_LEN 1024
+
+enum rettype {
+       SNMPD_UNSIGNED = 0,
+};
+
+union retval {
+       unsigned int ui;
+};
+
+struct retdata {
+       enum rettype type;
+       union retval val;
+};
+
+/*
+ * function declarations
+ */
+static int get_mgmt_data(struct ptp_message *msg,
+                        struct management_tlv **mgt)
+{
+       int action;
+       struct TLV *tlv;
+
+       if (msg_type(msg) != MANAGEMENT) {
+               pr_err("msg type not MANAGEMENT");
+               return -1;
+       }
+
+       action = management_action(msg);
+       if (action < GET || action > ACKNOWLEDGE) {
+               pr_err("incorrect action");
+               return -1;
+       }
+
+       if (msg->tlv_count != 1) {
+               pr_err("incorrect tlv count");
+               return -1;
+       }
+
+       tlv = (struct TLV *) msg->management.suffix;
+       if (tlv->type == TLV_MANAGEMENT) {
+               ;
+       } else if (tlv->type == TLV_MANAGEMENT_ERROR_STATUS) {
+               pr_err("MANAGEMENT_ERROR_STATUS");
+               return -1;
+       } else {
+               pr_err("unknown-tlv");
+               return -1;
+       }
+
+       *mgt = (struct management_tlv *) msg->management.suffix;
+       if ((*mgt)->length == 2 && (*mgt)->id != TLV_NULL_MANAGEMENT) {
+               pr_err("empty-tlv");
+               return -1;
+       }
+       return 0;
+}
+
+static int get_msg_retdata(struct ptp_message *msg, struct retdata *ret)
+{
+       struct management_tlv *mgt = NULL;
+       struct management_tlv_datum *mtd;
+       struct tlv_extra *extra = NULL;
+
+       if (get_mgmt_data(msg, &mgt)) {
+               return -1;
+       }
+       extra = TAILQ_FIRST(&msg->tlv_list);
+
+       switch (mgt->id) {
+       case TLV_PRIORITY1:
+       case TLV_PRIORITY2:
+       case TLV_VERSION_NUMBER:
+               mtd = (struct management_tlv_datum *) mgt->data;
+               ret->val.ui = mtd->val;
+               ret->type = SNMPD_UNSIGNED;
+               break;
+       }
+       (void)extra;  // Avoid build warning in example
+       return 0;
+}
+
+static int command_lookup(char *name, char *cmd)
+{
+       if (strcmp(name, "default_ds_priority1") == 0) {
+               snprintf(cmd, CMD_MAX_LEN, "GET PRIORITY1");
+       } else if (strcmp(name, "default_ds_priority2") == 0) {
+               snprintf(cmd, CMD_MAX_LEN, "GET PRIORITY2");
+       } else if (strcmp(name, "port_ds_ptp_version") == 0) {
+               snprintf(cmd, CMD_MAX_LEN, "GET VERSION_NUMBER");
+       } else {
+               return -1;
+       }
+       return 0;
+}
+
+static int handle_pdu(netsnmp_mib_handler *handler,
+                     netsnmp_handler_registration *reginfo,
+                     netsnmp_agent_request_info *reqinfo,
+                     netsnmp_request_info *requests)
+{
+       struct ptp_message *msg;
+       char cmd[CMD_MAX_LEN];
+       struct retdata ret;
+       int err = -1;
+
+       if (command_lookup(reginfo->handlerName, cmd)) {
+               pr_err("Failed to lookup command from reginfo");
+               return SNMP_ERR_GENERR;
+       }
+
+       switch (reqinfo->mode) {
+       case MODE_GET:
+               msg = run_pmc(cmd);
+               if (!msg) {
+                       return SNMP_ERR_GENERR;
+               }
+               if (get_msg_retdata(msg, &ret)) {
+                       msg_put(msg);
+                       return SNMP_ERR_GENERR;
+               }
+               msg_put(msg);
+               switch (ret.type) {
+               case SNMPD_UNSIGNED:
+                       err = snmp_set_var_typed_value(requests->requestvb,
+                                                      ASN_UNSIGNED,
+                                                      &ret.val.ui,
+                                                      sizeof(ret.val));
+                       break;
+               }
+               if (err) {
+                       return SNMP_ERR_GENERR;
+               }
+               break;
+       default:
+               snmp_log(LOG_ERR, "unknown mode (%d) in handle_totalClients\n",
+                        reqinfo->mode);
+               return SNMP_ERR_GENERR;
+       }
+       return SNMP_ERR_NOERROR;
+}
+
+static int init_default_ds_priority1(void)
+{
+       netsnmp_handler_registration *hr;
+       const oid default_ds_priority1_oid[] = { 
SNMP_OID_PTPBASE_CLOCK_DEFAULT_DS_ENTRY, 6 };
+
+       hr = netsnmp_create_handler_registration("default_ds_priority1",
+                                                handle_pdu,
+                                                default_ds_priority1_oid,
+                                                
OID_LENGTH(default_ds_priority1_oid),
+                                                HANDLER_CAN_RONLY);
+       return netsnmp_register_scalar(hr);
+}
+
+static int init_default_ds_priority2(void)
+{
+       netsnmp_handler_registration *hr;
+       const oid default_ds_priority2_oid[] = { 
SNMP_OID_PTPBASE_CLOCK_DEFAULT_DS_ENTRY, 7 };
+
+       hr = netsnmp_create_handler_registration("default_ds_priority2",
+                                                handle_pdu,
+                                                default_ds_priority2_oid,
+                                                
OID_LENGTH(default_ds_priority2_oid),
+                                                HANDLER_CAN_RONLY);
+       return netsnmp_register_scalar(hr);
+}
+
+static int init_port_ds_ptp_version(void)
+{
+       netsnmp_handler_registration *hr;
+       const oid port_ds_ptp_version_oid[] = { 
SNMP_OID_PTPBASE_CLOCK_PORT_DS_ENTRY, 15 };
+
+       hr = netsnmp_create_handler_registration("port_ds_ptp_version",
+                                                handle_pdu,
+                                                port_ds_ptp_version_oid,
+                                                
OID_LENGTH(port_ds_ptp_version_oid),
+                                                HANDLER_CAN_RONLY);
+       return netsnmp_register_scalar(hr);
+}
+
+void init_ptpbase_mib()
+{
+       if (init_default_ds_priority1()) {
+               pr_err("Failed to initialize default_ds_priority1");
+       }
+       if (init_default_ds_priority2()) {
+               pr_err("Failed to initialize default_ds_priority2");
+       }
+       if (init_port_ds_ptp_version()) {
+               pr_err("Failed to initialize port_ds_ptp_version");
+       }
+}
diff --git a/snmpd.c b/snmpd.c
index e0e9727..803cf74 100644
--- a/snmpd.c
+++ b/snmpd.c
@@ -17,6 +17,9 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
+#include <errno.h>
+#include <poll.h>
+
 #include <net-snmp/net-snmp-config.h>
 #include <net-snmp/net-snmp-includes.h>
 #include <net-snmp/agent/net-snmp-agent-includes.h>
@@ -24,10 +27,44 @@
 #include "config.h"
 #include "pmc_common.h"
 #include "print.h"
+#include "snmpd_mib.h"
 #include "util.h"
 
+#define SNMP_NFD 1
 static struct pmc *pmc;
 
+struct ptp_message* run_pmc(char *cmd)
+{
+       struct pollfd pollfd[SNMP_NFD];
+       int cnt, tmo = 100;
+
+       pollfd[0].fd = pmc_get_transport_fd(pmc);
+       pollfd[0].events = POLLIN | POLLPRI;
+
+       if (pmc_do_command(pmc, cmd)) {
+               pr_err("bad command: %s", cmd);
+       }
+
+       while (is_running()) {
+               cnt = poll(pollfd, SNMP_NFD, tmo);
+               if (cnt < 0) {
+                       if (EINTR == errno) {
+                               continue;
+                       } else {
+                               pr_emerg("poll failed");
+                               break;
+                       }
+               } else if (!cnt) {
+                       break;
+               }
+
+               if (pollfd[0].revents & (POLLIN|POLLPRI)) {
+                       return pmc_recv(pmc);
+               }
+       }
+       return NULL;
+}
+
 static int open_pmc(struct config *cfg)
 {
        char uds_local[MAX_IFNAME_SIZE + 1];
@@ -45,6 +82,8 @@ static int open_snmp()
                               NETSNMP_DS_AGENT_ROLE, 1);
        init_agent("linuxptpAgent");
 
+       init_ptpbase_mib();
+
        init_snmp("linuxptpAgent");
 
        return 0;
diff --git a/snmpd_mib.h b/snmpd_mib.h
new file mode 100644
index 0000000..e27de3e
--- /dev/null
+++ b/snmpd_mib.h
@@ -0,0 +1,32 @@
+/**
+ * @file snmpd_mib.h
+ * @brief Common header file for all supported mibs in linuxptp
+ * @note Copyright (C) 2018 Anders Selhammer <anders.selham...@est.tech>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef SNMPDMIB_H
+#define SNMPDMIB_H
+
+#include "msg.h"
+
+/*
+ * function declarations 
+ */
+struct ptp_message* run_pmc(char *cmd);
+
+void init_ptpbase_mib();
+
+#endif /* SNMPDMIB_H */
-- 
1.8.3.1


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to