]>
git.ipfire.org Git - thirdparty/squid.git/blob - snmplib/snmp_msg.c
623c81090f537541546ea00f260db489a2dce819
2 * SNMP Message Encoding Routines
6 * RFC 1901: Introduction to Community-based SNMPv2
7 * RFC 1157: A Simple Network Management Protocol (SNMP)
10 /**********************************************************************
12 * Copyright 1997 by Carnegie Mellon University
16 * Permission to use, copy, modify, and distribute this software and its
17 * documentation for any purpose and without fee is hereby granted,
18 * provided that the above copyright notice appear in all copies and that
19 * both that copyright notice and this permission notice appear in
20 * supporting documentation, and that the name of CMU not be
21 * used in advertising or publicity pertaining to distribution of the
22 * software without specific, written prior permission.
24 * CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
25 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
26 * CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
27 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
28 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
29 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
32 * Author: Ryan Troll <ryan+@andrew.cmu.edu>
34 **********************************************************************/
47 #include <sys/types.h>
53 #include <gnumalloc.h>
70 #include <sys/socket.h>
73 #include <netinet/in.h>
76 #include <arpa/inet.h>
87 #include "snmp_vars.h"
92 * RFC 1901: Introduction to Community-based SNMPv2
97 * community OCTET STRING
101 * RFC 1157: A Simple Network Management Protocol (SNMP)
106 * community OCTET STRING
112 /* Encode a SNMP Message Header. Return a pointer to the beginning of the
116 #define ASN_PARSE_ERROR(x) { return(x); }
118 /* Encode an SNMP Message
120 * Returns a pointer to the end of the message, or NULL.
122 * *BufLenP (Second Argument) will contain the amount of space left
127 snmp_msg_Encode(u_char
* Buffer
, int *BufLenP
,
128 u_char
* Community
, int CommLen
,
130 struct snmp_pdu
*PDU
)
133 u_char
*PDUHeaderPtr
, *VARHeaderPtr
;
134 u_char
*PDUDataStart
, *VARDataStart
;
138 snmplib_debug(4, "Buffer=%p BufLenP=%p, buflen=%d\n", Buffer
, BufLenP
,
140 /* Header for the entire thing, with a false, large length */
141 bufp
= asn_build_header(Buffer
, BufLenP
,
142 (u_char
) (ASN_SEQUENCE
|
146 snmplib_debug(4, "snmp_msg_Encode:Error encoding SNMP Message Header (Header)!\n");
152 bufp
= asn_build_int(bufp
, BufLenP
,
153 (u_char
) (ASN_UNIVERSAL
|
156 (int *) (&Version
), sizeof(Version
));
158 snmplib_debug(4, "snmp_msg_Encode:Error encoding SNMP Message Header (Version)!\n");
161 snmplib_debug(8, "snmp_msg_Encode: Encoding community (%s) (%d)\n", Community
, CommLen
);
164 bufp
= asn_build_string(bufp
, BufLenP
,
165 (u_char
) (ASN_UNIVERSAL
|
170 snmplib_debug(4, "snmp_msg_Encode:Error encoding SNMP Message Header (Community)!\n");
173 /* Encode the rest. */
175 /* A nice header for this PDU.
176 * Encoded with the wrong length. We'll fix it later.
178 snmplib_debug(8, "snmp_msg_Encode:Encoding PDU Header at 0x%p (fake len %d) (%d bytes so far)\n",
179 bufp
, *BufLenP
, *BufLenP
);
181 bufp
= asn_build_header(bufp
, BufLenP
,
182 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
187 /* Encode this PDU. */
189 bufp
= snmp_pdu_encode(bufp
, BufLenP
, PDU
);
191 return (NULL
); /* snmp_pdu_encode registered failure */
194 bufp
= asn_build_header(bufp
, BufLenP
,
195 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
201 /* And build the variables */
202 bufp
= snmp_var_EncodeVarBind(bufp
, BufLenP
, PDU
->variables
, Version
);
204 return (NULL
); /* snmp_var_EncodeVarBind registered failure */
206 /* Cool. Now insert the appropriate lengths.
209 snmplib_debug(9, "Msg: Vars returned 0x%x. PDU Started at 0x%x\n",
211 snmplib_debug(9, "MSG: Entire PDU length is %d (0x%x - 0x%x)\n",
212 (int) (bufp
- PDUDataStart
), PDUHeaderPtr
, bufp
);
214 tmp
= asn_build_header(PDUHeaderPtr
, &FakeArg
,
215 (u_char
) PDU
->command
,
216 (int) (bufp
- PDUDataStart
));
217 /* Length of the PDU and Vars */
222 snmplib_debug(9, "MSG: Entire message length is %d (0x%x - 0x%x)\n",
223 (int) (bufp
- MsgPtr
), MsgPtr
, bufp
);
225 tmp
= asn_build_header(Buffer
,
227 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
228 (bufp
- MsgPtr
)); /* Length of everything */
232 tmp
= asn_build_header(VARHeaderPtr
,
234 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
235 (bufp
- VARDataStart
)); /* Length of everything */
239 *BufLenP
= (bufp
- Buffer
);
240 return (u_char
*) bufp
;
243 /**********************************************************************/
246 snmp_msg_Decode(u_char
* Packet
, int *PacketLenP
,
247 u_char
* Community
, int *CommLenP
,
248 int *Version
, struct snmp_pdu
* PDU
)
253 bufp
= asn_parse_header(Packet
, PacketLenP
, &type
);
255 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Message Header (Header)!\n");
256 ASN_PARSE_ERROR(NULL
);
258 if (type
!= (ASN_SEQUENCE
| ASN_CONSTRUCTOR
)) {
259 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Message Header (Header)!\n");
260 ASN_PARSE_ERROR(NULL
);
262 bufp
= asn_parse_int(bufp
, PacketLenP
,
264 (int *) Version
, sizeof(*Version
));
266 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Message Header (Version)!\n");
267 ASN_PARSE_ERROR(NULL
);
269 bufp
= asn_parse_string(bufp
, PacketLenP
, &type
, Community
, CommLenP
);
271 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Message Header (Community)!\n");
272 ASN_PARSE_ERROR(NULL
);
274 Community
[*CommLenP
] = '\0';
276 if ((*Version
!= SNMP_VERSION_1
) &&
277 (*Version
!= SNMP_VERSION_2
)) {
279 /* Don't know how to handle this one. */
280 snmplib_debug(4, "snmp_msg_Decode:Unable to parse Version %u\n", *Version
);
281 snmplib_debug(4, "snmp_msg_Decode:Continuing anyway\n");
283 /* Now that we know the header, decode the PDU */
285 /* XXXXX -- More than one PDU? */
286 bufp
= snmp_pdu_decode(bufp
, PacketLenP
, PDU
);
288 /* snmp_pdu_decode registered failure */
291 bufp
= snmp_var_DecodeVarBind(bufp
, PacketLenP
, &(PDU
->variables
), *Version
);
293 /* snmp_var_DecodeVarBind registered failure */
296 return (u_char
*) bufp
;