]>
git.ipfire.org Git - thirdparty/squid.git/blob - lib/snmplib/snmp_msg.c
2 * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
10 * SNMP Message Encoding Routines
14 * RFC 1901: Introduction to Community-based SNMPv2
15 * RFC 1157: A Simple Network Management Protocol (SNMP)
18 /**********************************************************************
20 * Copyright 1997 by Carnegie Mellon University
24 * Permission to use, copy, modify, and distribute this software and its
25 * documentation for any purpose and without fee is hereby granted,
26 * provided that the above copyright notice appear in all copies and that
27 * both that copyright notice and this permission notice appear in
28 * supporting documentation, and that the name of CMU not be
29 * used in advertising or publicity pertaining to distribution of the
30 * software without specific, written prior permission.
32 * CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
33 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
34 * CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
35 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
36 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
37 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
40 * Author: Ryan Troll <ryan+@andrew.cmu.edu>
42 **********************************************************************/
53 #include <sys/types.h>
59 #include <gnumalloc.h>
76 #include <sys/socket.h>
79 #include <netinet/in.h>
82 #include <arpa/inet.h>
95 #include "snmp_vars.h"
98 * RFC 1901: Introduction to Community-based SNMPv2
103 * community OCTET STRING
107 * RFC 1157: A Simple Network Management Protocol (SNMP)
112 * community OCTET STRING
118 /* Encode a SNMP Message Header. Return a pointer to the beginning of the
122 #define ASN_PARSE_ERROR(x) { return(x); }
124 /* Encode an SNMP Message
126 * Returns a pointer to the end of the message, or NULL.
128 * *BufLenP (Second Argument) will contain the amount of space left
133 snmp_msg_Encode(u_char
* Buffer
, int *BufLenP
,
134 u_char
* Community
, int CommLen
,
136 struct snmp_pdu
*PDU
)
139 u_char
*PDUHeaderPtr
, *VARHeaderPtr
;
140 u_char
*PDUDataStart
, *VARDataStart
;
144 snmplib_debug(4, "Buffer=%p BufLenP=%p, buflen=%d\n", Buffer
, BufLenP
,
146 /* Header for the entire thing, with a false, large length */
147 bufp
= asn_build_header(Buffer
, BufLenP
,
148 (u_char
) (ASN_SEQUENCE
|
152 snmplib_debug(4, "snmp_msg_Encode:Error encoding SNMP Message Header (Header)!\n");
158 bufp
= asn_build_int(bufp
, BufLenP
,
159 (u_char
) (ASN_UNIVERSAL
|
162 (int *) (&Version
), sizeof(Version
));
164 snmplib_debug(4, "snmp_msg_Encode:Error encoding SNMP Message Header (Version)!\n");
167 snmplib_debug(8, "snmp_msg_Encode: Encoding community (%s) (%d)\n", Community
, CommLen
);
170 bufp
= asn_build_string(bufp
, BufLenP
,
171 (u_char
) (ASN_UNIVERSAL
|
176 snmplib_debug(4, "snmp_msg_Encode:Error encoding SNMP Message Header (Community)!\n");
179 /* Encode the rest. */
181 /* A nice header for this PDU.
182 * Encoded with the wrong length. We'll fix it later.
184 snmplib_debug(8, "snmp_msg_Encode:Encoding PDU Header at 0x%p (fake len %d) (%d bytes so far)\n",
185 bufp
, *BufLenP
, *BufLenP
);
187 bufp
= asn_build_header(bufp
, BufLenP
,
188 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
193 /* Encode this PDU. */
195 bufp
= snmp_pdu_encode(bufp
, BufLenP
, PDU
);
197 return (NULL
); /* snmp_pdu_encode registered failure */
200 bufp
= asn_build_header(bufp
, BufLenP
,
201 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
207 /* And build the variables */
208 bufp
= snmp_var_EncodeVarBind(bufp
, BufLenP
, PDU
->variables
, Version
);
210 return (NULL
); /* snmp_var_EncodeVarBind registered failure */
212 /* Cool. Now insert the appropriate lengths.
215 snmplib_debug(9, "Msg: Vars returned 0x%x. PDU Started at 0x%x\n",
217 snmplib_debug(9, "MSG: Entire PDU length is %d (0x%x - 0x%x)\n",
218 (int) (bufp
- PDUDataStart
), PDUHeaderPtr
, bufp
);
220 tmp
= asn_build_header(PDUHeaderPtr
, &FakeArg
,
221 (u_char
) PDU
->command
,
222 (int) (bufp
- PDUDataStart
));
223 /* Length of the PDU and Vars */
228 snmplib_debug(9, "MSG: Entire message length is %d (0x%x - 0x%x)\n",
229 (int) (bufp
- MsgPtr
), MsgPtr
, bufp
);
231 tmp
= asn_build_header(Buffer
,
233 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
234 (bufp
- MsgPtr
)); /* Length of everything */
238 tmp
= asn_build_header(VARHeaderPtr
,
240 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
241 (bufp
- VARDataStart
)); /* Length of everything */
245 *BufLenP
= (bufp
- Buffer
);
246 return (u_char
*) bufp
;
249 /**********************************************************************/
252 snmp_msg_Decode(u_char
* Packet
, int *PacketLenP
,
253 u_char
* Community
, int *CommLenP
,
254 int *Version
, struct snmp_pdu
* PDU
)
259 bufp
= asn_parse_header(Packet
, PacketLenP
, &type
);
261 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Message Header (Header)!\n");
262 ASN_PARSE_ERROR(NULL
);
264 if (type
!= (ASN_SEQUENCE
| ASN_CONSTRUCTOR
)) {
265 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Message Header (Header)!\n");
266 ASN_PARSE_ERROR(NULL
);
268 bufp
= asn_parse_int(bufp
, PacketLenP
,
270 (int *) Version
, sizeof(*Version
));
272 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Message Header (Version)!\n");
273 ASN_PARSE_ERROR(NULL
);
275 bufp
= asn_parse_string(bufp
, PacketLenP
, &type
, Community
, CommLenP
);
277 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Message Header (Community)!\n");
278 ASN_PARSE_ERROR(NULL
);
280 Community
[*CommLenP
] = '\0';
282 if ((*Version
!= SNMP_VERSION_1
) &&
283 (*Version
!= SNMP_VERSION_2
)) {
285 /* Don't know how to handle this one. */
286 snmplib_debug(4, "snmp_msg_Decode:Unable to parse Version %u\n", *Version
);
287 snmplib_debug(4, "snmp_msg_Decode:Continuing anyway\n");
289 /* Now that we know the header, decode the PDU */
291 /* XXXXX -- More than one PDU? */
292 bufp
= snmp_pdu_decode(bufp
, PacketLenP
, PDU
);
294 /* snmp_pdu_decode registered failure */
297 bufp
= snmp_var_DecodeVarBind(bufp
, PacketLenP
, &(PDU
->variables
), *Version
);
299 /* snmp_var_DecodeVarBind registered failure */
302 return (u_char
*) bufp
;