]>
git.ipfire.org Git - thirdparty/squid.git/blob - lib/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 **********************************************************************/
45 #include <sys/types.h>
51 #include <gnumalloc.h>
68 #include <sys/socket.h>
71 #include <netinet/in.h>
74 #include <arpa/inet.h>
87 #include "snmp_vars.h"
90 * RFC 1901: Introduction to Community-based SNMPv2
95 * community OCTET STRING
99 * RFC 1157: A Simple Network Management Protocol (SNMP)
104 * community OCTET STRING
110 /* Encode a SNMP Message Header. Return a pointer to the beginning of the
114 #define ASN_PARSE_ERROR(x) { return(x); }
116 /* Encode an SNMP Message
118 * Returns a pointer to the end of the message, or NULL.
120 * *BufLenP (Second Argument) will contain the amount of space left
125 snmp_msg_Encode(u_char
* Buffer
, int *BufLenP
,
126 u_char
* Community
, int CommLen
,
128 struct snmp_pdu
*PDU
)
131 u_char
*PDUHeaderPtr
, *VARHeaderPtr
;
132 u_char
*PDUDataStart
, *VARDataStart
;
136 snmplib_debug(4, "Buffer=%p BufLenP=%p, buflen=%d\n", Buffer
, BufLenP
,
138 /* Header for the entire thing, with a false, large length */
139 bufp
= asn_build_header(Buffer
, BufLenP
,
140 (u_char
) (ASN_SEQUENCE
|
144 snmplib_debug(4, "snmp_msg_Encode:Error encoding SNMP Message Header (Header)!\n");
150 bufp
= asn_build_int(bufp
, BufLenP
,
151 (u_char
) (ASN_UNIVERSAL
|
154 (int *) (&Version
), sizeof(Version
));
156 snmplib_debug(4, "snmp_msg_Encode:Error encoding SNMP Message Header (Version)!\n");
159 snmplib_debug(8, "snmp_msg_Encode: Encoding community (%s) (%d)\n", Community
, CommLen
);
162 bufp
= asn_build_string(bufp
, BufLenP
,
163 (u_char
) (ASN_UNIVERSAL
|
168 snmplib_debug(4, "snmp_msg_Encode:Error encoding SNMP Message Header (Community)!\n");
171 /* Encode the rest. */
173 /* A nice header for this PDU.
174 * Encoded with the wrong length. We'll fix it later.
176 snmplib_debug(8, "snmp_msg_Encode:Encoding PDU Header at 0x%p (fake len %d) (%d bytes so far)\n",
177 bufp
, *BufLenP
, *BufLenP
);
179 bufp
= asn_build_header(bufp
, BufLenP
,
180 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
185 /* Encode this PDU. */
187 bufp
= snmp_pdu_encode(bufp
, BufLenP
, PDU
);
189 return (NULL
); /* snmp_pdu_encode registered failure */
192 bufp
= asn_build_header(bufp
, BufLenP
,
193 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
199 /* And build the variables */
200 bufp
= snmp_var_EncodeVarBind(bufp
, BufLenP
, PDU
->variables
, Version
);
202 return (NULL
); /* snmp_var_EncodeVarBind registered failure */
204 /* Cool. Now insert the appropriate lengths.
207 snmplib_debug(9, "Msg: Vars returned 0x%x. PDU Started at 0x%x\n",
209 snmplib_debug(9, "MSG: Entire PDU length is %d (0x%x - 0x%x)\n",
210 (int) (bufp
- PDUDataStart
), PDUHeaderPtr
, bufp
);
212 tmp
= asn_build_header(PDUHeaderPtr
, &FakeArg
,
213 (u_char
) PDU
->command
,
214 (int) (bufp
- PDUDataStart
));
215 /* Length of the PDU and Vars */
220 snmplib_debug(9, "MSG: Entire message length is %d (0x%x - 0x%x)\n",
221 (int) (bufp
- MsgPtr
), MsgPtr
, bufp
);
223 tmp
= asn_build_header(Buffer
,
225 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
226 (bufp
- MsgPtr
)); /* Length of everything */
230 tmp
= asn_build_header(VARHeaderPtr
,
232 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
233 (bufp
- VARDataStart
)); /* Length of everything */
237 *BufLenP
= (bufp
- Buffer
);
238 return (u_char
*) bufp
;
241 /**********************************************************************/
244 snmp_msg_Decode(u_char
* Packet
, int *PacketLenP
,
245 u_char
* Community
, int *CommLenP
,
246 int *Version
, struct snmp_pdu
* PDU
)
251 bufp
= asn_parse_header(Packet
, PacketLenP
, &type
);
253 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Message Header (Header)!\n");
254 ASN_PARSE_ERROR(NULL
);
256 if (type
!= (ASN_SEQUENCE
| ASN_CONSTRUCTOR
)) {
257 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Message Header (Header)!\n");
258 ASN_PARSE_ERROR(NULL
);
260 bufp
= asn_parse_int(bufp
, PacketLenP
,
262 (int *) Version
, sizeof(*Version
));
264 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Message Header (Version)!\n");
265 ASN_PARSE_ERROR(NULL
);
267 bufp
= asn_parse_string(bufp
, PacketLenP
, &type
, Community
, CommLenP
);
269 snmplib_debug(4, "snmp_msg_Decode:Error decoding SNMP Message Header (Community)!\n");
270 ASN_PARSE_ERROR(NULL
);
272 Community
[*CommLenP
] = '\0';
274 if ((*Version
!= SNMP_VERSION_1
) &&
275 (*Version
!= SNMP_VERSION_2
)) {
277 /* Don't know how to handle this one. */
278 snmplib_debug(4, "snmp_msg_Decode:Unable to parse Version %u\n", *Version
);
279 snmplib_debug(4, "snmp_msg_Decode:Continuing anyway\n");
281 /* Now that we know the header, decode the PDU */
283 /* XXXXX -- More than one PDU? */
284 bufp
= snmp_pdu_decode(bufp
, PacketLenP
, PDU
);
286 /* snmp_pdu_decode registered failure */
289 bufp
= snmp_var_DecodeVarBind(bufp
, PacketLenP
, &(PDU
->variables
), *Version
);
291 /* snmp_var_DecodeVarBind registered failure */
294 return (u_char
*) bufp
;