snparse.c
来自「TCP-IP红宝书源代码」· C语言 代码 · 共 137 行
C
137 行
/* snparse.c - snparse */
#include <conf.h>
#include <kernel.h>
#include <network.h>
#include <mem.h>
#include <string.h>
#ifdef SNMP
#include <snmp.h>
#include <asn1.h>
/*------------------------------------------------------------------------
* snparse - convert the ASN.1-encoded SNMP packet into internal form
* N.B. the binding list rqdp->bindlf must either be NULL or a valid
* binding list, in which case I'll free it up.
*------------------------------------------------------------------------
*/
int
snparse(struct req_desc *rqdp, u_char *snmppack, int len)
{
struct snbentry *bl, *lastbl = 0;
register u_char *packp;
int totpacklen = 0, commlen = 0;
int pdulen, totbindlen = 0;
u_int lenlen;
int varbindlen = 0;
u_char *packendp;
packp = snmppack;
packendp = snmppack + len;
/* sequence operator and total packet length */
if (*packp++ != ASN1_SEQ ||
(totpacklen = a1readlen(packp, &lenlen)) < 0) {
return SYSERR;
}
packp += lenlen;
/* verify total length, version, community */
if (packendp != packp + totpacklen ||
*packp++ != ASN1_INT ||
*packp++ != SVERS_LEN ||
*packp++ != SVERSION ||
*packp++ != ASN1_OCTSTR ||
(commlen = a1readlen(packp, &lenlen)) < 0) {
return SYSERR;
}
packp += lenlen;
if (strncmp((char *)packp, SCOMM_STR, commlen) != 0) {
return SYSERR;
}
packp += commlen;
/* PDU type and length */
if (*packp == PDU_TRAP)
return SYSERR;
rqdp->pdutype_pos = packp - snmppack;
rqdp->reqtype = *packp++;
if ((pdulen = a1readlen(packp, &lenlen)) < 0) {
return SYSERR;
}
packp += lenlen;
/* verify PDU length */
if (packendp != packp + pdulen) {
return SYSERR;
}
/* request id */
if (*packp++ != ASN1_INT ||
(rqdp->reqidlen = a1readlen(packp, &lenlen)) < 0) {
return SYSERR;
}
packp += lenlen;
memcpy(rqdp->reqid, packp, rqdp->reqidlen);
packp += rqdp->reqidlen;
/* error status */
if (*packp++ != ASN1_INT || *packp++ != 1) {
return SYSERR;
}
rqdp->err_stat = *packp;
rqdp->err_stat_pos = packp++ - snmppack;
/* error index */
if (*packp++ != ASN1_INT || *packp++ != 1) {
return SYSERR;
}
rqdp->err_idx = *packp;
rqdp->err_idx_pos = packp++ - snmppack;
/* sequence of variable bindings */
if (*packp++ != ASN1_SEQ ||
(totbindlen = a1readlen(packp, &lenlen)) < 0) {
return SYSERR;
}
packp += lenlen;
/* canberra bug fix - rqdp might already have old dynamic memory */
/* attached, free before overwriting pointers */
snfreebl(&rqdp->bindlf);
/* verify variable bindings length */
if (packendp != packp + totbindlen)
return SYSERR;
/* build doubly-linked bindings list; fill in only sb_a1str's */
rqdp->bindlf = rqdp->bindle = (struct snbentry *) NULL;
do {
bl = (struct snbentry *) getmem(sizeof(struct snbentry));
bl->sb_next = 0;
bl->sb_prev = 0;
if (rqdp->bindlf) {
lastbl->sb_next = bl;
bl->sb_prev = lastbl;
lastbl = bl;
} else
lastbl = rqdp->bindlf = bl;
bl->sb_a1str = packp;
bl->sb_a1dynstr = FALSE; /* not dynamically allocated */
if (*packp++ != ASN1_SEQ ||
(varbindlen = a1readlen(packp, &lenlen)) < 0) {
return SYSERR;
}
packp += lenlen;
bl->sb_a1slen = varbindlen;
packp += varbindlen;
} while (packp < packendp);
/* check that the entire packet has now been parsed */
if (packp != packendp) {
return SYSERR;
}
rqdp->bindle = lastbl;
return OK;
}
#endif /* SNMP */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?