Corrected object identifier codec for object ids not starting with .iso.dod (e.g. zeroDotZero (0.0)).

This commit is contained in:
christiaans 2006-08-07 11:32:44 +00:00
parent a82e02ef15
commit 7eeaf8eaa5
2 changed files with 130 additions and 72 deletions

View File

@ -420,6 +420,7 @@ snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid)
{ {
u16_t plen, base; u16_t plen, base;
u8_t *msg_ptr; u8_t *msg_ptr;
s32_t *oid_ptr;
plen = 0; plen = 0;
while (p != NULL) while (p != NULL)
@ -431,13 +432,52 @@ snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid)
msg_ptr = p->payload; msg_ptr = p->payload;
msg_ptr += ofs - base; msg_ptr += ofs - base;
if ((len > 1) && (*msg_ptr == 0x2B)) oid->len = 0;
oid_ptr = &oid->id[0];
if (len > 0)
{
/* first compressed octet */
if (*msg_ptr == 0x2B)
{
/* (most) common case 1.3 (iso.org) */
*oid_ptr = 1;
oid_ptr++;
*oid_ptr = 3;
oid_ptr++;
}
else if (*msg_ptr < 40)
{
*oid_ptr = 0;
oid_ptr++;
*oid_ptr = *msg_ptr;
oid_ptr++;
}
else if (*msg_ptr < 80)
{
*oid_ptr = 1;
oid_ptr++;
*oid_ptr = (*msg_ptr) - 40;
oid_ptr++;
}
else
{
*oid_ptr = 2;
oid_ptr++;
*oid_ptr = (*msg_ptr) - 80;
oid_ptr++;
}
oid->len = 2;
}
else
{
/* length == 0, zero length (empty list) isn't allowed here.
ISO 8825 (BER) isn't clear about this, but some seem to accept it (why?).
zeroDotZero (0.0) must be at least 06 01 00 */
return ERR_ARG;
}
len--;
if (len > 0)
{ {
s32_t *oid_ptr;
/* we have compressed 1.3 (iso.org) Z = (X * 40) + Y */
len--;
/* proceed to .dod */
ofs += 1; ofs += 1;
if (ofs >= plen) if (ofs >= plen)
{ {
@ -452,51 +492,18 @@ snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid)
/* next octet in same pbuf */ /* next octet in same pbuf */
msg_ptr++; msg_ptr++;
} }
oid->len = 0; }
oid_ptr = &oid->id[0]; while ((len > 0) && (oid->len < LWIP_SNMP_OBJ_ID_LEN))
while ((len > 0) && (oid->len < LWIP_SNMP_OBJ_ID_LEN)) {
/* sub-identifier uses multiple octets */
if (*msg_ptr & 0x80)
{ {
/* sub-identifier uses multiple octets */ s32_t sub_id = 0;
if (*msg_ptr & 0x80)
{
s32_t sub_id = 0;
while ((*msg_ptr & 0x80) && (len > 1)) while ((*msg_ptr & 0x80) && (len > 1))
{
len--;
sub_id = (sub_id << 7) + (*msg_ptr & ~0x80);
ofs += 1;
if (ofs >= plen)
{
/* next octet in next pbuf */
p = p->next;
if (p == NULL) { return ERR_ARG; }
msg_ptr = p->payload;
plen += p->len;
}
else
{
/* next octet in same pbuf */
msg_ptr++;
}
}
if (!(*msg_ptr & 0x80) && (len > 0))
{
/* last octet sub-identifier */
len--;
sub_id = (sub_id << 7) + *msg_ptr;
*oid_ptr = sub_id;
}
}
else
{ {
/* !(*msg_ptr & 0x80) sub-identifier uses single octet */
len--; len--;
*oid_ptr = *msg_ptr; sub_id = (sub_id << 7) + (*msg_ptr & ~0x80);
}
if (len > 0)
{
/* remaining oid bytes available ... */
ofs += 1; ofs += 1;
if (ofs >= plen) if (ofs >= plen)
{ {
@ -511,26 +518,53 @@ snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid)
/* next octet in same pbuf */ /* next octet in same pbuf */
msg_ptr++; msg_ptr++;
} }
} }
oid_ptr++; if (!(*msg_ptr & 0x80) && (len > 0))
oid->len++; {
} /* last octet sub-identifier */
if (len == 0) len--;
{ sub_id = (sub_id << 7) + *msg_ptr;
/* len == 0, end of oid */ *oid_ptr = sub_id;
return ERR_OK; }
} }
else else
{ {
/* len > 0, oid->len == LWIP_SNMP_OBJ_ID_LEN or malformed encoding */ /* !(*msg_ptr & 0x80) sub-identifier uses single octet */
return ERR_ARG; len--;
*oid_ptr = *msg_ptr;
} }
if (len > 0)
{
/* remaining oid bytes available ... */
ofs += 1;
if (ofs >= plen)
{
/* next octet in next pbuf */
p = p->next;
if (p == NULL) { return ERR_ARG; }
msg_ptr = p->payload;
plen += p->len;
}
else
{
/* next octet in same pbuf */
msg_ptr++;
}
}
oid_ptr++;
oid->len++;
}
if (len == 0)
{
/* len == 0, end of oid */
return ERR_OK;
} }
else else
{ {
/* length <= 1 OR prefix not 1.3 (iso.org) */ /* len > 0, oid->len == LWIP_SNMP_OBJ_ID_LEN or malformed encoding */
return ERR_ARG; return ERR_ARG;
} }
} }
p = p->next; p = p->next;
} }

View File

@ -143,6 +143,13 @@ snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed)
u8_t cnt; u8_t cnt;
cnt = 0; cnt = 0;
if (ident_len > 1)
{
/* compressed prefix in one octet */
cnt++;
ident_len -= 2;
ident += 2;
}
while(ident_len > 0) while(ident_len > 0)
{ {
ident_len--; ident_len--;
@ -157,8 +164,6 @@ snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed)
} }
ident++; ident++;
} }
/* one extra for compressed iso.dod. prefix */
cnt++;
*octets_needed = cnt; *octets_needed = cnt;
} }
@ -445,22 +450,41 @@ snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident)
{ {
msg_ptr = p->payload; msg_ptr = p->payload;
msg_ptr += ofs - base; msg_ptr += ofs - base;
/* add compressed prefix .iso.dod */
*msg_ptr = 0x2b; if (ident_len > 1)
ofs += 1;
if (ofs >= plen)
{ {
/* next octet in next pbuf */ if ((ident[0] == 1) && (ident[1] == 3))
p = p->next; {
if (p == NULL) { return ERR_ARG; } /* compressed (most common) prefix .iso.dod */
msg_ptr = p->payload; *msg_ptr = 0x2b;
plen += p->len; }
else
{
/* calculate prefix */
*msg_ptr = (ident[0] * 40) + ident[1];
}
ofs += 1;
if (ofs >= plen)
{
/* next octet in next pbuf */
p = p->next;
if (p == NULL) { return ERR_ARG; }
msg_ptr = p->payload;
plen += p->len;
}
else
{
/* next octet in same pbuf */
msg_ptr++;
}
ident_len -= 2;
ident += 2;
} }
else else
{ {
/* next octet in same pbuf */ /* ident_len <= 1, at least we need zeroDotZero (0.0) (ident_len == 2) */
msg_ptr++; return ERR_ARG;
} }
while (ident_len > 0) while (ident_len > 0)
{ {
s32_t sub_id; s32_t sub_id;