]>
git.ipfire.org Git - thirdparty/squid.git/blob - snmplib/snmp_msg.c
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"
93 * RFC 1901: Introduction to Community-based SNMPv2
98 * community OCTET STRING
102 * RFC 1157: A Simple Network Management Protocol (SNMP)
107 * community OCTET STRING
113 /* Encode a SNMP Message Header. Return a pointer to the beginning of the
117 #define ASN_PARSE_ERROR(x) { return(x); }
119 /* Encode an SNMP Message
121 * Returns a pointer to the end of the message, or NULL.
123 * *BufLenP (Second Argument) will contain the amount of space left
128 snmp_msg_Encode(u_char
* Buffer
, int *BufLenP
,
129 u_char
* Community
, int CommLen
,
131 struct snmp_pdu
*PDU
)
134 u_char
*PDUHeaderPtr
, *VARHeaderPtr
;
135 u_char
*PDUDataStart
, *VARDataStart
;
139 snmplib_debug(4, "Buffer=%p BufLenP=%p, buflen=%d\n", Buffer
, BufLenP
,
141 /* Header for the entire thing, with a false, large length */
142 bufp
= asn_build_header(Buffer
, BufLenP
,
143 (u_char
) (ASN_SEQUENCE
|
147 snmplib_debug(4, "snmp_msg_Encode:Error encoding SNMP Message Header (Header)!\n");
153 bufp
= asn_build_int(bufp
, BufLenP
,
154 (u_char
) (ASN_UNIVERSAL
|
157 (int *) (&Version
), sizeof(Version
));
159 snmplib_debug(4, "snmp_msg_Encode:Error encoding SNMP Message Header (Version)!\n");
162 snmplib_debug(8, "snmp_msg_Encode: Encoding community (%s) (%d)\n", Community
, CommLen
);
165 bufp
= asn_build_string(bufp
, BufLenP
,
166 (u_char
) (ASN_UNIVERSAL
|
171 snmplib_debug(4, "snmp_msg_Encode:Error encoding SNMP Message Header (Community)!\n");
174 /* Encode the rest. */
176 /* A nice header for this PDU.
177 * Encoded with the wrong length. We'll fix it later.
179 snmplib_debug(8, "snmp_msg_Encode:Encoding PDU Header at 0x%p (fake len %d) (%d bytes so far)\n",
180 bufp
, *BufLenP
, *BufLenP
);
182 bufp
= asn_build_header(bufp
, BufLenP
,
183 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
188 /* Encode this PDU. */
190 bufp
= snmp_pdu_encode(bufp
, BufLenP
, PDU
);
192 return (NULL
); /* snmp_pdu_encode registered failure */
195 bufp
= asn_build_header(bufp
, BufLenP
,
196 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
202 /* And build the variables */
203 bufp
= snmp_var_EncodeVarBind(bufp
, BufLenP
, PDU
->variables
, Version
);
205 return (NULL
); /* snmp_var_EncodeVarBind registered failure */
207 /* Cool. Now insert the appropriate lengths.
210 snmplib_debug(9, "Msg: Vars returned 0x%x. PDU Started at 0x%x\n",
212 snmplib_debug(9, "MSG: Entire PDU length is %d (0x%x - 0x%x)\n",
213 (int) (bufp
- PDUDataStart
), PDUHeaderPtr
, bufp
);
215 tmp
= asn_build_header(PDUHeaderPtr
, &FakeArg
,
216 (u_char
) PDU
->command
,
217 (int) (bufp
- PDUDataStart
));
218 /* Length of the PDU and Vars */
223 snmplib_debug(9, "MSG: Entire message length is %d (0x%x - 0x%x)\n",
224 (int) (bufp
- MsgPtr
), MsgPtr
, bufp
);
226 tmp
= asn_build_header(Buffer
,
228 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
229 (bufp
- MsgPtr
)); /* Length of everything */
233 tmp
= asn_build_header(VARHeaderPtr
,
235 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
236 (bufp
- VARDataStart
)); /* Length of everything */
240 *BufLenP
= (bufp
- Buffer
);
241 return (u_char
*) bufp
;
244 /**********************************************************************/
247 snmp_msg_Decode(u_char
* Packet
, int *PacketLenP
,
248 u_char
* Community
, int *CommLenP
,
249 int *Version
, struct snmp_pdu
* PDU
)
254 bufp
= asn_parse_header(Packet
, PacketLenP
, &type
);
256 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Messsage Header (Header)!\n");
257 ASN_PARSE_ERROR(NULL
);
259 if (type
!= (ASN_SEQUENCE
| ASN_CONSTRUCTOR
)) {
260 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Messsage Header (Header)!\n");
261 ASN_PARSE_ERROR(NULL
);
263 bufp
= asn_parse_int(bufp
, PacketLenP
,
265 (int *) Version
, sizeof(*Version
));
267 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Messsage Header (Version)!\n");
268 ASN_PARSE_ERROR(NULL
);
270 bufp
= asn_parse_string(bufp
, PacketLenP
, &type
, Community
, CommLenP
);
272 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Messsage Header (Community)!\n");
273 ASN_PARSE_ERROR(NULL
);
275 Community
[*CommLenP
] = '\0';
277 if ((*Version
!= SNMP_VERSION_1
) &&
278 (*Version
!= SNMP_VERSION_2
)) {
280 /* Don't know how to handle this one. */
281 snmplib_debug(4, "snmp_msg_Decode:Unable to parse Version %u\n", *Version
);
282 snmplib_debug(4, "snmp_msg_Decode:Continuing anyway\n");
284 /* Now that we know the header, decode the PDU */
286 /* XXXXX -- More than one PDU? */
287 bufp
= snmp_pdu_decode(bufp
, PacketLenP
, PDU
);
289 /* snmp_pdu_decode registered failure */
292 bufp
= snmp_var_DecodeVarBind(bufp
, PacketLenP
, &(PDU
->variables
), *Version
);
294 /* snmp_var_DecodeVarBind registered failure */
297 return (u_char
*) bufp
;