summaryrefslogtreecommitdiff
path: root/sbin/atm/ilmid/ilmid.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/atm/ilmid/ilmid.c')
-rw-r--r--sbin/atm/ilmid/ilmid.c2830
1 files changed, 1555 insertions, 1275 deletions
diff --git a/sbin/atm/ilmid/ilmid.c b/sbin/atm/ilmid/ilmid.c
index 9da24241f726..e515a1088f99 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.1 1998/09/15 08:22:47 phk Exp $
+ * @(#) $Id: ilmid.c,v 1.9 1998/08/13 20:15:28 jpt Exp $
*
*/
@@ -45,24 +45,40 @@
*
*/
-#include <sys/param.h>
-
#ifndef lint
-__RCSID("@(#) $Id: ilmid.c,v 1.1 1998/09/15 08:22:47 phk Exp $");
+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>
-#include <errno.h>
+#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 <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>
@@ -70,30 +86,36 @@ __RCSID("@(#) $Id: ilmid.c,v 1.1 1998/09/15 08:22:47 phk 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 <libatm.h>
+#include <netatm/uni/unisig_var.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
*/
@@ -103,167 +125,360 @@ static char *Var_Types[] = { "", "", "ASN_INTEGER", "", "ASN_OCTET", "ASN_NULL",
#define PDU_TYPE_SET 0xA3
#define PDU_TYPE_TRAP 0xA4
-static char *PDU_Types[] = { "GET REQUEST", "GETNEXT REQUEST", "GET RESPONSE", "SET REQUEST",
- "TRAP" };
-
/*
- * Define TRAP codes
+ * 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.
*/
-#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
+struct snmp_header {
+ int pdulen;
+ int version;
+ char community[64];
+ int pdutype;
+ int reqid;
+ int error;
+ int erridx;
+};
+typedef struct snmp_header Snmp_Header;
/*
- * Define SNMP Version numbers
+ * Define our internal representation of an OBJECT IDENTIFIER
*/
-#define SNMP_VERSION_1 1
-#define SNMP_VERSION_2 2
+struct objid {
+ int oid[128];
+};
+typedef struct objid Objid;
/*
- * Max string length for Variable
+ * 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...)
*/
-#define STRLEN 128
-
+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 };
/*
- * Unknown variable
+ * (Partialy) pre-encoded SNMP responses
*/
-#define VAR_UNKNOWN -1
/*
- * Define our internal representation of an OBJECT IDENTIFIER
+ * sysObjId reply
*/
-struct objid {
- int oid[128];
+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
};
-typedef struct objid Objid;
/*
- * Define a Veriable classso that we can handle multiple GET/SET's
- * per PDU.
+ * sysUpTime: reply to a sysUpTime GET request
*/
-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;
+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 */
};
/*
- * 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.
+ * coldStart TRAP to start the ILMI protocol
*/
-struct snmp_header {
- int pdulen;
- int version;
- char community[64];
- int pdutype;
+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 */
+};
- /* 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;
+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 */
};
-typedef struct snmp_header Snmp_Header;
-Snmp_Header *ColdStart_Header;
-Snmp_Header *PDU_Header;
+/*
+ * Reply to GET myIpNm
+ */
+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 */
+};
/*
- * 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...)
+ * Reply to GET portIndex - we're always 1 + unit number
*/
-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 }},
+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 */
};
-#define NUM_OIDS (sizeof(Objids)/sizeof(Objid))
+/*
+ * 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 */
+};
+
+/*
+ * Reply to GET uniType - we only support PRIVATE
+ */
+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) */
+};
-#define UNIVER_UNI20 1
#define UNIVER_UNI30 2
#define UNIVER_UNI31 3
#define UNIVER_UNI40 4
-#define UNIVER_UNKNOWN 5
-#define UNITYPE_PUBLIC 1
-#define UNITYPE_PRIVATE 2
+/*
+ * 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 DEVTYPE_USER 1
-#define DEVTYPE_NODE 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) */
+};
/*
- * ILMI protocol states
+ * Reply to GET foreSigGroup.* with noSuchError
*/
-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 */
+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 */
};
/*
* Our (incrementing) Request ID
*/
-int Req_ID;
+int Req_ID = 0;
/*
* Temporary buffer for building response packets. Should help ensure
@@ -287,15 +502,18 @@ char *Traps[] = { "coldStart", "warmStart", "linkDown", "linkUp",
int NUnits;
-
/*
- * fd for units which have seen a coldStart TRAP and are now exchaning SNMP requests
+ * 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
*/
-int ilmi_fd[MAX_UNITS + 1];
+int trap_fd[MAX_UNITS];
/*
- * enum ilmi_states for this unit
+ * fd for units which have seen a coldStart TRAP and are now exchaning SNMP requests
*/
-int ilmi_state[MAX_UNITS + 1];
+int ilmi_fd[MAX_UNITS];
/*
* Local copy for HARP physical configuration information
*/
@@ -306,17 +524,11 @@ 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];
@@ -325,6 +537,14 @@ 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 ) );
@@ -354,11 +574,10 @@ write_timestamp()
clock = time ( (time_t)NULL );
tm = localtime ( &clock );
- 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 );
+ 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 );
return;
@@ -398,10 +617,8 @@ 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++ );
@@ -410,10 +627,8 @@ 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;
@@ -431,32 +646,24 @@ 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, plen )
- u_char **bufp;
- int *plen;
+asn_get_pdu_len ( bufp )
+ u_char **bufp;
{
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;
@@ -513,18 +720,15 @@ 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, plen )
- u_char **bufp;
- int *plen;
+asn_get_int ( bufp )
+ u_char **bufp;
{
int i;
int len;
@@ -532,69 +736,14 @@ asn_get_int ( bufp, plen )
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:
@@ -633,19 +782,16 @@ 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, plen )
- u_char **bufp;
- Objid *objid;
- int *plen;
+asn_get_objid ( bufp, objid )
+ u_char **bufp;
+ Objid *objid;
{
int len;
u_char *bp = *bufp;
@@ -653,53 +799,17 @@ asn_get_objid ( bufp, objid, plen )
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;
- 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 );
+ if ( Debug_Level > 1 )
+ print_objid ( objid );
+ return;
}
/*
@@ -711,19 +821,16 @@ asn_put_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, plen )
- u_char **bufp;
- char *octet;
- int *plen;
+asn_get_octet ( bufp, octet )
+ u_char **bufp;
+ char *octet;
{
u_char *bp = *bufp;
int i = 0;
@@ -733,13 +840,10 @@ asn_get_octet ( bufp, octet, plen )
* &i is really a dummy value here as we don't keep track
* of the ongoing buffer length
*/
- len = asn_get_encoded ( &bp, &i, plen );
+ len = asn_get_encoded ( &bp, &i );
- for ( i = 0; i < len; i++ ) {
+ for ( i = 0; i < len; i++ )
*octet++ = *bp++;
- if ( plen )
- (*plen)--;
- }
*bufp = bp;
@@ -761,133 +865,22 @@ 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 %s\n",
+ "Pdu len: %d Version: %d Community: \"%s\" Pdu Type: 0x%x\n",
Hdr->pdulen, Hdr->version + 1, Hdr->community,
- 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;
+ Hdr->pdutype );
}
+ 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.
@@ -908,8 +901,6 @@ asn_get_header ( bufp )
{
Snmp_Header *h;
u_char *bp = *bufp;
- int len = 0;
- int dummy = 0;
/*
* Allocate memory to hold the SNMP header
@@ -918,11 +909,6 @@ 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 */
@@ -931,7 +917,7 @@ asn_get_header ( bufp )
/*
* Get the length of remaining PDU data
*/
- h->pdulen = asn_get_pdu_len ( &bp, NULL );
+ h->pdulen = asn_get_pdu_len ( &bp );
/*
* We expect to find an integer encoding Version-1
@@ -939,7 +925,7 @@ asn_get_header ( bufp )
if ( *bp++ != ASN_INTEGER ) {
return ( (Snmp_Header *)NULL );
}
- h->version = asn_get_int ( &bp, NULL );
+ h->version = asn_get_int ( &bp );
/*
* After the version, we need the community name
@@ -947,7 +933,8 @@ asn_get_header ( bufp )
if ( *bp++ != ASN_OCTET ) {
return ( (Snmp_Header *)NULL );
}
- asn_get_octet ( &bp, h->community, NULL );
+ UM_ZERO ( h->community, sizeof ( h->community ) );
+ asn_get_octet ( &bp, h->community );
/*
* Single byte PDU type
@@ -959,43 +946,31 @@ asn_get_header ( bufp )
*/
if ( h->pdutype != PDU_TYPE_TRAP ) { /* TRAP uses different format */
- (void) asn_get_pdu_len ( &bp, &dummy );
+ bp++; /* Skip over data len */
/* Request ID */
if ( *bp++ != ASN_INTEGER ) {
- UM_FREE ( h );
return ( (Snmp_Header *)NULL );
}
- h->reqid = asn_get_int ( &bp, NULL );
+ h->reqid = asn_get_int ( &bp );
/* Error Status */
if ( *bp++ != ASN_INTEGER ) {
- UM_FREE ( h );
return ( (Snmp_Header *)NULL );
}
- h->error = asn_get_int ( &bp, NULL );
+ h->error = asn_get_int ( &bp );
/* 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->varlen = ( asn_get_pdu_len ( &bp, &len ) - 1 );
- h->varlen += ( len - 1 );
+ h->erridx = asn_get_int ( &bp );
- parse_oids ( h, &bp );
}
*bufp = bp;
- if ( Log && Debug_Level )
+ if ( Debug_Level > 2 )
print_header ( h );
return ( h );
@@ -1003,7 +978,7 @@ asn_get_header ( bufp )
}
/*
- * Compare two internal OID representations
+ * Compare to internal OID representations
*
* Arguments:
* oid1 - Internal Object Identifier
@@ -1019,54 +994,18 @@ 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 <= len; i++ ) {
- if ( !(oid1->oid[i] == oid2->oid[i]) )
- /* values don't match */
- return ( 1 );
- }
-
- /* Objid's are identical */
- return ( 0 );
-}
-
-/*
- * Compare two internal OID representations
- *
- * Arguments:
- * oid1 - Internal Object Identifier
- * oid2 - Internal Object Identifier
- * len - Length of OID to compare
- *
- * 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++ ) {
+ for ( i = 1; i <= oid1->oid[0]; i++ ) {
if ( !(oid1->oid[i] == oid2->oid[i]) )
/* values don't match */
return ( 1 );
@@ -1077,50 +1016,35 @@ oid_ncmp ( oid1, oid2, len )
}
/*
- * Find the index of a OBJID which matches this Variable instance
- *
- * Arguments:
- * var - pointer to Variable instance
- *
- * Returns:
- * idx - index of matched Variable instance
- * -1 - no matching Variable found
+ * Encode a timeval as the number of time ticks
*
- */
-int
-find_var ( var )
- Variable *var;
-{
- 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
+ * 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').
*
* Arguments:
- * none
+ * bufp - pointer to buffer pointer
*
* Returns:
- * number of ticks
+ * bufp - updated buffper pointer
+ * len - number of bytes to encode time ticks value
+ * - ticks since 'starttime' encoded in buffer
*
*/
int
-get_ticks()
+asn_encode_ticks ( bufp, ret )
+ u_char **bufp;
+ int *ret;
{
- struct timeval timenow;
- struct timeval timediff;
+ struct timeval timenow;
+ struct timeval timediff;
+ u_char *bp = *bufp;
+ int len, ticks;
(void) gettimeofday ( &timenow, NULL );
/*
- * Adjust for subtraction
+ * Adjust for subtraction
*/
timenow.tv_sec--;
timenow.tv_usec += 1000000;
@@ -1140,252 +1064,139 @@ get_ticks()
}
/*
- * Compute number of ticks
+ * Compute 100th's of second in diff time structure
*/
- return ( ( timediff.tv_sec * 100 ) + ( timediff.tv_usec / 10000 ) );
+ *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;
+ *bufp = bp;
+ return ( len + 2 );
}
/*
- * Build a response PDU
+ * Send back up sysUpTime response
*
* Arguments:
- * hdr - pointer to PDU Header with completed Variable list
- *
+ * sd - socket descriptor to send reply on
+ * reqid - original GET request id
+ *
* Returns:
- * none
+ * none - response sent
*
*/
void
-build_pdu ( hdr, type )
- Snmp_Header *hdr;
- int type;
+send_uptime_resp ( sd, reqid )
+ int sd;
+ int reqid;
{
- 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;
- }
- }
-
- /* 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 );
+ int len;
+ short *sp;
+ u_long *ip;
+ u_char *bp;
+ short val;
+ int ticks;
- /* Continue with variable processing */
- }
+ COPY_RESP ( sysUpTime_Resp );
- /* 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 );
+ bp = (u_char *)&Resp_Buf[Resp_Buf[0]+1];
+ len = asn_encode_ticks ( &bp, &ticks );
- 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;
- }
- }
+ /*
+ * Adjust overall length
+ */
+ bp = (u_char *)&Resp_Buf[0];
+ *bp += len;
- /* Accumulate total Variable sequence length */
- varlen += (len + 4);
+ /*
+ * 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 */
- /* Fill in length of this sequence */
- bpp[1] = len & 0xff;
- bpp[0] = len >> 8;
+ /*
+ * 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
- var = var->next;
+ if ( Debug_Level > 1 && Log ) {
+ write_timestamp();
+ fprintf ( Log, "\tSend sysUpTime: %d\n", ticks );
}
-
- /* 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 */
+ 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 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;
+ /*
+ * Send response
+ */
+ write ( sd, (caddr_t)&Resp_Buf[1], Resp_Buf[0] );
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 */
}
/*
@@ -1410,7 +1221,11 @@ 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
@@ -1418,6 +1233,7 @@ set_reqid ( resp, reqid )
UM_COPY ( (caddr_t)&u.c[4-resp[17]], bp, resp[17] );
return;
+
}
/*
@@ -1433,77 +1249,24 @@ set_reqid ( resp, reqid )
*
*/
void
-send_resp ( intf, Hdr, resp )
- int intf;
- Snmp_Header *Hdr;
+send_resp ( sd, reqid, resp )
+ int sd;
+ int reqid;
u_char *resp;
{
- int n;
- if ( ilmi_fd[intf] > 0 ) {
- n = write ( ilmi_fd[intf], (caddr_t)&resp[1], resp[0] );
- if ( Log && Debug_Level > 1 ) {
+ set_reqid ( resp, reqid );
+
+ if ( Debug_Level > 1 && Log ) {
write_timestamp();
- 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] );
- }
+ fprintf ( Log, "===== Sent %d bytes =====\n", resp[0] );
+ 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
*
@@ -1522,7 +1285,7 @@ void
init_ilmi()
{
struct air_cfg_rsp *cfg_info = NULL;
- struct air_int_rsp *intf_info = NULL;
+ struct air_intf_rsp *intf_info = NULL;
int buf_len;
/*
@@ -1536,6 +1299,10 @@ 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;
}
@@ -1547,8 +1314,12 @@ 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 */
- UM_FREE ( cfg_info );
+ free ( cfg_info );
cfg_info = NULL;
/*
* Get the per interface information
@@ -1567,7 +1338,7 @@ init_ilmi()
*/
UM_COPY ( intf_info, (caddr_t)Intf, buf_len );
/* Housecleaning */
- UM_FREE ( intf_info );
+ free ( intf_info );
intf_info = NULL;
return;
@@ -1599,15 +1370,28 @@ 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
*/
@@ -1616,11 +1400,16 @@ ilmi_open ()
sig_proto != ATM_SIG_UNI40 )
continue;
- if ( ilmi_fd[unit] == -1 ) {
+ /*
+ * 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 ) {
- ilmi_fd[unit] = socket ( AF_ATM, SOCK_SEQPACKET, ATM_PROTO_AAL5 );
+ trap_fd[unit] = socket ( AF_ATM, SOCK_SEQPACKET, ATM_PROTO_AAL5 );
- if ( ilmi_fd[unit] < 0 ) {
+ if ( trap_fd[unit] < 0 ) {
perror ( "open" );
continue;
}
@@ -1633,13 +1422,14 @@ ilmi_open ()
write_timestamp();
fprintf ( Log, "No nif on unit %d\n", unit );
}
- close ( ilmi_fd[unit] );
+ close ( trap_fd[unit] );
+ trap_fd[unit] = -1;
ilmi_fd[unit] = -1;
continue;
}
- sprintf ( nifname, "%s0", Intf[unit].anp_nif_pref );
+ sprintf ( nifname, "%s0\0", Intf[unit].anp_nif_pref );
optlen = sizeof ( nifname );
- if ( setsockopt ( ilmi_fd[unit], T_ATM_SIGNALING,
+ if ( setsockopt ( trap_fd[unit], T_ATM_SIGNALING,
T_ATM_NET_INTF, (caddr_t)nifname, optlen ) < 0 ) {
perror ( "setsockopt" );
if ( Log ) {
@@ -1652,8 +1442,9 @@ ilmi_open ()
write_timestamp();
fprintf ( Log, "nifname: closing unit %d\n", unit );
}
- close ( ilmi_fd[unit] );
- ilmi_fd[unit] = -1;
+ close ( trap_fd[unit] );
+ trap_fd[unit] = -1;
+ ilmi_fd[unit] = -1;
continue;
}
@@ -1662,9 +1453,9 @@ ilmi_open ()
*/
UM_ZERO ( (caddr_t) &satm, sizeof(satm) );
satm.satm_family = AF_ATM;
-#if (defined(BSD) && (BSD >= 199103))
+#ifndef sun
satm.satm_len = sizeof(satm);
-#endif
+#endif /* sun */
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;
@@ -1690,14 +1481,15 @@ ilmi_open ()
aal5.backward_max_SDU_size = MAX_LEN;
aal5.SSCS_type = T_ATM_NULL;
optlen = sizeof(aal5);
- if ( setsockopt ( ilmi_fd[unit], T_ATM_SIGNALING, T_ATM_AAL5,
+ if ( setsockopt ( trap_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 ( ilmi_fd[unit] );
+ close ( trap_fd[unit] );
+ trap_fd[unit] = -1;
ilmi_fd[unit] = -1;
continue;
}
@@ -1718,7 +1510,7 @@ ilmi_open ()
traffic.backward.tagging = T_NO;
traffic.best_effort = T_YES;
optlen = sizeof(traffic);
- if (setsockopt(ilmi_fd[unit], T_ATM_SIGNALING, T_ATM_TRAFFIC,
+ if (setsockopt(trap_fd[unit], T_ATM_SIGNALING, T_ATM_TRAFFIC,
(caddr_t)&traffic, optlen) < 0) {
perror("setsockopt(traffic)");
}
@@ -1728,7 +1520,7 @@ ilmi_open ()
bearer.clipping_susceptibility = T_NO;
bearer.connection_configuration = T_ATM_1_TO_1;
optlen = sizeof(bearer);
- if (setsockopt(ilmi_fd[unit], T_ATM_SIGNALING, T_ATM_BEARER_CAP,
+ if (setsockopt(trap_fd[unit], T_ATM_SIGNALING, T_ATM_BEARER_CAP,
(caddr_t)&bearer, optlen) < 0) {
perror("setsockopt(bearer)");
}
@@ -1737,7 +1529,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(ilmi_fd[unit], T_ATM_SIGNALING, T_ATM_QOS, (caddr_t)&qos,
+ if (setsockopt(trap_fd[unit], T_ATM_SIGNALING, T_ATM_QOS, (caddr_t)&qos,
optlen) < 0) {
perror("setsockopt(qos)");
}
@@ -1745,14 +1537,14 @@ ilmi_open ()
subaddr.address_format = T_ATM_ABSENT;
subaddr.address_length = 0;
optlen = sizeof(subaddr);
- if (setsockopt(ilmi_fd[unit], T_ATM_SIGNALING, T_ATM_DEST_SUB,
+ if (setsockopt(trap_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(ilmi_fd[unit], T_ATM_SIGNALING, T_ATM_APP_NAME,
+ if (setsockopt(trap_fd[unit], T_ATM_SIGNALING, T_ATM_APP_NAME,
(caddr_t)&appname, optlen) < 0) {
perror("setsockopt(appname)");
}
@@ -1760,14 +1552,15 @@ ilmi_open ()
/*
* Now try to connect to destination
*/
- if ( connect ( ilmi_fd[unit], (struct sockaddr *) &satm,
+ if ( connect ( trap_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 ( ilmi_fd[unit] );
+ close ( trap_fd[unit] );
+ trap_fd[unit] = -1;
ilmi_fd[unit] = -1;
continue;
}
@@ -1776,44 +1569,61 @@ ilmi_open ()
write_timestamp();
fprintf ( Log, "***** opened unit %d\n", unit );
}
-
- ilmi_state[unit] = ILMI_COLDSTART;
-
+ /*
+ * 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] );
}
}
+ signal ( SIGALRM, ilmi_open );
+ alarm ( SLEEP_TIME );
+
return;
}
/*
- * Get our local IP address for this interface
+ * Send our local IP address for this interface
*
* Arguments:
- * s - socket to find address for
- * aval - pointer to variable to store address in
+ * s - socket to send message on
+ * hdr - pointer to internal SNMP header
*
* Returns:
* none
*
*/
void
-get_local_ip ( s, aval )
- int s;
- long *aval;
+send_myipnm ( s, hdr )
+ int s;
+ Snmp_Header *hdr;
{
- 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;
- /*
- * Get physical interface name
- */
+ COPY_RESP ( MyIpNm_Resp );
+
if ( getsockopt ( s, T_ATM_SIGNALING, T_ATM_NET_INTF,
- (caddr_t) intf_name, &namelen ) )
- return;
+ (caddr_t) intf_name, &namelen ) ) {
+ perror ( "Couldn't get socket name" );
+ return;
+ }
/*
* Get network interface information for this physical interface
@@ -1825,14 +1635,23 @@ get_local_ip ( s, aval )
sin = (struct sockaddr_in *)&net_info->anp_proto_addr;
/*
- * Fill in answer
+ * Copy interface's IP address into reply packet
*/
- UM_COPY ( (caddr_t)&sin->sin_addr.s_addr, aval, 4 );
+ 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_FREE ( net_info );
+ send_resp ( s, hdr->reqid, Resp_Buf );
+ /*
+ * Clean up
+ */
+ free ( net_info );
return;
-
}
/*
@@ -1853,29 +1672,40 @@ get_local_ip ( s, aval )
*
*/
void
-set_prefix ( oid, hdr, intf )
+set_prefix ( oid, hdr, buf, s )
Objid *oid;
Snmp_Header *hdr;
- int intf;
+ u_char *buf;
+ int s;
{
- struct atmsetreq asr;
- Atm_addr *aa;
- int fd;
- int i;
+ 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 );
/*
* Build IOCTL request to set prefix
*/
asr.asr_opcode = AIOCS_SET_PRF;
- strncpy ( asr.asr_prf_intf, Intf[intf].anp_intf,
+ strncpy ( asr.asr_prf_intf, Intf[0].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
@@ -1888,10 +1718,9 @@ set_prefix ( oid, hdr, intf )
syslog ( LOG_ERR, "ilmid: error setting prefix: %m" );
if ( Log ) {
write_timestamp();
- fprintf ( Log, "errno %d setting prefix\n",
+ fprintf ( Log, "ilmid: errno %d setting prefix\n",
errno );
}
- close ( fd );
return;
}
}
@@ -1902,58 +1731,375 @@ set_prefix ( oid, hdr, intf )
*/
init_ilmi();
- aa = &Intf[intf].anp_addr;
+ aa = &Intf[0].anp_addr;
/*
- * Copy our NSAP into addressEntry table
+ * Finish building SET NSAP packet
*/
- addressEntry[intf].oid[0] = 0;
+ COPY_RESP ( NetPrefix_Resp );
+
+ len = Resp_Buf[0];
+ cpp = &Resp_Buf[len + 1]; /* Set to end of response buffer */
+ len++;
+ *cpp++ = aa->address_length;
for ( i = 0; i < aa->address_length; i++ ) {
- addressEntry[intf].oid[0]++; /* Increment length */
- addressEntry[intf].oid[i + 1] = (int)((u_char *)(aa->address))[i];
+ u_char c = ((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
-set_address ( hdr, intf )
- Snmp_Header *hdr;
- int intf;
+send_no_such ( s, Hdr, op )
+ int s;
+ Snmp_Header *Hdr;
+ Objid *op;
{
- 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 );
+ 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;
}
/*
@@ -1997,20 +2143,13 @@ Increment_DL ( sig )
int sig;
{
Debug_Level++;
- if ( Debug_Level && Log == (FILE *)NULL ) {
- if ( foregnd ) {
- Log = stderr;
- } else {
- if ( ( Log = fopen ( LOG_FILE, "a" ) ) == NULL )
- Log = NULL;
- }
- if ( Log ) {
+ if ( Debug_Level && Log == (FILE *)NULL )
+ if ( ( Log = fopen ( LOG_FILE, "a" ) ) == NULL )
+ Log = NULL;
+ else
setbuf ( Log, NULL );
- write_timestamp();
- fprintf ( Log, "Raised Debug_Level to %d\n", Debug_Level );
- }
- }
signal ( SIGUSR1, Increment_DL );
+ alarm ( SLEEP_TIME );
return;
}
@@ -2034,388 +2173,37 @@ Decrement_DL ( sig )
if ( Debug_Level <= 0 ) {
Debug_Level = 0;
if ( Log ) {
- write_timestamp();
- fprintf ( Log, "Lowered Debug_Level to %d\n", Debug_Level );
- if ( !foregnd )
- fclose ( Log );
+ 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])
@@ -2460,10 +2248,34 @@ 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 );
@@ -2471,16 +2283,11 @@ main ( argc, argv )
/*
* Open log file
*/
- if ( Debug_Level ) {
- if ( foregnd ) {
- Log = stderr;
- } else {
- if ( ( Log = fopen ( LOG_FILE, "a" ) ) == NULL )
- Log = NULL;
- }
- }
- if ( Log )
- setbuf ( Log, NULL );
+ if ( Debug_Level )
+ if ( ( Log = fopen ( LOG_FILE, "a" ) ) == NULL )
+ Log = NULL;
+ else
+ setbuf ( Log, NULL );
/*
* Get our startup time
@@ -2489,13 +2296,12 @@ 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;
}
/*
@@ -2508,23 +2314,497 @@ main ( argc, argv )
*/
if ( Reset ) {
for ( i = 0; i < MAX_UNITS; i++ )
- 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 ( trap_fd[i] >= 0 ) {
if ( Debug_Level > 1 && Log ) {
write_timestamp();
- fprintf ( Log, "Close ilmi_fd[%d]: %d\n",
- i, ilmi_fd[i] );
+ fprintf ( Log, "Close trap_fd[%d]: %d\n",
+ i, trap_fd[i] );
}
- close ( ilmi_fd[i] );
+ close ( trap_fd[i] );
}
exit ( 2 );
}
- ilmi_do_state();
+ /*
+ * 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;
- exit(0);
+ } /* 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 */
+
}