summaryrefslogtreecommitdiffstats
path: root/sbin/atm
diff options
context:
space:
mode:
authormks <mks@FreeBSD.org>1999-01-20 00:56:21 +0000
committermks <mks@FreeBSD.org>1999-01-20 00:56:21 +0000
commit5f3006942fd798125287d4697f71b6303a0403de (patch)
treefd229a97678429628f58cb0aeda90d6e3514ccdc /sbin/atm
parent6f731db02ec0f2dfd49ba289c3dff40dbfce8fd6 (diff)
downloadFreeBSD-src-5f3006942fd798125287d4697f71b6303a0403de.zip
FreeBSD-src-5f3006942fd798125287d4697f71b6303a0403de.tar.gz
Re-write of ilmi daemon. Among the major changes, it does not use predefined
PDUs and should handle multi-request OIDs on GETs.
Diffstat (limited to 'sbin/atm')
-rw-r--r--sbin/atm/ilmid/ilmid.c2830
1 files changed, 1275 insertions, 1555 deletions
diff --git a/sbin/atm/ilmid/ilmid.c b/sbin/atm/ilmid/ilmid.c
index e515a10..9da2424 100644
--- a/sbin/atm/ilmid/ilmid.c
+++ b/sbin/atm/ilmid/ilmid.c
@@ -23,7 +23,7 @@
* Copies of this Software may be made, however, the above copyright
* notice must be reproduced on all copies.
*
- * @(#) $Id: ilmid.c,v 1.9 1998/08/13 20:15:28 jpt Exp $
+ * @(#) $Id: ilmid.c,v 1.1 1998/09/15 08:22:47 phk Exp $
*
*/
@@ -45,40 +45,24 @@
*
*/
-#ifndef lint
-static char *RCSid = "@(#) $Id: ilmid.c,v 1.9 1998/08/13 20:15:28 jpt Exp $";
-#endif
-
-#include <sys/types.h>
#include <sys/param.h>
-#if (defined(BSD) && (BSD >= 199103))
-#include <err.h>
+#ifndef lint
+__RCSID("@(#) $Id: ilmid.c,v 1.1 1998/09/15 08:22:47 phk Exp $");
#endif
-#ifdef BSD
-#if __FreeBSD_version < 300001
-#include <stdlib.h>
-#ifdef sun
-#include <unistd.h>
-#endif /* sun */
-#else
-#include <unistd.h>
-#endif /* __FreeBSD_version >= 300001 */
-#endif /* BSD */
-
+#include <err.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
-#include <time.h>
-#include <sys/errno.h>
#include <string.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
#include <syslog.h>
+#include <time.h>
+#include <unistd.h>
#include <sys/socket.h>
+#include <sys/sockio.h>
#include <net/if.h>
#include <netinet/in.h>
-
#include <netatm/port.h>
#include <netatm/atm.h>
#include <netatm/atm_if.h>
@@ -86,36 +70,30 @@ static char *RCSid = "@(#) $Id: ilmid.c,v 1.9 1998/08/13 20:15:28 jpt Exp $";
#include <netatm/atm_sap.h>
#include <netatm/atm_sys.h>
#include <netatm/atm_ioctl.h>
-
#include <dev/hea/eni_stats.h>
#include <dev/hfa/fore_aali.h>
#include <dev/hfa/fore_slave.h>
#include <dev/hfa/fore_stats.h>
-#include <netatm/uni/unisig_var.h>
+
+#include <libatm.h>
#define MAX_LEN 9180
#define MAX_UNITS 8
/*
- * Time to sleep between loops
- */
-#define SLEEP_TIME 10
-/*
- * Time to pass between sending coldStart TRAPs
- */
-#define TRAP_TIME 5
-
-/*
* Define some ASN types
*/
#define ASN_INTEGER 0x02
#define ASN_OCTET 0x04
+#define ASN_NULL 0x05
#define ASN_OBJID 0x06
#define ASN_SEQUENCE 0x30
#define ASN_IPADDR 0x40
#define ASN_TIMESTAMP 0x43
+static char *Var_Types[] = { "", "", "ASN_INTEGER", "", "ASN_OCTET", "ASN_NULL", "ASN_OBJID" };
+
/*
* Define SNMP PDU types
*/
@@ -125,360 +103,167 @@ static char *RCSid = "@(#) $Id: ilmid.c,v 1.9 1998/08/13 20:15:28 jpt Exp $";
#define PDU_TYPE_SET 0xA3
#define PDU_TYPE_TRAP 0xA4
-/*
- * Every SNMP PDU has the first four fields of this header. The only type
- * which doesn't have the last three fields is the TRAP type.
- */
-struct snmp_header {
- int pdulen;
- int version;
- char community[64];
- int pdutype;
- int reqid;
- int error;
- int erridx;
-};
-typedef struct snmp_header Snmp_Header;
+static char *PDU_Types[] = { "GET REQUEST", "GETNEXT REQUEST", "GET RESPONSE", "SET REQUEST",
+ "TRAP" };
/*
- * Define our internal representation of an OBJECT IDENTIFIER
+ * Define TRAP codes
*/
-struct objid {
- int oid[128];
-};
-typedef struct objid Objid;
+#define TRAP_COLDSTART 0
+#define TRAP_WARMSTART 1
+#define TRAP_LINKDOWN 2
+#define TRAP_LINKUP 3
+#define TRAP_AUTHFAIL 4
+#define TRAP_EGPLOSS 5
+#define TRAP_ENTERPRISE 6
/*
- * Define some OBJET IDENTIFIERS that we'll try to reply to:
- *
- * sysUpTime: number of time ticks since this deamon came up
- * netpfx_oid: network prefix table
- * unitype: is this a PRIVATE or PUBLIC network link
- * univer: which version of UNI are we running
- * devtype: is this a USER or NODE ATM device
- * setprefix: used when the switch wants to tell us its NSAP prefix
- * foresiggrp: FORE specific Objid we see alot of (being connected to FORE
- * switches...)
- */
-Objid sysObjId = { 8, 43, 6, 1, 2, 1, 1, 2, 0 };
-Objid sysUpTime = { 8, 43, 6, 1, 2, 1, 1, 3, 0 };
-Objid foresiggrp = { 18, 43, 6, 1, 4, 1, 326, 2, 2, 2, 1, 6, 2, 1, 1, 1, 20, 0, 0 };
-Objid portidx = { 12, 43, 6, 1, 4, 1, 353, 2, 1, 1, 1, 1, 0 };
-Objid myipnm = { 10, 43, 6, 1, 4, 1, 353, 2, 1, 2, 0 };
-Objid layeridx = { 12, 43, 6, 1, 4, 1, 353, 2, 2, 1, 1, 1, 0 };
-Objid maxvcc = { 12, 43, 6, 1, 4, 1, 353, 2, 2, 1, 1, 3, 0 };
-Objid unitype = { 12, 43, 6, 1, 4, 1, 353, 2, 2, 1, 1, 8, 0 };
-Objid univer = { 12, 43, 6, 1, 4, 1, 353, 2, 2, 1, 1, 9, 0 };
-Objid devtype = { 12, 43, 6, 1, 4, 1, 353, 2, 2, 1, 1, 10, 0 };
-Objid netpfx_oid = { 9, 43, 6, 1, 4, 1, 353, 2, 7, 1 };
-Objid setprefix = { 12, 43, 6, 1, 4, 1, 353, 2, 7, 1, 1, 3, 0 };
-/*
- * (Partialy) pre-encoded SNMP responses
+ * Define SNMP Version numbers
*/
+#define SNMP_VERSION_1 1
+#define SNMP_VERSION_2 2
/*
- * sysObjId reply
+ * Max string length for Variable
*/
-u_char sysObjId_Resp[] = {
- 54, /* <--- len */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x32, /* <--- len */
- 0x02, 0x01, 0x00, /* (Version - 1) */
- 0x04, 0x04, 0x49, 0x4c, 0x4d, 0x49, /* Community: ILMI */
- PDU_TYPE_GETRESP, /* GET Response */
- 0x27, /* <--- len */
- 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, /* <--- request id */
- 0x02, 0x01, 0x00, /* Error Status */
- 0x02, 0x01, 0x00, /* Error Index */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x17, /* <--- len */
- 0x82, 0x00, 0x14, /* <--- len */
- 0x06, 0x08, /* Objid: 1.3.6.1.4.1.1.2.0 */
- 0x2b, 0x06, 0x01, 0x04, 0x01, 0x01, 0x02, 0x00,
- 0x06, 0x08, /* Objid: 1.3.6.1.4.1.9999.1 */
- 0x2b, 0x06, 0x01, 0x04, 0x01, 0xce, 0x0f, 0x01
-};
+#define STRLEN 128
/*
- * sysUpTime: reply to a sysUpTime GET request
+ * Unknown variable
*/
-u_char sysUpTime_Resp[] = {
- 45, /* <--- len */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x29, /* <--- len */
- 0x02, 0x01, 0x00, /* (Version - 1) */
- 0x04, 0x04, 0x49, 0x4c, 0x4d, 0x49, /* Community - ILMI */
- PDU_TYPE_GETRESP, /* GET Response */
- 0x1e, /* <--- len */
- 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, /* <--- request id */
- 0x02, 0x01, 0x00, /* Error Status */
- 0x02, 0x01, 0x00, /* Error Index */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x0E, /* <--- len */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x0A, /* <--- len */
- /* Objid: .1.3.6.1.2.1.1.3.0 */
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00,
- /* <--- uptime */
-};
+#define VAR_UNKNOWN -1
/*
- * coldStart TRAP to start the ILMI protocol
+ * Define our internal representation of an OBJECT IDENTIFIER
*/
-u_char coldStart_Trap[] = {
- 60,
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x38, /* <--- len */
- 0x02, 0x01, 0x00, /* (Version - 1) */
- 0x04, 0x04, 0x49, 0x4c, 0x4d, 0x49, /* Community: ILMI */
- PDU_TYPE_TRAP, /* TRAP */
- 0x2d, /* <--- len */
- 0x06, 0x08, /* Objid: .1.3.6.1.4.1.3.1.1 */
- 0x2b, 0x06, 0x01, 0x04, 0x01, 0x03, 0x01, 0x01,
- 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, /* IP address - 0.0.0.0 */
- 0x02, 0x01, 0x00, /* generic trap */
- 0x02, 0x01, 0x00, /* specific trap */
- 0x43, 0x01, 0x00, /* Time ticks - 0 */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x10, /* <--- len */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x0c, /* <-- len */
- 0x06, 0x08, /* Objid: 1.3.6.1.2.1.1.3.0 */
- 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00,
- 0x05, 0x00 /* Null */
-};
-
-u_char GetNext_Resp[] = {
- 49,
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x2d, /* <--- len */
- 0x02, 0x01, 0x00, /* (Version - 1) */
- 0x04, 0x04, 0x49, 0x4c, 0x4d, 0x49, /* Community: ILMI */
- PDU_TYPE_GETRESP, /* PDU_TYPE_GETRESP */
- 0x22, /* <--- len */
- 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, /* Request ID */
- 0x02, 0x01, 0x02, /* Error Status */
- 0x02, 0x01, 0x01, /* Error Index */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x12, /* <--- len */
- 0x30, /* Seqence of */
- 0x82, 0x00, 0x0e, /* <--- len */
- 0x06, 0x0a, /* Objid: .1.3.6.4.1.353.2.7.1 */
- 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x61, 0x02, 0x07, 0x01,
- 0x05, 0x00 /* Get response: NULL */
+struct objid {
+ int oid[128];
};
+typedef struct objid Objid;
/*
- * Reply to GET myIpNm
+ * Define a Veriable classso that we can handle multiple GET/SET's
+ * per PDU.
*/
-u_char MyIpNm_Resp[] = {
- 54,
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x32, /* <--- len */
- 0x02, 0x01, 0x00, /* (Version - 1) */
- 0x04, 0x04, 0x49, 0x4c, 0x4d, 0x49, /* Community: ILMI */
- PDU_TYPE_GETRESP, /* PDU_TYPE_GETRESP */
- 0x27, /* <--- len */
- 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, /* Request ID */
- 0x02, 0x01, 0x00, /* Error Status */
- 0x02, 0x01, 0x00, /* Error Index */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x17, /* <--- len */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x13, /* <--- len */
- /* Objid: .1.3.6.1.4.1.353.2.1.2.1 */
- 0x06, 0x0B, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x61, 0x02,
- 0x01, 0x02, 0x01,
- 0x40, 0x04, 0x00, 0x00, 0x00, 0x00 /* IP address */
+typedef struct variable Variable;
+struct variable {
+ Objid oid;
+ int type;
+ union {
+ int ival; /* INTEGER/TIMESTAMP */
+ Objid oval; /* OBJID */
+ long aval; /* IPADDR */
+ char sval[STRLEN]; /* OCTET */
+ } var;
+ Variable *next;
};
/*
- * Reply to GET portIndex - we're always 1 + unit number
+ * Every SNMP PDU has the first four fields of this header. The only type
+ * which doesn't have the last three fields is the TRAP type.
*/
-u_char PortIndex_Resp[] = {
- 53,
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x31, /* <-- len */
- 0x02, 0x01, 0x00, /* (Version - 1) */
- 0x04, 0x04, 0x49, 0x4c, 0x4d, 0x49, /* Community: ILMI */
- PDU_TYPE_GETRESP,
- 0x26, /* <-- len */
- 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, /* Request ID */
- 0x02, 0x01, 0x00, /* Error Status */
- 0x02, 0x01, 0x00, /* Error Index */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x16, /* <--- len */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x12, /* <--- len */
- /* Objid: .1.3.6.1.4.1.353.2.1.1.1.1.x */
- 0x06, 0x0d, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x61, 0x02,
- 0x01, 0x01, 0x01, 0x01, 0x00,
- 0x02, 0x01, 0x00, /* Value */
-};
+struct snmp_header {
+ int pdulen;
+ int version;
+ char community[64];
+ int pdutype;
-/*
- * Reply to GET MaxVcc
- */
-u_char maxVCC_Resp[] = {
- 52, /* <--- len */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x30, /* <--- len */
- 0x02, 0x01, 0x01, /* (Version - 1) */
- 0x04, 0x04, 0x49, 0x4c, 0x4d, 0x49, /* Community: ILMI */
- PDU_TYPE_GETRESP, /* GET Response */
- 0x25, /* <--- len */
- 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, /* <--- request id */
- 0x02, 0x01, 0x00, /* Error Status */
- 0x02, 0x01, 0x00, /* Error Index */
- 0x30, /* Sequence of */
- 0x82, 0x16, /* <--- len */
- 0x30, /* Sequence of */
- 0x82, 0x13, /* <--- len */
- 0x06, 0x0d, /* Objid: 1.3.6.1.4.1.353.2.2.1.1.3.0 */
- 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x61, 0x02,
- 0x02, 0x01, 0x01, 0x03, 0x00,
- 0x02, 0x02, 0x04, 0x00 /* Value = 1024 */
+ /* GET/GETNEXT/GETRESP/SET */
+ int reqid;
+ int error;
+ int erridx;
+
+ /* TRAP */
+ Objid enterprise;
+ int ipaddr;
+ int generic_trap;
+ int specific_trap;
+
+ int varlen;
+ Variable *head,
+ *tail;
};
+typedef struct snmp_header Snmp_Header;
+
+Snmp_Header *ColdStart_Header;
+Snmp_Header *PDU_Header;
/*
- * Reply to GET uniType - we only support PRIVATE
+ * Define some OBJET IDENTIFIERS that we'll try to reply to:
+ *
+ * sysUpTime: number of time ticks since this deamon came up
+ * netpfx_oid: network prefix table
+ * unitype: is this a PRIVATE or PUBLIC network link
+ * univer: which version of UNI are we running
+ * devtype: is this a USER or NODE ATM device
+ * setprefix: used when the switch wants to tell us its NSAP prefix
+ * foresiggrp: FORE specific Objid we see alot of (being connected to FORE
+ * switches...)
*/
-u_char UniType_Resp[] = {
- 53,
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x31, /* <--- len */
- 0x02, 0x01, 0x00, /* (Version - 1) */
- 0x04, 0x04, 0x49, 0x4c, 0x4d, 0x49, /* Community: ILMI */
- PDU_TYPE_GETRESP, /* PDU_TYPE_GETRESP */
- 0x26, /* <--- len */
- 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, /* Request ID */
- 0x02, 0x01, 0x00, /* Error Status */
- 0x02, 0x01, 0x00, /* Error Index */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x16, /* <--- len */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x12, /* <--- len */
- /* Objid: .1.3.6.1.4.1.353.2.2.1.1.8.0 */
- 0x06, 0x0d, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x61, 0x02, 0x02,
- 0x01, 0x01, 0x08, 0x00,
- 0x02, 0x01, 0x02 /* Get response: Integer */
- /* = UNITYPE_PRIVATE (2) */
+Objid Objids[] = {
+#define SYS_OBJID 0
+ {{ 8, 43, 6, 1, 2, 1, 1, 2, 0 }},
+#define UPTIME_OBJID 1
+ {{ 8, 43, 6, 1, 2, 1, 1, 3, 0 }},
+#define PORT_OBJID 2
+ {{ 12, 43, 6, 1, 4, 1, 353, 2, 1, 1, 1, 1, 0 }},
+#define IPNM_OBJID 3
+ {{ 10, 43, 6, 1, 4, 1, 353, 2, 1, 2, 0 }},
+#define LAYER_OBJID 4
+ {{ 12, 43, 6, 1, 4, 1, 353, 2, 2, 1, 1, 1, 0 }},
+#define MAXVCC_OBJID 5
+ {{ 12, 43, 6, 1, 4, 1, 353, 2, 2, 1, 1, 3, 0 }},
+#define UNITYPE_OBJID 6
+ {{ 12, 43, 6, 1, 4, 1, 353, 2, 2, 1, 1, 8, 0 }},
+#define UNIVER_OBJID 7
+ {{ 12, 43, 6, 1, 4, 1, 353, 2, 2, 1, 1, 9, 0 }},
+#define DEVTYPE_OBJID 8
+ {{ 12, 43, 6, 1, 4, 1, 353, 2, 2, 1, 1, 10, 0 }},
+#define ADDRESS_OBJID 9
+ {{ 8, 43, 6, 1, 4, 1, 353, 2, 6 }},
+#define NETPFX_OBJID 10
+ {{ 9, 43, 6, 1, 4, 1, 353, 2, 7, 1 }},
+#define MY_OBJID 11
+ {{ 7, 43, 6, 1, 4, 1, 9999, 1 }},
+#define SETPFX_OBJID 12
+ {{ 12, 43, 6, 1, 4, 1, 353, 2, 7, 1, 1, 3, 0 }},
+#define ENTERPRISE_OBJID 13
+ {{ 8, 43, 6, 1, 4, 1, 3, 1, 1 }},
+#define ATMF_PORTID 14
+ {{ 10, 43, 6, 1, 4, 1, 353, 2, 1, 4, 0 }},
+#define ATMF_SYSID 15
+ {{ 12, 43, 6, 1, 4, 1, 353, 2, 1, 1, 1, 8, 0 }},
};
+#define NUM_OIDS (sizeof(Objids)/sizeof(Objid))
+
+#define UNIVER_UNI20 1
#define UNIVER_UNI30 2
#define UNIVER_UNI31 3
#define UNIVER_UNI40 4
+#define UNIVER_UNKNOWN 5
-/*
- * Reply to GET uniVer
- */
-u_char UniVer_Resp[] = {
- 53,
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x31, /* <--- len */
- 0x02, 0x01, 0x00, /* (Version - 1) */
- 0x04, 0x04, 0x49, 0x4c, 0x4d, 0x49, /* Community: ILMI */
- PDU_TYPE_GETRESP, /* PDU_TYPE_GETRESP */
- 0x26, /* <--- len */
- 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, /* Request ID */
- 0x02, 0x01, 0x00, /* Error Status */
- 0x02, 0x01, 0x00, /* Error Index */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x16, /* <--- len */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x12, /* <--- len */
- /* Objid: .1.3.6.1.4.1.353.2.2.1.1.9.0 */
- 0x06, 0x0d, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x61, 0x02, 0x02,
- 0x01, 0x01, 0x09, 0x00,
- 0x02, 0x01, 0x02 /* Get response: Integer */
- /* = UNIVER_UNI30 (2) */
-};
+#define UNITYPE_PUBLIC 1
+#define UNITYPE_PRIVATE 2
-/*
- * Reply to GET devType - we're a host therefore we're type USER
- */
-u_char DevType_Resp[] = {
- 53,
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x31, /* <--- len */
- 0x02, 0x01, 0x00, /* (Version -1) */
- 0x04, 0x04, 0x49, 0x4c, 0x4d, 0x49, /* Community: ILMI */
- PDU_TYPE_GETRESP, /* PDU_TYPE_GETRESP */
- 0x26, /* <--- len */
- 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, /* Request ID */
- 0x02, 0x01, 0x00, /* Error Status */
- 0x02, 0x01, 0x00, /* Error Index */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x16, /* <--- len */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x12, /* <--- len */
- /* Objid: .1.3.6.1.4.1.353.2.2.1.1.10.0 */
- 0x06, 0x0d, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x61, 0x02, 0x02,
- 0x01, 0x01, 0x0a, 0x00,
- 0x02, 0x01, 0x01 /* Get response: Integer */
- /* = DEVTYPE_USER (1) */
-};
+#define DEVTYPE_USER 1
+#define DEVTYPE_NODE 2
/*
- * Reply to GET foreSigGroup.* with noSuchError
+ * ILMI protocol states
*/
-u_char NoSuchFore_Resp[] = {
- 85,
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x51, /* <--- len */
- 0x02, 0x01, 0x00, /* (Version - 1) */
- 0x04, 0x04, 0x49, 0x4c, 0x4d, 0x49, /* Community: ILMI */
- PDU_TYPE_GETRESP, /* PDU_TYPE_GETRESP */
- 0x46, /* <--- len */
- 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, /* Request ID */
- 0x02, 0x01, 0x02, /* Error Status: noSuch (2) */
- 0x02, 0x01, 0x01, /* Error Index */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x36, /* <--- len */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x17, /* <--- len */
- /* Objid: .1.3.6.1.5.1.326.2.2.2.1.6.2.1.1.1.20.0.0 */
- 0x06, 0x13,
- 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x46,
- 0x02, 0x02, 0x02, 0x01, 0x06, 0x02, 0x01, 0x01,
- 0x01, 0x14, 0x00, 0x00,
- 0x05, 0x00, /* NULL */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x17, /* <--- len */
- /* Objid: .1.3.6.1.5.1.326.2.2.2.1.6.2.1.1.1.21.0.0 */
- 0x06, 0x13,
- 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x46,
- 0x02, 0x02, 0x02, 0x01, 0x06, 0x02, 0x01, 0x01,
- 0x01, 0x15, 0x00, 0x00,
- 0x05, 0x00 /* NULL */
-};
-
-u_char NetPrefix_Resp[] = {
- 50,
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x00, /* <--- len */
- 0x02, 0x01, 0x00, /* (Version - 1) */
- 0x04, 0x04, 0x49, 0x4c, 0x4d, 0x49, /* Community: ILMI */
- PDU_TYPE_SET, /* PDU_TYPE_SET */
- 0x00, /* <--- len */
- 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, /* Request ID */
- 0x02, 0x01, 0x00,
- 0x02, 0x01, 0x00,
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x00, /* <--- len */
- 0x30, /* Sequence of */
- 0x82, 0x00, 0x00, /* <--- len */
- /* Objid: .1.3.6.1.4.1.353.2.6.1.1.3.0. */
- 0x06, 0x00,
- 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x61, 0x02,
- 0x06, 0x01, 0x01, 0x03, 0x00
- /* Remainder of Objid plus SET value INTEGER =1 */
+enum ilmi_states {
+ ILMI_UNKNOWN, /* Uninitialized */
+ ILMI_COLDSTART, /* We need to send a COLD_START trap */
+ ILMI_INIT, /* Ensure that switch has reset */
+ ILMI_REG, /* Looking for SET message */
+ ILMI_RUNNING /* Normal processing */
};
/*
* Our (incrementing) Request ID
*/
-int Req_ID = 0;
+int Req_ID;
/*
* Temporary buffer for building response packets. Should help ensure
@@ -502,18 +287,15 @@ char *Traps[] = { "coldStart", "warmStart", "linkDown", "linkUp",
int NUnits;
+
/*
- * Time last coldStart trap was sent to this unit
- */
-time_t last_trap[MAX_UNITS];
-/*
- * fd for units still awiting coldStart TRAP from network side
+ * fd for units which have seen a coldStart TRAP and are now exchaning SNMP requests
*/
-int trap_fd[MAX_UNITS];
+int ilmi_fd[MAX_UNITS + 1];
/*
- * fd for units which have seen a coldStart TRAP and are now exchaning SNMP requests
+ * enum ilmi_states for this unit
*/
-int ilmi_fd[MAX_UNITS];
+int ilmi_state[MAX_UNITS + 1];
/*
* Local copy for HARP physical configuration information
*/
@@ -524,11 +306,17 @@ struct air_cfg_rsp Cfg[MAX_UNITS + 1];
struct air_int_rsp Intf[MAX_UNITS + 1];
/*
+ * addressEntry table
+ */
+Objid addressEntry[MAX_UNITS + 1];
+
+/*
* When this daemon started
*/
struct timeval starttime;
int Debug_Level = 0;
+int foregnd = 0; /* run in the foreground? */
char *progname;
char hostname[80];
@@ -537,14 +325,6 @@ char hostname[80];
#define LOG_FILE "/var/log/ilmid"
FILE *Log; /* File descriptor for log messages */
-extern int errno;
-
-#ifdef sun
-extern char *optarg;
-extern int optind, opterr;
-extern int getopt __P((int, char **, char *));
-#endif /* sun */
-
void set_reqid __P ( ( u_char *, int ) );
void Increment_DL __P ( ( int ) );
void Decrement_DL __P ( ( int ) );
@@ -574,10 +354,11 @@ write_timestamp()
clock = time ( (time_t)NULL );
tm = localtime ( &clock );
- if ( Log )
- fprintf ( Log, "%.3s %2d %.2d:%.2d:%.2d %s: ",
- Months[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min,
- tm->tm_sec, hostname );
+ if ( Log && Debug_Level > 1 )
+ if ( Log != stderr )
+ fprintf ( Log, "%.3s %2d %.2d:%.2d:%.2d %s: ",
+ Months[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min,
+ tm->tm_sec, hostname );
return;
@@ -617,8 +398,10 @@ hexdump ( bp, len )
for ( ; j < 8 && j + i < len; j++ )
if ( Log )
fprintf ( Log, "%.2x ", *bp++ );
- if ( Log )
+ if ( Log ) {
fprintf ( Log, " " );
+ fflush ( Log );
+ }
for ( ; j < 12 && j + i < len; j++ )
if ( Log )
fprintf ( Log, "%.2x ", *bp++ );
@@ -627,8 +410,10 @@ hexdump ( bp, len )
for ( ; j < 16 && j + i < len; j++ )
if ( Log )
fprintf ( Log, "%.2x ", *bp++ );
- if ( Log )
+ if ( Log ) {
fprintf ( Log, "\n" );
+ fflush ( Log );
+ }
}
return;
@@ -646,24 +431,32 @@ hexdump ( bp, len )
*
* Arguments:
* bufp - pointer to buffer pointer
+ * plen - pointer to PDU length or NULL if not a concern
*
* Returns:
* bufp - updated buffer pointer
+ * plen - (possibly) adjusted pdu length
* <len> - decoded length
*
*/
int
-asn_get_pdu_len ( bufp )
- u_char **bufp;
+asn_get_pdu_len ( bufp, plen )
+ u_char **bufp;
+ int *plen;
{
u_char *bp = *bufp;
int len = 0;
int i, b;
b = *bp++;
+ if ( plen )
+ (*plen)--;
if ( b & 0x80 ) {
- for ( i = 0; i < (b & ~0x80); i++ )
+ for ( i = 0; i < (b & ~0x80); i++ ) {
len = len * 256 + *bp++;
+ if ( plen )
+ (*plen)--;
+ }
} else
len = b;
@@ -720,15 +513,18 @@ asn_get_encoded ( bufp, len )
*
* Arguments:
* bufp - pointer to the buffer pointer
+ * plen - pointer to PDU length or NULL if not a concern
*
* Returns:
* bufp - updated buffer pointer
+ * plen - (possibly) updated PDU length
* <val> - value of encoded integer
*
*/
int
-asn_get_int ( bufp )
- u_char **bufp;
+asn_get_int ( bufp, plen )
+ u_char **bufp;
+ int *plen;
{
int i;
int len;
@@ -736,14 +532,69 @@ asn_get_int ( bufp )
u_char *bp = *bufp;
len = *bp++;
+ if ( plen )
+ (*plen)--;
for ( i = 0; i < len; i++ ) {
v = (v * 256) + *bp++;
+ if ( plen )
+ (*plen)--;
}
*bufp = bp;
return ( v );
}
/*
+ * Set a BER encoded integer
+ *
+ * Arguments:
+ * bufp - pointer to buffer pointer where we are to set int in
+ * val - integer value to set
+ *
+ * Returns:
+ * none
+ * <bufp> - updated buffer pointer
+ *
+ */
+void
+asn_set_int ( bufp, val )
+ u_char **bufp;
+ int val;
+{
+ union {
+ int i;
+ u_char c[4];
+ } u;
+ int len = sizeof(int);
+ int i = 0;
+ u_char *bp = *bufp;
+
+ /* Check for special case where val == 0 */
+ if ( val == 0 ) {
+ *bp++ = 1;
+ *bp++ = 0;
+ *bufp = bp;
+ return;
+ }
+
+ u.i = htonl ( val );
+
+ while ( u.c[i] == 0 && i++ < sizeof(int) )
+ len--;
+
+ if ( u.c[i] > 0x7f ) {
+ i--;
+ len++;
+ }
+
+ *bp++ = len;
+ UM_COPY ( (caddr_t)&u.c[sizeof(int)-len], bp, len );
+ bp += len;
+ *bufp = bp;
+
+ return;
+}
+
+/*
* Utility to print a object identifier
*
* Arguments:
@@ -782,16 +633,19 @@ print_objid ( objid )
* Arguments:
* bufp - pointer to buffer pointer
* objid - pointer to objid buffer
+ * plen - pointer to PDU length or NULL of not a concern
*
* Returns:
* bufp - updated buffer pointer
* objid - internal representation of encoded objid
+ * plen - (possibly) adjusted PDU length
*
*/
void
-asn_get_objid ( bufp, objid )
- u_char **bufp;
- Objid *objid;
+asn_get_objid ( bufp, objid, plen )
+ u_char **bufp;
+ Objid *objid;
+ int *plen;
{
int len;
u_char *bp = *bufp;
@@ -799,20 +653,56 @@ asn_get_objid ( bufp, objid )
int oidlen = 0;
len = *bp++;
+ if ( plen )
+ (*plen)--;
while ( len ) {
*ip++ = asn_get_encoded ( &bp, &len );
+ if ( plen )
+ (*plen)--;
oidlen++;
}
objid->oid[0] = oidlen;
*bufp = bp;
- if ( Debug_Level > 1 )
- print_objid ( objid );
-
return;
}
/*
+ * Put OBJID - assumes elements <= 16383 for two byte coding
+ *
+ */
+int
+asn_put_objid ( bufp, objid )
+ u_char **bufp;
+ Objid *objid;
+{
+ int len = 0;
+ u_char *bp = *bufp;
+ u_char *cpp;
+ int i;
+
+ cpp = bp;
+ *bp++ = objid->oid[0];
+ len++;
+ for ( i = 1; i <= objid->oid[0]; i++ ) {
+ u_int c = objid->oid[i];
+
+ while ( c > 127 ) {
+ *bp++ = ( ( c >> 7 ) & 0x7f ) | 0x80;
+ len++;
+ c &= 0x7f; /* XXX - assumption of two bytes */
+ (*cpp)++;
+ }
+ *bp++ = c;
+ len++;
+ }
+
+ *bufp = bp;
+ return ( len );
+
+}
+
+/*
* Get OCTET STRING
*
* Octet strings are encoded as a 7-bit encoded length followed by <len>
@@ -821,16 +711,19 @@ asn_get_objid ( bufp, objid )
* Arguments:
* bufp - pointer to buffer pointer
* octet - pointer to octet buffer
+ * plen - pointer to PDU length
*
* Returns:
* bufp - updated buffer pointer
* octet - encoded Octet String
+ * plen - (possibly) adjusted PDU length
*
*/
void
-asn_get_octet ( bufp, octet )
- u_char **bufp;
- char *octet;
+asn_get_octet ( bufp, octet, plen )
+ u_char **bufp;
+ char *octet;
+ int *plen;
{
u_char *bp = *bufp;
int i = 0;
@@ -840,10 +733,13 @@ asn_get_octet ( bufp, octet )
* &i is really a dummy value here as we don't keep track
* of the ongoing buffer length
*/
- len = asn_get_encoded ( &bp, &i );
+ len = asn_get_encoded ( &bp, &i, plen );
- for ( i = 0; i < len; i++ )
+ for ( i = 0; i < len; i++ ) {
*octet++ = *bp++;
+ if ( plen )
+ (*plen)--;
+ }
*bufp = bp;
@@ -865,22 +761,133 @@ void
print_header ( Hdr )
Snmp_Header *Hdr;
{
+ Variable *var;
+
if ( Log ) {
write_timestamp();
fprintf ( Log,
- "Pdu len: %d Version: %d Community: \"%s\" Pdu Type: 0x%x\n",
+ "Pdu len: %d Version: %d Community: \"%s\" Pdu Type: 0x%x %s\n",
Hdr->pdulen, Hdr->version + 1, Hdr->community,
- Hdr->pdutype );
+ Hdr->pdutype, PDU_Types[Hdr->pdutype - PDU_TYPE_GET] );
+ write_timestamp();
+ if ( Hdr->pdutype != PDU_TYPE_TRAP && Log )
+ fprintf ( Log, "\tReq Id: 0x%x Error: %d Error Index: %d\n",
+ Hdr->reqid, Hdr->error, Hdr->erridx );
+ }
+
+ var = Hdr->head;
+ while ( var ) {
+ if ( Log ) {
+ write_timestamp();
+ fprintf ( Log, " Variable Type: %d", var->type );
+ if ( Var_Types[var->type] )
+ fprintf ( Log, " %s", Var_Types[var->type] );
+ fprintf ( Log, "\n\tObject: " );
+ print_objid ( &var->oid );
+ fprintf ( Log, "\tValue: " );
+ switch ( var->type ) {
+ case ASN_INTEGER:
+ fprintf ( Log, "%d (0x%x)\n", var->var.ival, var->var.ival );
+ break;
+ case ASN_NULL:
+ fprintf ( Log, "NULL" );
+ break;
+ default:
+ fprintf ( Log, "[0x%x]", var->type );
+ break;
+ }
+ fprintf ( Log, "\n" );
+ }
+ var = var->next;
}
- if ( Hdr->pdutype != PDU_TYPE_TRAP && Log )
- fprintf ( Log, "\tReq Id: 0x%x Error: %d Error Index: %d\n",
- Hdr->reqid, Hdr->error, Hdr->erridx );
return;
}
/*
+ * Pull OID's from GET/SET message
+ *
+ * Arguments:
+ * h - pointer to Snmp_Header
+ * bp - pointer to input PDU
+ *
+ * Returns:
+ * none
+ *
+ */
+void
+parse_oids ( h, bp )
+ Snmp_Header *h;
+ caddr_t *bp;
+{
+ int len = h->varlen;
+ int sublen;
+ Variable *var;
+ caddr_t bufp = *bp;
+
+ while ( len > 0 ) {
+ if ( *bufp++ == ASN_SEQUENCE ) {
+ len--;
+
+ /* Create new Variable instance */
+ if ( ( var = (Variable *)UM_ALLOC(sizeof(Variable)) ) == NULL )
+ {
+ *bp = bufp;
+ return;
+ }
+ /* Link to tail */
+ if ( h->tail )
+ h->tail->next = var;
+ /* Set head iff NULL */
+ if ( h->head == NULL ) {
+ h->head = var;
+ }
+ /* Adjust tail */
+ h->tail = var;
+
+ /* Get length of variable sequence */
+ sublen = asn_get_pdu_len ( &bufp, &len );
+ /* Should be OBJID type */
+ if ( *bufp++ != ASN_OBJID ) {
+ *bp = bufp;
+ return;
+ }
+ asn_get_objid ( &bufp, &var->oid, &len );
+ var->type = *bufp++;
+ len--;
+ switch ( var->type ) {
+ case ASN_INTEGER:
+ var->var.ival = asn_get_int ( &bufp, &len );
+ break;
+ case ASN_NULL:
+ bufp++;
+ len--;
+ break;
+ case ASN_OBJID:
+ asn_get_objid ( &bufp, &var->var.oval, &len );
+ break;
+ case ASN_OCTET:
+ asn_get_octet ( &bufp, var->var.sval, &len );
+ break;
+ default:
+ if ( Log ) {
+ write_timestamp();
+ fprintf ( Log, "Unknown variable type: %d\n",
+ var->type );
+ }
+ break;
+ }
+ var->next = NULL;
+ } else
+ break;
+ }
+
+ *bp = bufp;
+ return;
+}
+
+/*
* Crack the SNMP header
*
* Pull the PDU length, SNMP version, SNMP community and PDU type.
@@ -901,6 +908,8 @@ asn_get_header ( bufp )
{
Snmp_Header *h;
u_char *bp = *bufp;
+ int len = 0;
+ int dummy = 0;
/*
* Allocate memory to hold the SNMP header
@@ -909,6 +918,11 @@ asn_get_header ( bufp )
return ( (Snmp_Header *)NULL );
/*
+ * Ensure that we wipe the slate clean
+ */
+ UM_ZERO ( h, sizeof ( Snmp_Header ) );
+
+ /*
* PDU has to start as SEQUENCE OF
*/
if ( *bp++ != ASN_SEQUENCE ) /* Class == Universial, f == 1, tag == SEQUENCE */
@@ -917,7 +931,7 @@ asn_get_header ( bufp )
/*
* Get the length of remaining PDU data
*/
- h->pdulen = asn_get_pdu_len ( &bp );
+ h->pdulen = asn_get_pdu_len ( &bp, NULL );
/*
* We expect to find an integer encoding Version-1
@@ -925,7 +939,7 @@ asn_get_header ( bufp )
if ( *bp++ != ASN_INTEGER ) {
return ( (Snmp_Header *)NULL );
}
- h->version = asn_get_int ( &bp );
+ h->version = asn_get_int ( &bp, NULL );
/*
* After the version, we need the community name
@@ -933,8 +947,7 @@ asn_get_header ( bufp )
if ( *bp++ != ASN_OCTET ) {
return ( (Snmp_Header *)NULL );
}
- UM_ZERO ( h->community, sizeof ( h->community ) );
- asn_get_octet ( &bp, h->community );
+ asn_get_octet ( &bp, h->community, NULL );
/*
* Single byte PDU type
@@ -946,31 +959,43 @@ asn_get_header ( bufp )
*/
if ( h->pdutype != PDU_TYPE_TRAP ) { /* TRAP uses different format */
- bp++; /* Skip over data len */
+ (void) asn_get_pdu_len ( &bp, &dummy );
/* Request ID */
if ( *bp++ != ASN_INTEGER ) {
+ UM_FREE ( h );
return ( (Snmp_Header *)NULL );
}
- h->reqid = asn_get_int ( &bp );
+ h->reqid = asn_get_int ( &bp, NULL );
/* Error Status */
if ( *bp++ != ASN_INTEGER ) {
+ UM_FREE ( h );
return ( (Snmp_Header *)NULL );
}
- h->error = asn_get_int ( &bp );
+ h->error = asn_get_int ( &bp, NULL );
/* Error Index */
if ( *bp++ != ASN_INTEGER ) {
+ UM_FREE ( h );
+ return ( (Snmp_Header *)NULL );
+ }
+ h->erridx = asn_get_int ( &bp, NULL );
+
+ /* Sequence of... */
+ if ( *bp++ != ASN_SEQUENCE ) {
+ UM_FREE ( h );
return ( (Snmp_Header *)NULL );
}
- h->erridx = asn_get_int ( &bp );
+ h->varlen = ( asn_get_pdu_len ( &bp, &len ) - 1 );
+ h->varlen += ( len - 1 );
+ parse_oids ( h, &bp );
}
*bufp = bp;
- if ( Debug_Level > 2 )
+ if ( Log && Debug_Level )
print_header ( h );
return ( h );
@@ -978,7 +1003,7 @@ asn_get_header ( bufp )
}
/*
- * Compare to internal OID representations
+ * Compare two internal OID representations
*
* Arguments:
* oid1 - Internal Object Identifier
@@ -994,18 +1019,21 @@ oid_cmp ( oid1, oid2 )
Objid *oid1, *oid2;
{
int i;
+ int len;
/*
* Compare lengths
*/
- if ( !(oid1->oid[0] == oid2->oid[0]) )
+ if ( !(oid1->oid[0] == oid2->oid[0] ) )
/* Different lengths */
return ( 1 );
+ len = oid1->oid[0];
+
/*
* value by value compare
*/
- for ( i = 1; i <= oid1->oid[0]; i++ ) {
+ for ( i = 1; i <= len; i++ ) {
if ( !(oid1->oid[i] == oid2->oid[i]) )
/* values don't match */
return ( 1 );
@@ -1016,35 +1044,83 @@ oid_cmp ( oid1, oid2 )
}
/*
- * Encode a timeval as the number of time ticks
+ * Compare two internal OID representations
+ *
+ * Arguments:
+ * oid1 - Internal Object Identifier
+ * oid2 - Internal Object Identifier
+ * len - Length of OID to compare
*
- * Time ticks are the number of 100th's of a second since some event.
- * For sysUpTime, this is the time ticks since the application started,
- * not since the host came up. We only support encoding ticks since we
- * started running (what we are calling 'starttime').
+ * Returns:
+ * 0 - Objid's match
+ * 1 - Objid's don't match
+ *
+ */
+int
+oid_ncmp ( oid1, oid2, len )
+ Objid *oid1, *oid2;
+ int len;
+{
+ int i;
+
+ /*
+ * value by value compare
+ */
+ for ( i = 1; i <= len; i++ ) {
+ if ( !(oid1->oid[i] == oid2->oid[i]) )
+ /* values don't match */
+ return ( 1 );
+ }
+
+ /* Objid's are identical */
+ return ( 0 );
+}
+
+/*
+ * Find the index of a OBJID which matches this Variable instance
*
* Arguments:
- * bufp - pointer to buffer pointer
+ * var - pointer to Variable instance
*
* Returns:
- * bufp - updated buffper pointer
- * len - number of bytes to encode time ticks value
- * - ticks since 'starttime' encoded in buffer
+ * idx - index of matched Variable instance
+ * -1 - no matching Variable found
*
*/
int
-asn_encode_ticks ( bufp, ret )
- u_char **bufp;
- int *ret;
+find_var ( var )
+ Variable *var;
{
- struct timeval timenow;
- struct timeval timediff;
- u_char *bp = *bufp;
- int len, ticks;
+ int i;
+
+ for ( i = 0; i < NUM_OIDS; i++ )
+ if ( oid_cmp ( &var->oid, &Objids[i] ) == 0 ) {
+ return ( i );
+ }
+
+ return ( -1 );
+
+}
+
+/*
+ * Return the time process has been running as a number of ticks
+ *
+ * Arguments:
+ * none
+ *
+ * Returns:
+ * number of ticks
+ *
+ */
+int
+get_ticks()
+{
+ struct timeval timenow;
+ struct timeval timediff;
(void) gettimeofday ( &timenow, NULL );
/*
- * Adjust for subtraction
+ * Adjust for subtraction
*/
timenow.tv_sec--;
timenow.tv_usec += 1000000;
@@ -1064,139 +1140,252 @@ asn_encode_ticks ( bufp, ret )
}
/*
- * Compute 100th's of second in diff time structure
+ * Compute number of ticks
*/
- *ret = ticks = (timediff.tv_sec * 100) + (timediff.tv_usec / 10000);
-
- /*
- * The rest of this is just plain gross. I'm sure there
- * are better ways to do this...
- */
-
- /* Compute time ticks length */
- if ( ticks < 0xFF )
- len = 1;
- else if ( ticks < 0xFFFF )
- len = 2;
- else if ( ticks < 0xFFFFFF )
- len = 3;
- else
- len = 4;
-
- /*
- * Encode time ticks
- */
- *bp++ = ASN_TIMESTAMP; /* Time Ticks */
- *bp++ = len; /* length of value */
-
- /* there's always a better way but this is quick and dirty... */
- if ( ticks > 0xFFFFFF ) {
- *bp++ = ( ticks & 0xFF000000 ) >> 24;
- ticks &= 0xFFFFFF;
- }
- if ( ticks > 0xFFFF ) {
- *bp++ = ( ticks & 0xFF0000 ) >> 16;
- ticks &= 0xFFFF;
- }
- if ( ticks > 0xFF ) {
- *bp++ = ( ticks & 0xFF00 ) >> 8;
- ticks &= 0xFF;
- }
- *bp++ = ticks;
+ return ( ( timediff.tv_sec * 100 ) + ( timediff.tv_usec / 10000 ) );
- *bufp = bp;
- return ( len + 2 );
}
/*
- * Send back up sysUpTime response
+ * Build a response PDU
*
* Arguments:
- * sd - socket descriptor to send reply on
- * reqid - original GET request id
- *
+ * hdr - pointer to PDU Header with completed Variable list
+ *
* Returns:
- * none - response sent
+ * none
*
*/
void
-send_uptime_resp ( sd, reqid )
- int sd;
- int reqid;
+build_pdu ( hdr, type )
+ Snmp_Header *hdr;
+ int type;
{
- int len;
- short *sp;
- u_long *ip;
- u_char *bp;
- short val;
- int ticks;
+ u_char *bp = Resp_Buf;
+ u_char *vpp;
+ u_char *ppp;
+ int erridx = 0;
+ int varidx = 1;
+ int varlen = 0;
+ int pdulen = 0;
+ int traplen = 0;
+ Variable *var;
+
+ /*
+ * Clear out the reply
+ */
+ UM_ZERO ( Resp_Buf, sizeof(Resp_Buf) );
+
+ /* [0] is reserved for overall length */
+ bp++;
+
+ /* Start with SEQUENCE OF */
+ *bp++ = ASN_SEQUENCE;
+ /* - assume we can code length in two octets */
+ *bp++ = 0x82;
+ bp++;
+ bp++;
+ /* Version */
+ *bp++ = ASN_INTEGER;
+ asn_set_int ( &bp, hdr->version );
+ /* Community name */
+ *bp++ = ASN_OCTET;
+ *bp++ = strlen ( hdr->community );
+ UM_COPY ( hdr->community, bp, strlen ( hdr->community ) );
+ bp += strlen ( hdr->community );
+ /* PDU Type */
+ *bp++ = type;
+ ppp = bp;
+ /* Length of OID data - assume it'll fit in one octet */
+ bp++;
+
+ if ( type != PDU_TYPE_TRAP ) {
+ /* Sequence ID */
+ *bp++ = ASN_INTEGER;
+ asn_set_int ( &bp, hdr->reqid );
+ /*
+ * Check to see if all the vaiables were resolved - we do this
+ * by looking for something which still has a ASN_NULL value.
+ */
+ var = hdr->head;
+ if ( type == PDU_TYPE_GETRESP ) {
+ while ( var && erridx == 0 ) {
+ if ( var->type != ASN_NULL ) {
+ varidx++;
+ var = var->next;
+ } else
+ erridx = varidx;
+ }
+ }
- COPY_RESP ( sysUpTime_Resp );
+ /* Error status */
+ *bp++ = ASN_INTEGER;
+ *bp++ = 0x01; /* length = 1 */
+ if ( erridx )
+ *bp++ = 0x02; /* NoSuch */
+ else
+ *bp++ = 0x00; /* NoError */
+ /* Error Index */
+ *bp++ = ASN_INTEGER;
+ *bp++ = 0x01; /* length = 1 */
+ *bp++ = erridx; /* index - 0 if no error */
+ } else {
+ /* type == PDU_TYPE_TRAP */
+
+ /* Fill in ENTERPRISE OBJID */
+ *bp++ = ASN_OBJID;
+ (void) asn_put_objid ( &bp, &hdr->enterprise );
+
+ /* Fill in IP address */
+ *bp++ = ASN_IPADDR;
+ *bp++ = sizeof ( hdr->ipaddr );
+ UM_COPY ( (caddr_t)&hdr->ipaddr, bp, sizeof(hdr->ipaddr) );
+ bp += sizeof(hdr->ipaddr);
+
+ /* Fill in generic and specific trap types */
+ *bp++ = ASN_INTEGER;
+ asn_set_int ( &bp, hdr->generic_trap );
+ *bp++ = ASN_INTEGER;
+ asn_set_int ( &bp, hdr->specific_trap );
+
+ /* Fill in time-stamp - assume 0 for now */
+ *bp++ = ASN_TIMESTAMP;
+ asn_set_int ( &bp, 0 );
+
+ /* encoded length */
+ traplen = ( bp - ppp - 1 );
- bp = (u_char *)&Resp_Buf[Resp_Buf[0]+1];
- len = asn_encode_ticks ( &bp, &ticks );
+ /* Continue with variable processing */
+ }
- /*
- * Adjust overall length
- */
- bp = (u_char *)&Resp_Buf[0];
- *bp += len;
+ /* SEQUENCE OF */
+ *bp++ = ASN_SEQUENCE;
+ *bp++ = 0x82;
+ /* - assume we can code length in two octets */
+ vpp = bp;
+ varlen = 0;
+ bp++;
+ bp++;
+
+ /* Install Variables */
+ var = hdr->head;
+ varidx = 1;
+ while ( var ) {
+ u_char *bpp;
+ int len = 0;
+
+ /* SEQUENCE OF */
+ *bp++ = ASN_SEQUENCE;
+ *bp++ = 0x82;
+ /* - assume we can code length in two octets */
+ bpp = bp;
+ bp++;
+ bp++;
+ /* OBJID */
+ *bp++ = ASN_OBJID;
+ len++;
+ len += asn_put_objid ( &bp, &var->oid );
- /*
- * Adjust sequence lengths - works because this is my
- * PDU and I know all the variable lengths are fixed (ie.
- * reqid is always 4 byte encoded).
- */
-#ifndef sun
- sp = (short *)&Resp_Buf[3];
- val = ntohs ( *sp );
- *sp = htons ( val + len );
- Resp_Buf[15] += len;
- sp = (u_short *)&Resp_Buf[30];
- val = ntohs ( *sp );
- *sp = htons ( val + len );
- sp = (u_short *)&Resp_Buf[34];
- val = ntohs ( *sp );
- *sp = htons ( val + len );
-#else
- /* Sun SPARCs have alignment requirements */
- Resp_Buf[4] += len;
- Resp_Buf[15] += len;
- Resp_Buf[31] += len;
- Resp_Buf[35] += len;
-#endif /* sun */
+ if ( erridx && varidx >= erridx ) {
+ /* Code this variable as NULL */
+ *bp++ = ASN_NULL;
+ len++;
+ bp++;
+ len++;
+ } else {
+ u_char *lpp;
+ /* Variable type */
+ *bp++ = var->type;
+ len++;
+ lpp = bp;
+ switch ( var->type ) {
+ case ASN_INTEGER:
+ asn_set_int ( &bp, var->var.ival );
+ len += ( *lpp + 1 );
+ break;
+ case ASN_OCTET:
+ *bp++ = var->var.sval[0];
+ len++;
+ UM_COPY ( (caddr_t)&var->var.sval[1],
+ bp, var->var.sval[0] );
+ len += var->var.sval[0];
+ bp += var->var.sval[0];
+ break;
+ case ASN_NULL:
+ *bp++ = 0x00;
+ len++;
+ break;
+ case ASN_OBJID:
+ len += asn_put_objid ( &bp, &var->var.oval );
+ break;
+ case ASN_SEQUENCE:
+ break;
+ case ASN_IPADDR:
+ *bp++ = 4;
+ len++;
+ UM_COPY ( (caddr_t)&var->var.aval, bp, 4 );
+ len += 4;
+ bp += 4;
+ break;
+ case ASN_TIMESTAMP:
+ asn_set_int ( &bp, var->var.ival );
+ len += ( *lpp + 1 );
+ break;
+ default:
+ break;
+ }
+ }
- /*
- * Store the original request ID in the response
- */
- set_reqid ( Resp_Buf, reqid );
-#ifdef notdef
-#ifndef sun
- ip = (u_long *)&Resp_Buf[18];
- *ip = htonl ( reqid );
-#else
- /* Sun SPARCs have alignment requirements */
- UM_COPY ( (caddr_t)&reqid, (caddr_t)&Resp_Buf[18], sizeof(reqid) );
-#endif /* sun */
-#endif
+ /* Accumulate total Variable sequence length */
+ varlen += (len + 4);
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log, "\tSend sysUpTime: %d\n", ticks );
+ /* Fill in length of this sequence */
+ bpp[1] = len & 0xff;
+ bpp[0] = len >> 8;
+
+ var = var->next;
}
- if ( Debug_Level > 4 && Log ) {
- write_timestamp();
- fprintf ( Log, "\n===== Sent %d bytes =====\n", Resp_Buf[0] );
- hexdump ( (u_char *)&Resp_Buf[1], Resp_Buf[0] );
+
+ /* Fill in length of Variable sequence */
+ vpp[1] = varlen & 0xff;
+ vpp[0] = varlen >> 8;
+
+ if ( type != PDU_TYPE_TRAP ) {
+ /* Fill in length of data AFTER PDU type */
+ *ppp = varlen + 12 + ppp[2]; /* + length of reqid */
+ } else {
+ /* Fill in length of data AFTER PDU type */
+ *ppp = varlen + traplen + 4; /* + length of initial sequence of */
}
- /*
- * Send response
- */
- write ( sd, (caddr_t)&Resp_Buf[1], Resp_Buf[0] );
+
+ /* Fill in overall sequence length */
+ pdulen = *ppp + 7 + strlen ( hdr->community );
+ Resp_Buf[4] = pdulen & 0x7f;
+ Resp_Buf[3] = pdulen >> 8;
+
+ pdulen = bp - Resp_Buf - 1;
+
+ Resp_Buf[0] = pdulen;
+
+ hdr->pdutype = type;
return;
+}
+void
+free_pdu ( hdr )
+Snmp_Header *hdr;
+{
+ Variable *var;
+
+ while ( hdr->head ) {
+ var = hdr->head->next; /* Save next link */
+ UM_FREE ( hdr->head ); /* Free current var */
+ hdr->head = var; /* Set head to next link */
+ }
+
+ UM_FREE ( hdr ); /* Free fixed portion */
}
/*
@@ -1221,11 +1410,7 @@ set_reqid ( resp, reqid )
u_char c[4];
} u;
-#ifndef sun
u.i = htonl(reqid);
-#else
- u.i = reqid;
-#endif /* !sun */
/*
* Replace the current Request ID with the supplied value
@@ -1233,7 +1418,6 @@ set_reqid ( resp, reqid )
UM_COPY ( (caddr_t)&u.c[4-resp[17]], bp, resp[17] );
return;
-
}
/*
@@ -1249,24 +1433,77 @@ set_reqid ( resp, reqid )
*
*/
void
-send_resp ( sd, reqid, resp )
- int sd;
- int reqid;
+send_resp ( intf, Hdr, resp )
+ int intf;
+ Snmp_Header *Hdr;
u_char *resp;
{
+ int n;
- set_reqid ( resp, reqid );
-
- if ( Debug_Level > 1 && Log ) {
+ if ( ilmi_fd[intf] > 0 ) {
+ n = write ( ilmi_fd[intf], (caddr_t)&resp[1], resp[0] );
+ if ( Log && Debug_Level > 1 ) {
write_timestamp();
- fprintf ( Log, "===== Sent %d bytes =====\n", resp[0] );
- hexdump ( (u_char *)&resp[1], resp[0] );
+ fprintf ( Log, "===== Sent %d of %d bytes (%d) =====\n", n, resp[0], ilmi_fd[intf] );
+ print_header ( Hdr );
+ if ( Debug_Level > 2 )
+ hexdump ( (u_char *)&resp[1], resp[0] );
+ }
}
- write ( sd, (caddr_t)&resp[1], resp[0] );
+ free_pdu ( Hdr );
return;
}
+/*
+ * Build a COLD_START TRAP PDU
+ *
+ */
+Snmp_Header *
+build_cold_start()
+{
+ Snmp_Header *hdr;
+ Variable *var;
+
+ hdr = (Snmp_Header *)UM_ALLOC (sizeof(Snmp_Header));
+
+ hdr->pdulen = 0;
+ hdr->version = SNMP_VERSION_1 - 1;
+ snprintf ( hdr->community, sizeof(hdr->community), "ILMI" );
+
+ hdr->ipaddr = 0x0; /* 0.0.0.0 */
+ hdr->generic_trap = TRAP_COLDSTART;
+ hdr->specific_trap = 0;
+ UM_COPY ( (caddr_t)&Objids[ENTERPRISE_OBJID], (caddr_t)&hdr->enterprise,
+ sizeof(Objid) );
+
+ hdr->head = (Variable *)UM_ALLOC(sizeof(Variable));
+ var = hdr->head;
+ UM_COPY ( (caddr_t)&Objids[UPTIME_OBJID], (caddr_t)&var->oid,
+ sizeof(Objid) );
+ var->type = ASN_NULL;
+
+ return ( hdr );
+}
+
+/*
+ * Build a Generic PDU Header
+ *
+ */
+Snmp_Header *
+build_generic_header()
+{
+ Snmp_Header *hdr;
+
+ hdr = (Snmp_Header *)UM_ALLOC(sizeof(Snmp_Header));
+
+ hdr->pdulen = 0;
+ hdr->version = SNMP_VERSION_1 - 1;
+ snprintf ( hdr->community, sizeof(hdr->community), "ILMI" );
+
+ return ( hdr );
+}
+
/*
* Initialize information on what physical adapters HARP knows about
*
@@ -1285,7 +1522,7 @@ void
init_ilmi()
{
struct air_cfg_rsp *cfg_info = NULL;
- struct air_intf_rsp *intf_info = NULL;
+ struct air_int_rsp *intf_info = NULL;
int buf_len;
/*
@@ -1299,10 +1536,6 @@ init_ilmi()
UM_ZERO ( Cfg, sizeof(Cfg) );
UM_ZERO ( Intf, sizeof(Intf) );
NUnits = 0;
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log, "NUnits: %d\n", NUnits );
- }
return;
}
@@ -1314,12 +1547,8 @@ init_ilmi()
* Compute how many units information was returned for
*/
NUnits = buf_len / sizeof(struct air_cfg_rsp);
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log, "NUnits: %d\n", NUnits );
- }
/* Housecleaning */
- free ( cfg_info );
+ UM_FREE ( cfg_info );
cfg_info = NULL;
/*
* Get the per interface information
@@ -1338,7 +1567,7 @@ init_ilmi()
*/
UM_COPY ( intf_info, (caddr_t)Intf, buf_len );
/* Housecleaning */
- free ( intf_info );
+ UM_FREE ( intf_info );
intf_info = NULL;
return;
@@ -1370,28 +1599,15 @@ ilmi_open ()
struct t_atm_qos qos;
struct t_atm_app_name appname;
Atm_addr subaddr;
- char buffer[MAX_LEN+1];
char nifname[IFNAMSIZ];
int optlen;
int unit = 0;
- struct timer_elem *open_timer,
- *state_timer;
u_char sig_proto;
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log, "ilmi_open()\n" );
- }
init_ilmi();
for ( unit = 0; unit < NUnits; unit++ ) {
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log, "Unit: %d Sig: %d Trap: %d Ilmi: %d\n",
- unit, Intf[unit].anp_sig_proto, trap_fd[unit],
- ilmi_fd[unit] );
- }
/*
* ILMI only makes sense for UNI signalling protocols
*/
@@ -1400,16 +1616,11 @@ ilmi_open ()
sig_proto != ATM_SIG_UNI40 )
continue;
- /*
- * If we're waiting for a coldStart TRAP, we'll be in trap_fd[],
- * If we're processing ILMI, we'll be in ilmi_fd[], otherwise,
- * this unit hasn't been opened yet.
- */
- if ( trap_fd[unit] == -1 && ilmi_fd[unit] == -1 ) {
+ if ( ilmi_fd[unit] == -1 ) {
- trap_fd[unit] = socket ( AF_ATM, SOCK_SEQPACKET, ATM_PROTO_AAL5 );
+ ilmi_fd[unit] = socket ( AF_ATM, SOCK_SEQPACKET, ATM_PROTO_AAL5 );
- if ( trap_fd[unit] < 0 ) {
+ if ( ilmi_fd[unit] < 0 ) {
perror ( "open" );
continue;
}
@@ -1422,14 +1633,13 @@ ilmi_open ()
write_timestamp();
fprintf ( Log, "No nif on unit %d\n", unit );
}
- close ( trap_fd[unit] );
- trap_fd[unit] = -1;
+ close ( ilmi_fd[unit] );
ilmi_fd[unit] = -1;
continue;
}
- sprintf ( nifname, "%s0\0", Intf[unit].anp_nif_pref );
+ sprintf ( nifname, "%s0", Intf[unit].anp_nif_pref );
optlen = sizeof ( nifname );
- if ( setsockopt ( trap_fd[unit], T_ATM_SIGNALING,
+ if ( setsockopt ( ilmi_fd[unit], T_ATM_SIGNALING,
T_ATM_NET_INTF, (caddr_t)nifname, optlen ) < 0 ) {
perror ( "setsockopt" );
if ( Log ) {
@@ -1442,9 +1652,8 @@ ilmi_open ()
write_timestamp();
fprintf ( Log, "nifname: closing unit %d\n", unit );
}
- close ( trap_fd[unit] );
- trap_fd[unit] = -1;
- ilmi_fd[unit] = -1;
+ close ( ilmi_fd[unit] );
+ ilmi_fd[unit] = -1;
continue;
}
@@ -1453,9 +1662,9 @@ ilmi_open ()
*/
UM_ZERO ( (caddr_t) &satm, sizeof(satm) );
satm.satm_family = AF_ATM;
-#ifndef sun
+#if (defined(BSD) && (BSD >= 199103))
satm.satm_len = sizeof(satm);
-#endif /* sun */
+#endif
satm.satm_addr.t_atm_sap_addr.SVE_tag_addr = T_ATM_PRESENT;
satm.satm_addr.t_atm_sap_addr.SVE_tag_selector = T_ATM_ABSENT;
@@ -1481,15 +1690,14 @@ ilmi_open ()
aal5.backward_max_SDU_size = MAX_LEN;
aal5.SSCS_type = T_ATM_NULL;
optlen = sizeof(aal5);
- if ( setsockopt ( trap_fd[unit], T_ATM_SIGNALING, T_ATM_AAL5,
+ if ( setsockopt ( ilmi_fd[unit], T_ATM_SIGNALING, T_ATM_AAL5,
(caddr_t) &aal5, optlen ) < 0 ) {
perror ( "setsockopt(aal5)" );
if ( Debug_Level > 1 && Log ) {
write_timestamp();
fprintf ( Log, "aal5: closing unit %d\n", unit );
}
- close ( trap_fd[unit] );
- trap_fd[unit] = -1;
+ close ( ilmi_fd[unit] );
ilmi_fd[unit] = -1;
continue;
}
@@ -1510,7 +1718,7 @@ ilmi_open ()
traffic.backward.tagging = T_NO;
traffic.best_effort = T_YES;
optlen = sizeof(traffic);
- if (setsockopt(trap_fd[unit], T_ATM_SIGNALING, T_ATM_TRAFFIC,
+ if (setsockopt(ilmi_fd[unit], T_ATM_SIGNALING, T_ATM_TRAFFIC,
(caddr_t)&traffic, optlen) < 0) {
perror("setsockopt(traffic)");
}
@@ -1520,7 +1728,7 @@ ilmi_open ()
bearer.clipping_susceptibility = T_NO;
bearer.connection_configuration = T_ATM_1_TO_1;
optlen = sizeof(bearer);
- if (setsockopt(trap_fd[unit], T_ATM_SIGNALING, T_ATM_BEARER_CAP,
+ if (setsockopt(ilmi_fd[unit], T_ATM_SIGNALING, T_ATM_BEARER_CAP,
(caddr_t)&bearer, optlen) < 0) {
perror("setsockopt(bearer)");
}
@@ -1529,7 +1737,7 @@ ilmi_open ()
qos.forward.qos_class = T_ATM_QOS_CLASS_0;
qos.backward.qos_class = T_ATM_QOS_CLASS_0;
optlen = sizeof(qos);
- if (setsockopt(trap_fd[unit], T_ATM_SIGNALING, T_ATM_QOS, (caddr_t)&qos,
+ if (setsockopt(ilmi_fd[unit], T_ATM_SIGNALING, T_ATM_QOS, (caddr_t)&qos,
optlen) < 0) {
perror("setsockopt(qos)");
}
@@ -1537,14 +1745,14 @@ ilmi_open ()
subaddr.address_format = T_ATM_ABSENT;
subaddr.address_length = 0;
optlen = sizeof(subaddr);
- if (setsockopt(trap_fd[unit], T_ATM_SIGNALING, T_ATM_DEST_SUB,
+ if (setsockopt(ilmi_fd[unit], T_ATM_SIGNALING, T_ATM_DEST_SUB,
(caddr_t)&subaddr, optlen) < 0) {
perror("setsockopt(dest_sub)");
}
strncpy(appname.app_name, "ILMI", T_ATM_APP_NAME_LEN);
optlen = sizeof(appname);
- if (setsockopt(trap_fd[unit], T_ATM_SIGNALING, T_ATM_APP_NAME,
+ if (setsockopt(ilmi_fd[unit], T_ATM_SIGNALING, T_ATM_APP_NAME,
(caddr_t)&appname, optlen) < 0) {
perror("setsockopt(appname)");
}
@@ -1552,15 +1760,14 @@ ilmi_open ()
/*
* Now try to connect to destination
*/
- if ( connect ( trap_fd[unit], (struct sockaddr *) &satm,
+ if ( connect ( ilmi_fd[unit], (struct sockaddr *) &satm,
sizeof(satm)) < 0 ) {
perror ( "connect" );
if ( Debug_Level > 1 && Log ) {
write_timestamp();
fprintf ( Log, "connect: closing unit %d\n", unit );
}
- close ( trap_fd[unit] );
- trap_fd[unit] = -1;
+ close ( ilmi_fd[unit] );
ilmi_fd[unit] = -1;
continue;
}
@@ -1569,61 +1776,44 @@ ilmi_open ()
write_timestamp();
fprintf ( Log, "***** opened unit %d\n", unit );
}
- /*
- * Send coldStart TRAP
- */
- if ( Debug_Level > 4 && Log ) {
- write_timestamp();
- fprintf ( Log, "===== Sent %d bytes =====\n",
- coldStart_Trap[0] );
- hexdump ( (u_char *)&coldStart_Trap[1], coldStart_Trap[0] );
- }
- if ( Debug_Level && Log ) {
- write_timestamp();
- fprintf ( Log, "\tSend coldStart TRAP to unit %d\n", unit );
- }
- last_trap[unit] = time ( (time_t *)NULL );
- write ( trap_fd[unit], (caddr_t)&coldStart_Trap[1],
- coldStart_Trap[0] );
+
+ ilmi_state[unit] = ILMI_COLDSTART;
+
}
}
- signal ( SIGALRM, ilmi_open );
- alarm ( SLEEP_TIME );
-
return;
}
/*
- * Send our local IP address for this interface
+ * Get our local IP address for this interface
*
* Arguments:
- * s - socket to send message on
- * hdr - pointer to internal SNMP header
+ * s - socket to find address for
+ * aval - pointer to variable to store address in
*
* Returns:
* none
*
*/
void
-send_myipnm ( s, hdr )
- int s;
- Snmp_Header *hdr;
+get_local_ip ( s, aval )
+ int s;
+ long *aval;
{
- char intf_name[IFNAMSIZ];
- int namelen = IFNAMSIZ;
- struct air_netif_rsp *net_info = NULL;
+ char intf_name[IFNAMSIZ];
+ int namelen = IFNAMSIZ;
+ struct air_netif_rsp *net_info = NULL;
struct sockaddr_in *sin;
- COPY_RESP ( MyIpNm_Resp );
-
+ /*
+ * Get physical interface name
+ */
if ( getsockopt ( s, T_ATM_SIGNALING, T_ATM_NET_INTF,
- (caddr_t) intf_name, &namelen ) ) {
- perror ( "Couldn't get socket name" );
- return;
- }
+ (caddr_t) intf_name, &namelen ) )
+ return;
/*
* Get network interface information for this physical interface
@@ -1635,23 +1825,14 @@ send_myipnm ( s, hdr )
sin = (struct sockaddr_in *)&net_info->anp_proto_addr;
/*
- * Copy interface's IP address into reply packet
+ * Fill in answer
*/
- UM_COPY ( (caddr_t)&sin->sin_addr.s_addr, (caddr_t)&Resp_Buf[51],
- 4 );
-
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log, "\tSend NM IP address\n" );
- }
+ UM_COPY ( (caddr_t)&sin->sin_addr.s_addr, aval, 4 );
- send_resp ( s, hdr->reqid, Resp_Buf );
+ UM_FREE ( net_info );
- /*
- * Clean up
- */
- free ( net_info );
return;
+
}
/*
@@ -1672,40 +1853,29 @@ send_myipnm ( s, hdr )
*
*/
void
-set_prefix ( oid, hdr, buf, s )
+set_prefix ( oid, hdr, intf )
Objid *oid;
Snmp_Header *hdr;
- u_char *buf;
- int s;
+ int intf;
{
- struct atmsetreq asr;
- Atm_addr *aa;
- int fd;
- int i;
- u_char *cpp;
- int len; /* PDU length before completion */
-
- /*
- * If we don't reply to the SET then it keeps getting retransmitted.
- */
- buf[14] = PDU_TYPE_GETRESP;
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log, "\tSend SET_RESPONSE\n" );
- }
- send_resp ( s, hdr->reqid, buf );
+ struct atmsetreq asr;
+ Atm_addr *aa;
+ int fd;
+ int i;
/*
* Build IOCTL request to set prefix
*/
asr.asr_opcode = AIOCS_SET_PRF;
- strncpy ( asr.asr_prf_intf, Intf[0].anp_intf,
+ strncpy ( asr.asr_prf_intf, Intf[intf].anp_intf,
sizeof(asr.asr_prf_intf ) );
/*
* Pull prefix out of received Objid
+ * save in set_prefix IOCTL and addressEntry table
*/
- for ( i = 0; i < oid->oid[13]; i++ )
+ for ( i = 0; i < oid->oid[13]; i++ ) {
asr.asr_prf_pref[i] = oid->oid[i + 14];
+ }
/*
* Pass new prefix to the HARP kernel
@@ -1718,9 +1888,10 @@ set_prefix ( oid, hdr, buf, s )
syslog ( LOG_ERR, "ilmid: error setting prefix: %m" );
if ( Log ) {
write_timestamp();
- fprintf ( Log, "ilmid: errno %d setting prefix\n",
+ fprintf ( Log, "errno %d setting prefix\n",
errno );
}
+ close ( fd );
return;
}
}
@@ -1731,375 +1902,58 @@ set_prefix ( oid, hdr, buf, s )
*/
init_ilmi();
- aa = &Intf[0].anp_addr;
+ aa = &Intf[intf].anp_addr;
/*
- * Finish building SET NSAP packet
+ * Copy our NSAP into addressEntry table
*/
- COPY_RESP ( NetPrefix_Resp );
-
- len = Resp_Buf[0];
- cpp = &Resp_Buf[len + 1]; /* Set to end of response buffer */
- len++;
- *cpp++ = aa->address_length;
+ addressEntry[intf].oid[0] = 0;
for ( i = 0; i < aa->address_length; i++ ) {
- u_char c = ((u_char *)(aa->address))[i];
+ addressEntry[intf].oid[0]++; /* Increment length */
+ addressEntry[intf].oid[i + 1] = (int)((u_char *)(aa->address))[i];
- if ( c > 127 ) {
- *cpp++ = ( c >> 7 ) | 0x80;
- len++;
- c &= 0x7f;
- }
- *cpp++ = c;
- len++;
- }
- /*
- * Pack "set = 1" onto end
- */
- *cpp++ = 0x02;
- *cpp++ = 0x01;
- *cpp++ = 0x01;
- len += 3;
-
- /*
- * Go back and patch up lengths...
- */
- Resp_Buf[0] = len;
- Resp_Buf[4] = (u_char)(len - 4);
- Resp_Buf[15] = (u_char)(len - 15);
- Resp_Buf[31] = (u_char)(len - 31);
- Resp_Buf[35] = (u_char)(len - 35);
- Resp_Buf[37] = (u_char)(len - 40);
-
- /*
- * Set reqid
- */
- set_reqid ( Resp_Buf, Req_ID++ );
-
- /*
- * Send SET
- */
- if ( Debug_Level > 2 && Log ) {
- write_timestamp();
- fprintf ( Log, "===== Send SET: %d bytes =====\n",
- Resp_Buf[0] );
- hexdump ( (u_char *)&Resp_Buf[1], Resp_Buf[0] );
}
- write ( s, (caddr_t)&Resp_Buf[1], Resp_Buf[0] );
return;
}
-Objid oid;
-
-/*
- * Parse an ASN_TYPE_SET pdu
- *
- * Crack apart the various pieces of a SET message. The OBJID being set is
- * left in oid which is compared and handled else where.
- *
- * Arguments:
- * bp - pointer to current location in PDU buffer
- *
- * Returns:
- * bp - updated buffer pointer
- * 0 - no error
- * -1 - error in PDU
- *
- */
-int
-process_set ( bp )
- caddr_t *bp;
-{
- caddr_t bufp = *bp;
- int pdulen;
- int b;
-
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log, "SET:: " );
- }
- /*
- * Should be SEQUENCE OF
- */
- if ( *bufp++ != ASN_SEQUENCE ) {
- *bp = bufp;
- return ( -1 );
- }
- pdulen = asn_get_pdu_len ( &bufp );
- /*
- * Should be SEQUENCE OF
- */
- if ( *bufp++ != ASN_SEQUENCE ) {
- *bp = bufp;
- return ( -1 );
- }
- pdulen = asn_get_pdu_len ( &bufp );
- /*
- * Should be OBJID
- */
- if ( *bufp++ != ASN_OBJID ) {
- *bp = bufp;
- return ( -1 );
- }
- asn_get_objid ( &bufp, &oid );
- /*
- * Should be <= value>
- */
- switch ( *bufp++ ) {
- case ASN_INTEGER:
- b = asn_get_int ( &bufp );
- if ( Debug_Level > 5 && Log ) {
- write_timestamp();
- fprintf ( Log, "Value = %d\n", b );
- }
- break;
- case ASN_OBJID:
- break;
- }
-
- /*
- * Return updated pointer
- */
- *bp = bufp;
-
- return ( 0 );
-}
-
-int specific_trap;
-int generic_trap;
-int trap_time;
-u_char trap_ip[5];
-Objid trap_oid;
-Objid extra_trap_oid;
-
-/*
- * Parse an ASN_TYPE_TRAP pdu
- *
- * Crack apart the various pieces of a TRAP message. The information elements are
- * left in global space and used elsewhere if anyone cares (which they currently don't).
- *
- * Arguments:
- * bp - pointer to current location in PDU buffer
- * sd - socket descriptor pdu arrived on
- *
- * Returns:
- * bp - updated buffer pointer
- * 0 - no error
- * -1 - error in PDU
- *
- */
-int
-process_trap ( bp, sd )
- caddr_t *bp;
- int sd;
-{
- caddr_t bufp = *bp;
- int pdulen;
- int i;
-
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log, "TRAP:: " );
- }
- /*
- * Should be pdulen
- */
- pdulen = *bufp++;
- /*
- * Should be OBJID
- */
- if ( *bufp++ != ASN_OBJID ) {
- if ( Log )
- fprintf ( Log, "\n" );
- *bp = bufp;
- return ( -1 );
- }
- asn_get_objid ( &bufp, &trap_oid );
- /*
- * First oid coded as 40 * X + Y
- */
- if ( Debug_Level > 5 && Log ) {
- write_timestamp();
- fprintf ( Log, "%d.%d", trap_oid.oid[1] / 40,
- trap_oid.oid[1] % 40 );
- for ( i = 2; i <= trap_oid.oid[0]; i++ )
- fprintf ( Log, ".%d", trap_oid.oid[i] );
- fprintf ( Log, "\n" );
- }
- /*
- * Should be OCTET STRING
- */
- if ( *bufp++ != ASN_IPADDR ) {
- if ( Debug_Level > 5 && Log ) {
- write_timestamp();
- fprintf ( Log, "Expected IP ADDRESS\n" );
- }
- *bp = bufp;
- return ( -1 );
- }
- asn_get_octet ( &bufp, trap_ip );
- if ( Debug_Level > 5 && Log) {
- write_timestamp();
- fprintf ( Log, "\tIP: %d.%d.%d.%d",
- trap_ip[0], trap_ip[1], trap_ip[2], trap_ip[3] );
- }
- /*
- * Should be Generic Trap followed by Specific Trap
- */
- if ( *bufp++ != ASN_INTEGER ) {
- if ( Log )
- fprintf ( Log, "\n" );
- *bp = bufp;
- return ( -1 );
- }
- generic_trap = asn_get_int ( &bufp );
- if ( Debug_Level > 5 && Log ) {
- fprintf ( Log, " Generic Trap: %s (%d)",
- Traps[generic_trap], generic_trap );
- }
- if ( *bufp++ != ASN_INTEGER ) {
- if ( Log )
- fprintf ( Log, "\n" );
- *bp = bufp;
- return ( -1 );
- }
- specific_trap = asn_get_int ( &bufp );
- if ( Debug_Level > 5 && Log ) {
- fprintf ( Log, " Specific Trap: 0x%x\n",
- specific_trap );
- }
- /*
- * Should be TIMESTAMP
- */
- if ( *bufp++ != ASN_TIMESTAMP ) {
- if ( Log )
- fprintf ( Log, "\n" );
- *bp = bufp;
- return ( -1 );
- }
- trap_time = asn_get_int ( &bufp );
- if ( Debug_Level > 5 && Log ) {
- write_timestamp();
- fprintf ( Log, "\tTimestamp: %d seconds", trap_time );
- }
- /*
- * Should be SEQUENCE OF
- */
- if ( *bufp++ != ASN_SEQUENCE ) {
- *bp = bufp;
- return ( -1 );
- }
- pdulen = asn_get_pdu_len ( &bufp );
- /*
- * Should be OBJID
- */
- if ( *bufp++ != ASN_OBJID ) {
- *bp = bufp;
- return ( -1 );
- }
- asn_get_objid ( &bufp, &extra_trap_oid );
- if ( Debug_Level > 5 && Log ) {
- write_timestamp();
- fprintf ( Log, "\tExtra Objid: " );
- fprintf ( Log, "%d.%d", extra_trap_oid.oid[1] / 40,
- extra_trap_oid.oid[1] % 40 );
- for ( i = 2; i <= extra_trap_oid.oid[0]; i++ )
- fprintf ( Log, ".%d", extra_trap_oid.oid[i] );
- fprintf ( Log, "\n" );
- }
- /*
- * Whole thing ended with a NULL
- */
- bufp++;
- bufp++;
-
- /*
- * Return updated pointer
- */
- *bp = bufp;
-
- if ( generic_trap == 0 ) {
- write ( sd, (caddr_t)&coldStart_Trap[1],
- coldStart_Trap[0] );
- }
-
- return ( 0 );
-
-}
-
-u_char No_Such[] = { 37,
- 0x30, 0x82, 0x00, 0x00,
- 0x02, 0x01, 0x00,
- 0x04, 0x04, 0x49, 0x4c, 0x4d, 0x49,
- PDU_TYPE_GETRESP,
- 0x00,
- 0x02, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x01, 0x02,
- 0x02, 0x01, 0x01,
- 0x30, 0x82, 0x00, 0x00,
- 0x30, 0x82, 0x00, 0x00,
- 0x06, 0x00
- };
void
-send_no_such ( s, Hdr, op )
- int s;
- Snmp_Header *Hdr;
- Objid *op;
+set_address ( hdr, intf )
+ Snmp_Header *hdr;
+ int intf;
{
- u_char *cp, *cpp;
- int len;
- int i;
-
- len = No_Such[0];
-
- UM_COPY ( No_Such, Resp_Buf, len + 1 );
-
- cp = cpp = (u_char *)&Resp_Buf[len];
-
- /*
- * Copy OID into response buffer
- */
- *cp++ = op->oid[0];
- for ( i = 1; i <= op->oid[0]; i++ ) {
- u_int c = op->oid[i];
-
- if ( c > 127 ) {
- *cp++ = ( c >> 7 ) | 0x80;
- len++;
- c &= 0x7f;
- /*
- * Increment OID length
- */
- *cpp += 1;
- }
- *cp++ = c;
- len++;
- }
- /*
- * Finish off with a NULL
- */
- *cp++ = 0x05;
- *cp++ = 0x00;
- len += 2;
-
- /*
- * Patch up all the length locations
- */
- Resp_Buf[0] = len;
- Resp_Buf[4] = len - 4;
- Resp_Buf[15] = len - 15;
- Resp_Buf[31] = len - 31;
- Resp_Buf[35] = len - 35;
-
- /*
- * Send Response
- */
- send_resp ( s, Hdr->reqid, Resp_Buf );
-
- return;
+ Variable *var;
+ int i, j;
+
+ PDU_Header = build_generic_header();
+ PDU_Header->head = (Variable *)UM_ALLOC(sizeof(Variable));
+ var = PDU_Header->head;
+ /* Copy generic addressEntry OBJID */
+ UM_COPY ( (caddr_t)&Objids[ADDRESS_OBJID], (caddr_t)&var->oid,
+ sizeof(Objid) );
+ /* Set specific instance */
+ i = var->oid.oid[0] + 1; /* Get length */
+ var->oid.oid[i++] = 1;
+ var->oid.oid[i++] = 1;
+ var->oid.oid[i++] = 3;
+ var->oid.oid[i++] = 0;
+
+ /* Copy in address length */
+ var->oid.oid[i++] = addressEntry[intf].oid[0];
+
+ /* Copy in address */
+ for ( j = 0; j < addressEntry[intf].oid[0]; j++ )
+ var->oid.oid[i++] = addressEntry[intf].oid[j + 1];
+ var->oid.oid[0] = i - 1; /* Set new length */
+
+ /* Set == VALID */
+ var->type = ASN_INTEGER;
+ var->var.ival = 1;
+
+ build_pdu ( PDU_Header, PDU_TYPE_SET );
+ send_resp ( intf, PDU_Header, Resp_Buf );
}
/*
@@ -2143,13 +1997,20 @@ Increment_DL ( sig )
int sig;
{
Debug_Level++;
- if ( Debug_Level && Log == (FILE *)NULL )
- if ( ( Log = fopen ( LOG_FILE, "a" ) ) == NULL )
- Log = NULL;
- else
+ if ( Debug_Level && Log == (FILE *)NULL ) {
+ if ( foregnd ) {
+ Log = stderr;
+ } else {
+ if ( ( Log = fopen ( LOG_FILE, "a" ) ) == NULL )
+ Log = NULL;
+ }
+ if ( Log ) {
setbuf ( Log, NULL );
+ write_timestamp();
+ fprintf ( Log, "Raised Debug_Level to %d\n", Debug_Level );
+ }
+ }
signal ( SIGUSR1, Increment_DL );
- alarm ( SLEEP_TIME );
return;
}
@@ -2173,37 +2034,388 @@ Decrement_DL ( sig )
if ( Debug_Level <= 0 ) {
Debug_Level = 0;
if ( Log ) {
- fclose ( Log );
+ write_timestamp();
+ fprintf ( Log, "Lowered Debug_Level to %d\n", Debug_Level );
+ if ( !foregnd )
+ fclose ( Log );
Log = NULL;
}
}
signal ( SIGUSR2, Decrement_DL );
- alarm ( SLEEP_TIME );
return;
}
+/*
+ * Loop through GET variable list looking for matches
+ *
+ */
+void
+process_get ( hdr, intf )
+ Snmp_Header *hdr;
+ int intf;
+{
+ Variable *var;
+ int idx;
+
+ var = hdr->head;
+ while ( var ) {
+ idx = find_var ( var );
+ switch ( idx ) {
+ case SYS_OBJID:
+ var->type = ASN_OBJID;
+ UM_COPY ( (caddr_t)&Objids[MY_OBJID],
+ (caddr_t)&var->var.oval,
+ sizeof(Objid) );
+ break;
+ case UPTIME_OBJID:
+ var->type = ASN_TIMESTAMP;
+ var->var.ival = get_ticks();
+ break;
+ case UNITYPE_OBJID:
+ var->type = ASN_INTEGER;
+ var->var.ival = UNITYPE_PRIVATE;
+ break;
+ case UNIVER_OBJID:
+ var->type = ASN_INTEGER;
+ switch ( Intf[intf].anp_sig_proto ) {
+ case ATM_SIG_UNI30:
+ var->var.ival = UNIVER_UNI30;
+ break;
+ case ATM_SIG_UNI31:
+ var->var.ival = UNIVER_UNI31;
+ break;
+ case ATM_SIG_UNI40:
+ var->var.ival = UNIVER_UNI40;
+ break;
+ default:
+ var->var.ival = UNIVER_UNKNOWN;
+ break;
+ }
+ break;
+ case DEVTYPE_OBJID:
+ var->type = ASN_INTEGER;
+ var->var.ival = DEVTYPE_USER;
+ break;
+ case MAXVCC_OBJID:
+ var->type = ASN_INTEGER;
+ var->var.ival = 1024;
+ break;
+ case PORT_OBJID:
+ var->type = ASN_INTEGER;
+ var->var.ival = intf + 1;
+ break;
+ case IPNM_OBJID:
+ var->type = ASN_IPADDR;
+ get_local_ip ( ilmi_fd[intf],
+ &var->var.ival );
+ break;
+ case ADDRESS_OBJID:
+ break;
+ case ATMF_PORTID:
+ var->type = ASN_INTEGER;
+ var->var.ival = 0x30 + intf;
+ break;
+ case ATMF_SYSID:
+ var->type = ASN_OCTET;
+ var->var.sval[0] = 6;
+ UM_COPY ( (caddr_t)&Cfg[intf].acp_macaddr,
+ (caddr_t)&var->var.sval[1], 6 );
+ break;
+ default:
+ /* NO_SUCH */
+ break;
+ }
+ var = var->next;
+ }
+ build_pdu ( hdr, PDU_TYPE_GETRESP );
+ send_resp ( intf, hdr, Resp_Buf );
+
+}
+
+/*
+ * ILMI State Processing Loop
+ *
+ *
+ */
+void
+ilmi_do_state ()
+{
+ struct timeval tvp;
+ fd_set rfd;
+ u_char buf[1024];
+ Variable *var;
+ int intf;
+ int maxfd = 0;
+
+ /*
+ * Loop forever
+ */
+ for ( ; ; ) {
+ int count;
+ int n;
+ caddr_t bpp;
+ Snmp_Header *Hdr;
+
+ /*
+ * SunOS CC doesn't allow automatic aggregate initialization.
+ * Initialize to zero which effects a poll operation.
+ */
+ tvp.tv_sec = 15;
+ tvp.tv_usec = 0;
+
+ /*
+ * Clear fd_set and initialize to check this interface
+ */
+ FD_ZERO ( &rfd );
+ for ( intf = 0; intf < MAX_UNITS; intf++ )
+ if ( ilmi_fd[intf] > 0 ) {
+ FD_SET ( ilmi_fd[intf], &rfd );
+ maxfd = MAX ( maxfd, ilmi_fd[intf] );
+ }
+
+ /*
+ * Check for new interfaces
+ */
+ ilmi_open();
+
+ for ( intf = 0; intf < MAX_UNITS; intf++ ) {
+ /*
+ * Do any pre-message state processing
+ */
+ switch ( ilmi_state[intf] ) {
+ case ILMI_COLDSTART:
+ /*
+ * Clear addressTable
+ */
+ UM_ZERO ( (caddr_t)&addressEntry[intf], sizeof(Objid) );
+
+ /*
+ * Start by sending a COLD_START trap. This should cause the
+ * remote end to clear the associated prefix/address table(s).
+ */
+ /* Build ColdStart TRAP header */
+ ColdStart_Header = build_cold_start();
+ build_pdu ( ColdStart_Header, PDU_TYPE_TRAP );
+ send_resp ( intf, ColdStart_Header, Resp_Buf );
+
+ /*
+ * Start a timeout so that if the next state fails, we re-enter
+ * ILMI_COLDSTART.
+ */
+ /* atm_timeout() */
+
+ /* Enter new state */
+ ilmi_state[intf] = ILMI_INIT;
+ /* fall into ILMI_INIT */
+
+ case ILMI_INIT:
+ /*
+ * After a COLD_START, we need to check that the remote end has
+ * cleared any tables. Send a GET_NEXT request to check for this.
+ * In the event that the table is not empty, or that no reply is
+ * received, return to COLD_START state.
+ */
+ PDU_Header = build_generic_header();
+ PDU_Header->head = (Variable *)UM_ALLOC(sizeof(Variable));
+ var = PDU_Header->head;
+ UM_COPY ( (caddr_t)&Objids[ADDRESS_OBJID], (caddr_t)&var->oid,
+ sizeof(Objid) );
+ var->type = ASN_NULL;
+ var->next = NULL;
+
+ /*
+ * Send GETNEXT request looking for empty ATM Address Table
+ */
+ PDU_Header->reqid = Req_ID++;
+ build_pdu ( PDU_Header, PDU_TYPE_GETNEXT );
+ send_resp ( intf, PDU_Header, Resp_Buf );
+
+ /*
+ * Start a timeout while looking for SET message. If we don't receive
+ * a SET, then go back to COLD_START state.
+ */
+ /* atm_timeout() */
+ break;
+
+ case ILMI_RUNNING:
+ /* Normal SNMP processing */
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ count = select ( maxfd + 1, &rfd, NULL, NULL, &tvp );
+
+ for ( intf = 0; intf < MAX_UNITS; intf++ ) {
+ /*
+ * Check for received messages
+ */
+ if ( ilmi_fd[intf] > 0 && FD_ISSET ( ilmi_fd[intf], & rfd ) ) {
+
+ n = read ( ilmi_fd[intf], (caddr_t)&buf[1], sizeof(buf) - 1 );
+ if ( n == -1 && ( errno == ECONNRESET || errno == EBADF ) ) {
+ ilmi_state[intf] = ILMI_COLDSTART;
+ close ( ilmi_fd[intf] );
+ ilmi_fd[intf] = -1;
+ } else {
+ if ( Log && Debug_Level > 1 ) fprintf ( Log, "***** state %d ***** read %d bytes from %d (%d) ***** %s *****\n",
+ ilmi_state[intf], n, intf, ilmi_fd[intf], PDU_Types[buf[14] - 0xA0] ); {
+ if ( Debug_Level > 2 )
+ hexdump ( (caddr_t)&buf[1], n );
+ }
+ bpp = (caddr_t)&buf[1];
+ if ( ( Hdr = asn_get_header ( &bpp ) ) == NULL )
+ continue;
+
+ /* What we do with this messages depends upon the state we're in */
+ switch ( ilmi_state[intf] ) {
+ case ILMI_COLDSTART:
+ /* We should never be in this state here */
+ free_pdu ( Hdr );
+ break;
+ case ILMI_INIT:
+ /* The only messages we care about are GETNEXTs, GETRESPs, and TRAPs */
+ switch ( Hdr->pdutype ) {
+ case PDU_TYPE_GETNEXT:
+ /*
+ * Should be because the remote side is attempting
+ * to verify that our table is empty
+ */
+ if ( oid_ncmp ( (caddr_t)&Hdr->head->oid,
+ (caddr_t)&Objids[ADDRESS_OBJID],
+ Objids[ADDRESS_OBJID].oid[0] ) == 0 ) {
+ if ( addressEntry[intf].oid[0] ) {
+ /* XXX - FIXME */
+ /* Our table is not empty - return address */
+ }
+ }
+ build_pdu ( Hdr, PDU_TYPE_GETRESP );
+ send_resp ( intf, Hdr, Resp_Buf );
+ break;
+ case PDU_TYPE_GETRESP:
+ /*
+ * This should be in response to our GETNEXT.
+ * Check the OIDs and go onto ILMI_RUNNING if
+ * the address table is empty. We can cheat and
+ * not check sequence numbers because we only send
+ * the one GETNEXT request and ILMI says we shouldn't
+ * have interleaved sessions.
+ */
+ /*
+ * First look for empty table. If found, go to next state.
+ */
+ if ( oid_ncmp ( &Objids[ADDRESS_OBJID], &Hdr->head->oid,
+ Objids[ADDRESS_OBJID].oid[0] ) == 1 ) {
+ ilmi_state[intf] = ILMI_RUNNING; /* ILMI_REG; */
+ } else {
+ /*
+ * Check to see if this matches our address
+ * and if so, that it's a VALID entry.
+ */
+ Atm_addr *aa;
+ int l;
+ int match = 1;
+
+ aa = &Intf[intf].anp_addr;
+ if ( aa->address_length == Hdr->head->oid.oid[13] ) {
+ for ( l = 0; l < aa->address_length; l++ ) {
+ if ( (int)((u_char *)(aa->address))[l] !=
+ Hdr->head->oid.oid[14 + l] ) {
+ match = 0;
+ }
+ }
+ }
+ if ( match ) {
+ if ( Hdr->head->var.ival == 1 ) {
+ ilmi_state[intf] = ILMI_RUNNING;
+ }
+ }
+ }
+ free_pdu ( Hdr );
+ break;
+ case PDU_TYPE_SET:
+ /* Look for SET_PREFIX Objid */
+ if ( oid_ncmp ( (caddr_t)&Hdr->head->oid,
+ (caddr_t)&Objids[SETPFX_OBJID],
+ Objids[SETPFX_OBJID].oid[0] ) == 0 ) {
+ set_prefix ( &Hdr->head->oid, Hdr, intf );
+ /* Reply to SET before sending our ADDRESS */
+ build_pdu(Hdr, PDU_TYPE_GETRESP);
+ send_resp( intf, Hdr, Resp_Buf );
+ set_address ( Hdr, intf );
+ } else {
+ build_pdu(Hdr, PDU_TYPE_GETRESP);
+ send_resp( intf, Hdr, Resp_Buf );
+ }
+ break;
+ case PDU_TYPE_TRAP:
+ /* Remote side wants us to start fresh */
+ free_pdu ( Hdr );
+ break;
+ default:
+ /* Ignore */
+ free_pdu ( Hdr );
+ break;
+ }
+ break;
+ case ILMI_REG:
+ break;
+ case ILMI_RUNNING:
+ /* We'll take anything here */
+ switch ( Hdr->pdutype ) {
+ case PDU_TYPE_GET:
+ process_get ( Hdr, intf );
+ break;
+ case PDU_TYPE_GETRESP:
+ /* Ignore GETRESPs */
+ free_pdu ( Hdr );
+ break;
+ case PDU_TYPE_GETNEXT:
+ build_pdu ( Hdr, PDU_TYPE_GETRESP );
+ send_resp ( intf, Hdr, Resp_Buf );
+ break;
+ case PDU_TYPE_SET:
+ /* Look for SET_PREFIX Objid */
+ if ( oid_ncmp ( (caddr_t)&Hdr->head->oid,
+ (caddr_t)&Objids[SETPFX_OBJID],
+ Objids[SETPFX_OBJID].oid[0] ) == 0 ) {
+ set_prefix ( &Hdr->head->oid, Hdr, intf );
+ /* Reply to SET before sending our ADDRESS */
+ build_pdu(Hdr, PDU_TYPE_GETRESP);
+ send_resp( intf, Hdr, Resp_Buf );
+ set_address ( Hdr, intf );
+ } else {
+ build_pdu(Hdr, PDU_TYPE_GETRESP);
+ send_resp( intf, Hdr, Resp_Buf );
+ }
+ break;
+ case PDU_TYPE_TRAP:
+ free_pdu ( Hdr );
+ break;
+ }
+ break;
+ default:
+ /* Unknown state */
+ free_pdu ( Hdr );
+ break;
+ }
+ } /* if n > 0 */
+ } /* if received message */
+ } /* for each interface */
+ } /* for ever loop */
+
+}
+
+int
main ( argc, argv )
int argc;
char *argv[];
{
- u_char buf[256], set_buf[256];
- char community[1024];
- u_char *bufp;
- int s;
int c;
- int foregnd = 0; /* run in the foreground? */
- int pdulen;
- int version;
- int pdutype;
- int reqid;
- int error_status;
- int error_ptr;
- int b;
int i;
- int lerr = 0;
int Reset = 0; /* Should we send a coldStart and exit? */
- Snmp_Header *Hdr;
- int n;
/*
* What are we running as? (argv[0])
@@ -2248,34 +2460,10 @@ main ( argc, argv )
* If we're not doing debugging, run in the background
*/
if ( foregnd == 0 ) {
-#ifdef sun
- int pid, fd;
-
- if ( ( pid = fork() ) < 0 ) {
- fprintf ( stderr, "fork failed\n" );
- exit ( 1 );
- } else if (pid != 0) {
- /* Parent process - exit and allow child to run */
- exit ( 0 );
- }
- /* Child process */
- if ( ( lerr = setpgrp ( 0, getpid() ) ) < 0 ) {
- fprintf ( stderr, "Can't set process group" );
- exit ( 1 );
- }
- if ( ( fd = open ( "/dev/tty", O_RDWR ) ) >= 0 ) {
- ioctl ( fd, TIOCNOTTY, (char *)NULL );
- close ( fd );
- }
- /* close all open descriptors */
- for ( fd = 3; fd < getdtablesize(); fd++ )
- close ( fd );
-#else
if ( daemon ( 0, 0 ) )
err ( 1, "Can't fork" );
-#endif
} else
- setbuf ( stdout, NULL );
+ ; /* setbuf ( stdout, NULL ); */
signal ( SIGUSR1, Increment_DL );
signal ( SIGUSR2, Decrement_DL );
@@ -2283,11 +2471,16 @@ main ( argc, argv )
/*
* Open log file
*/
- if ( Debug_Level )
- if ( ( Log = fopen ( LOG_FILE, "a" ) ) == NULL )
- Log = NULL;
- else
- setbuf ( Log, NULL );
+ if ( Debug_Level ) {
+ if ( foregnd ) {
+ Log = stderr;
+ } else {
+ if ( ( Log = fopen ( LOG_FILE, "a" ) ) == NULL )
+ Log = NULL;
+ }
+ }
+ if ( Log )
+ setbuf ( Log, NULL );
/*
* Get our startup time
@@ -2296,12 +2489,13 @@ main ( argc, argv )
starttime.tv_sec--;
starttime.tv_usec += 1000000;
+ /* Randomize starting request ID */
+ Req_ID = starttime.tv_sec;
+
/*
* Reset all the interface descriptors
*/
for ( i = 0; i < MAX_UNITS; i++ ) {
- trap_fd[i] = -1;
- last_trap[i] = (time_t)0;
ilmi_fd[i] = -1;
}
/*
@@ -2314,497 +2508,23 @@ main ( argc, argv )
*/
if ( Reset ) {
for ( i = 0; i < MAX_UNITS; i++ )
- if ( trap_fd[i] >= 0 ) {
+ if ( ilmi_fd[i] >= 0 ) {
+ /* Build ColdStart TRAP header */
+ ColdStart_Header = build_cold_start();
+ build_pdu ( ColdStart_Header, PDU_TYPE_TRAP );
+ send_resp ( i, ColdStart_Header, Resp_Buf );
if ( Debug_Level > 1 && Log ) {
write_timestamp();
- fprintf ( Log, "Close trap_fd[%d]: %d\n",
- i, trap_fd[i] );
+ fprintf ( Log, "Close ilmi_fd[%d]: %d\n",
+ i, ilmi_fd[i] );
}
- close ( trap_fd[i] );
+ close ( ilmi_fd[i] );
}
exit ( 2 );
}
- /*
- * For ever...
- */
- for ( ; ; ) {
- int maxfd = 0;
- int count;
- struct timeval tvp;
- fd_set rfd;
- time_t curtime;
-
- ilmi_open();
-
- /*
- * SunOS CC doesn't allow automatic aggregate initialization.
- * Make everybody happy and do it here...
- */
- tvp.tv_sec = 15;
- tvp.tv_usec = 0;
-
- curtime = time ( (time_t *)NULL );
-
- /*
- * Check for TRAP messages
- */
- FD_ZERO ( &rfd );
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log, "Check Traps: " );
- }
- for ( i = 0; i < MAX_UNITS; i++ ) {
- if ( Debug_Level > 1 && Log )
- fprintf ( Log, "trap_fd[%d]: %d ", i, trap_fd[i] );
- if ( trap_fd[i] != -1 ) {
- /*
- * If we haven't sent a coldStart trap recently,
- * send one now
- */
- if ( last_trap[i] + TRAP_TIME < curtime ) {
- last_trap[i] = curtime;
- /*
- * Send coldStart TRAP
- */
- if ( Debug_Level > 4 && Log ) {
- write_timestamp();
- fprintf ( Log, "===== Sent %d bytes =====\n",
- coldStart_Trap[0] );
- hexdump ( (u_char *)&coldStart_Trap[1],
- coldStart_Trap[0] );
- }
- if ( Debug_Level && Log ) {
- write_timestamp();
- fprintf ( Log,
- "\tSend coldStart TRAP to unit %d\n", i );
- }
- write ( trap_fd[i], (caddr_t)&coldStart_Trap[1],
- coldStart_Trap[0] );
- }
- if ( (trap_fd[i] >= 0) &&
- FD_SET ( trap_fd[i], &rfd )) {
- maxfd = MAX ( maxfd, trap_fd[i] );
- }
- }
- }
- if ( Debug_Level > 1 && Log )
- fprintf ( Log, "maxfd: %d\n", maxfd );
-
- if ( maxfd ) {
- count = select ( maxfd + 1, &rfd, NULL, NULL, &tvp );
-
- if ( count > 0 ) {
- for ( i = 0; i < MAX_UNITS; i++ ) {
- if ( trap_fd[i] >= 0 && FD_ISSET ( trap_fd[i], &rfd ) ) {
- s = trap_fd[i];
-
- n = read ( s, (caddr_t)&buf[1], sizeof(buf) - 1 );
- if ( n == -1 && ( errno == ECONNRESET ||
- errno == EBADF ) ) {
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log,
- "Bad read: close trap_fd[%d]: %d\n",
- i, trap_fd[i] );
- }
- close ( trap_fd[i] );
- trap_fd[i] = -1;
- ilmi_fd[i] = -1;
- }
- if ( n ) {
- buf[0] = n;
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log, "***** Read %d bytes *****\n",
- n );
- hexdump ( (caddr_t)&buf[1], n );
- }
- bufp = buf;
- /*
- * Skip length byte
- */
- bufp++;
- /*
- * Crack the header
- */
- if ( ( Hdr = asn_get_header ( &bufp ) ) == NULL )
- continue;
- pdutype = Hdr->pdutype;
- /*
- * Only interested in TRAP messages
- */
- switch ( pdutype ) {
- /*
- * FORE switches often go straight to SET prefix
- * after receiving a coldStart TRAP from us
- */
- case PDU_TYPE_SET:
- /*
- * Make a copy of this PDU so that a
- * SET NSAP prefix can reply to it.
- */
- UM_COPY ( buf, set_buf, sizeof(buf) );
-
- lerr = process_set ( &bufp );
- /*
- * Can't do a simple oid_cmp since we
- * don't yet know what the prefix is.
- * If it looks like a SET netPrefix.0,
- * then compare the portion leading up
- * to the NSAP prefix part.
- */
- if ( oid.oid[0] == 26 ) {
- oid.oid[0] = 12;
- if ( oid_cmp ( &setprefix, &oid ) == 0 ) {
- oid.oid[0] = 26;
- set_prefix ( &oid, Hdr, set_buf, s );
- }
- }
- /*
- * We now move from awaiting TRAP to processing ILMI
- */
- ilmi_fd[i] = trap_fd[i];
- trap_fd[i] = -1;
- break;
- case PDU_TYPE_TRAP:
- lerr = process_trap ( &bufp, trap_fd[i] );
- /*
- * We now move from awaiting TRAP to processing ILMI
- */
- ilmi_fd[i] = trap_fd[i];
- trap_fd[i] = -1;
- break;
- }
- } /* if n */
- } /* if FD_ISSET */
- } /* for i */
- } /* if count */
- }
-
- /*
- * Reset from TRAP checking
- */
- maxfd = 0;
- errno = 0;
- /*
- * Check for ILMI messages
- */
- FD_ZERO ( &rfd );
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log, "Check Ilmis: " );
- }
- for ( i = 0; i < MAX_UNITS; i++ ) {
- if ( Debug_Level > 1 && Log )
- fprintf ( Log, "ilmi_fd[%d]: %d ", i, ilmi_fd[i] );
- if ( ilmi_fd[i] != -1 ) {
- if ( (ilmi_fd[i] >= 0) &&
- FD_SET ( ilmi_fd[i], &rfd )) {
- maxfd = MAX ( maxfd, ilmi_fd[i] );
- }
- }
- }
- if ( Debug_Level > 1 && Log )
- fprintf ( Log, "maxfd: %d\n", maxfd );
-
- if ( maxfd ) {
- count = select ( maxfd + 1, &rfd, NULL, NULL, &tvp );
-
- if ( count > 0 ) {
- for ( i = 0; i < MAX_UNITS; i++ ) {
- if ( ilmi_fd[i] >= 0 && FD_ISSET ( ilmi_fd[i], &rfd ) ) {
-
- s = ilmi_fd[i];
-
- n = read ( s, (caddr_t)&buf[1], sizeof(buf) - 1 );
- if ( n == -1 && ( errno == ECONNRESET ||
- errno == EBADF ) ) {
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log,
- "Bad read: close ilmi_fd[%d]: %d\n",
- i, ilmi_fd[i] );
- }
- close ( ilmi_fd[i] );
- trap_fd[i] = -1;
- ilmi_fd[i] = -1;
- }
- if ( n ) {
- buf[0] = n;
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log,
- "***** Read %d bytes *****\n",
- n );
- hexdump ( (caddr_t)&buf[1], n );
- }
- bufp = buf;
- /*
- * Skip length byte
- */
- bufp++;
- /*
- * Crack the header
- */
- if ( ( Hdr = asn_get_header ( &bufp ) )
- == NULL )
- continue;
- pdutype = Hdr->pdutype;
-
- /*
- * Do the operation...
- */
- switch ( pdutype ) {
-
- case PDU_TYPE_GET:
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log, "GET:: " );
- }
- /*
- * Should be SEQUENCE OF
- */
- if ( *bufp++ != ASN_SEQUENCE ) {
- lerr = 1;
- break;
- }
- pdulen = asn_get_pdu_len ( &bufp );
- /*
- * Should be SEQUENCE OF
- */
- if ( *bufp++ != ASN_SEQUENCE ) {
- lerr = 1;
- break;
- }
- pdulen = asn_get_pdu_len ( &bufp );
- /*
- * Should be OBJID
- */
- if ( *bufp++ != ASN_OBJID ) {
- lerr = 1;
- break;
- }
- asn_get_objid ( &bufp, &oid );
- /*
- * Ended with a NULL
- */
- bufp++;
- bufp++;
- /*
- * If GET sysObjId.0
- */
- if (oid_cmp(&sysObjId, &oid) == 0 ) {
- send_resp ( s, Hdr->reqid,
- sysObjId_Resp );
-
- } else
- /*
- * If GET sysUpTime.0
- */
- if (oid_cmp(&sysUpTime, &oid) == 0 ) {
- send_uptime_resp ( s,
- Hdr->reqid );
- } else
- /*
- * If GET myIpNm.0
- */
- if ( oid_cmp ( &myipnm, &oid ) == 0 ) {
- send_myipnm ( s, Hdr );
- } else
- /*
- * If GET uniType.0
- */
- if ( oid_cmp ( &unitype, &oid ) == 0 ) {
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log,
- "\tSend uniType\n" );
- }
- send_resp ( s, Hdr->reqid,
- UniType_Resp );
- } else
- /*
- * If GET uniVer.0
- */
- if ( oid_cmp ( &univer, &oid ) == 0 ) {
- int p = UniVer_Resp[0];
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log,
- "\tSend uniVer\n" );
- }
- switch (Intf[i].anp_sig_proto) {
- case ATM_SIG_UNI30:
- UniVer_Resp[p] =
- UNIVER_UNI30;
- break;
- case ATM_SIG_UNI31:
- UniVer_Resp[p] =
- UNIVER_UNI31;
- break;
- case ATM_SIG_UNI40:
- UniVer_Resp[p] =
- UNIVER_UNI40;
- break;
- }
- send_resp ( s, Hdr->reqid,
- UniVer_Resp );
- } else
- /*
- * If GET devType.0
- */
- if ( oid_cmp ( &devtype, &oid ) == 0 ) {
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log,
- "\tSend devType\n" );
- }
- send_resp ( s, Hdr->reqid,
- DevType_Resp );
- } else
- /*
- * If GET foreSigGrp....0
- */
- if (oid_cmp(&foresiggrp, &oid) == 0) {
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log,
- "\tSend noSuchVar\n" );
- }
- send_resp ( s, Hdr->reqid,
- NoSuchFore_Resp );
- } else
- if ( oid_cmp(&layeridx, &oid) == 0 ) {
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log,
- "\t*** LayerIndex\n" );
- }
- } else
- if ( oid_cmp(&maxvcc, &oid) == 0 ) {
- send_resp ( s, Hdr->reqid,
- maxVCC_Resp );
- } else
- if ( oid_cmp ( &portidx, &oid ) == 0 ) {
- int p = PortIndex_Resp[0];
- PortIndex_Resp[p] = i + 1;
- send_resp ( s, Hdr->reqid,
- PortIndex_Resp );
- } else
- send_no_such ( s, Hdr, &oid );
- break;
-
- case PDU_TYPE_GETNEXT:
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log, "GET_NEXT:: " );
- }
- /*
- * Should be SEQUENCE OF
- */
- if ( *bufp++ != ASN_SEQUENCE ) {
- lerr = 1;
- break;
- }
- pdulen = asn_get_pdu_len ( &bufp );
- /*
- * Should be SEQUENCE OF
- */
- if ( *bufp++ != ASN_SEQUENCE ) {
- lerr = 1;
- break;
- }
- pdulen = asn_get_pdu_len ( &bufp );
- /*
- * Should be OBJID
- */
- if ( *bufp++ != ASN_OBJID ) {
- lerr = 1;
- break;
- }
- asn_get_objid ( &bufp, &oid );
- /*
- * Ended with a NULL
- */
- bufp++;
- bufp++;
- /*
- * If this is a GET_NEXT netPrefix then
- * the other side probably restarted
- * and is looking for a table empty
- * indication before restarting the
- * ILMI protocol.
- */
- if ( oid_cmp(&netpfx_oid, &oid) == 0 ) {
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log,
- "\tSend GET_RESP:\n" );
- }
- send_resp ( s, Hdr->reqid,
- GetNext_Resp );
- }
- break;
-
- case PDU_TYPE_GETRESP:
- if ( Debug_Level > 1 && Log ) {
- write_timestamp();
- fprintf ( Log,
- "GET_RESP:: \n" );
- }
- /*
- * Ignore any responses to our GETs.
- * (We don't send any GETs.)
- */
- break;
-
- case PDU_TYPE_SET:
- /*
- * Make a copy of this PDU so that a
- * SET NSAP prefix can reply to it.
- */
- UM_COPY ( buf, set_buf, sizeof(buf) );
-
- if ( process_set ( &bufp ) < 0 )
- break;
-
- /*
- * Can't do a simple oid_cmp since we
- * don't know what the prefix is yet.
- * If it looks like a SET netPrefix.0,
- * then compare the portion leading up
- * to the NSAP prefix part.
- */
- if ( oid.oid[0] == 26 ) {
- oid.oid[0] = 12;
- if ( oid_cmp(&setprefix,&oid)
- == 0 ) {
- oid.oid[0] = 26;
- set_prefix ( &oid, Hdr,
- set_buf, s );
- }
- }
- break;
-
- case PDU_TYPE_TRAP:
- lerr = process_trap ( &bufp, s );
- break;
- }
- /*
- * Forget about this PDU
- */
- free ( Hdr );
- Hdr = NULL;
+ ilmi_do_state();
- } /* end of read(s) */
- } /* end if FD_ISSET(s) */
- } /* end of for ( i... */
- } /* end of if ( count ) */
- } else {
- sleep ( SLEEP_TIME );
- }
- } /* end of for ever */
-
+ exit(0);
}
OpenPOWER on IntegriCloud