⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asn1.c

📁 -
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Abstract Syntax Notation One, ASN.1 * As defined in ISO/IS 8824 and ISO/IS 8825 * This implements a subset of the above International Standards that * is sufficient to implement SNMP. * * Encodes abstract data types into a machine independent stream of bytes. * *//*************************************************************************** * *           Copyright 1997 by Carnegie Mellon University *  *                       All Rights Reserved *  * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of CMU not be * used in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. *  * CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL * CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. *  ***************************************************************************/#include "config.h"#include <stdio.h>#if HAVE_UNISTD_H#include <unistd.h>#endif#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_SYS_TYPES_H#include <sys/types.h>#endif#if HAVE_CTYPE_H#include <ctype.h>#endif#if HAVE_GNUMALLOC_H#include <gnumalloc.h>#elif HAVE_MALLOC_H && !defined(_SQUID_FREEBSD_) && !defined(_SQUID_NEXT_)#include <malloc.h>#endif#if HAVE_MEMORY_H#include <memory.h>#endif#ifdef HAVE_STRING_H#include <string.h>#endif#ifdef HAVE_STRINGS_H#include <strings.h>#endif#if HAVE_BSTRING_H#include <bstring.h>#endif#if HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif#if HAVE_NETINET_IN_H#include <netinet/in.h>#endif#if HAVE_ARPA_INET_H#include <arpa/inet.h>#endif#if HAVE_SYS_TIME_H#include <sys/time.h>#endif#if HAVE_NETDB_H#include <netdb.h>#endif#include "asn1.h"#include "snmp_api_error.h"u_char *asn_build_header(u_char * data,	/* IN - ptr to start of object */    int *datalength,		/* IN/OUT - # of valid bytes */					     /*          left in buffer */    u_char type,		/* IN - ASN type of object */    int length){				/* IN - length of object */    /* Truth is 0 'cause we don't know yet */    return (asn_build_header_with_truth(data, datalength, type, length, 0));}/* * asn_parse_int - pulls an int out of an ASN int type. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the end of this object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */u_char *asn_parse_int(u_char * data, int *datalength,    u_char * type, int *intp, int intsize)  /*    u_char *data;        IN     - pointer to start of object */  /*    int    *datalength;  IN/OUT - # of valid bytes left in buffer */  /*    u_char *type;        OUT    - asn type of object */  /*    int   *intp;         IN/OUT - pointer to start of output buffer */  /*    int     intsize;     IN     - size of output buffer */{    /*     * ASN.1 integer ::= 0x02 asnlength byte {byte}*     */    u_char *bufp = data;    u_int asn_length;    int value = 0;    /* Room to store int? */    if (intsize != sizeof(int)) {	snmp_set_api_error(SNMPERR_ASN_DECODE);	return (NULL);    }    /* Type */    *type = *bufp++;    /* Extract length */    bufp = asn_parse_length(bufp, &asn_length);    if (bufp == NULL)	return (NULL);    /* Make sure the entire int is in the buffer */    if (asn_length + (bufp - data) > *datalength) {	snmp_set_api_error(SNMPERR_ASN_DECODE);	return (NULL);    }    /* Can we store this int? */    if (asn_length > intsize) {	snmp_set_api_error(SNMPERR_ASN_DECODE);	return (NULL);    }    /* Remaining data */    *datalength -= (int) asn_length + (bufp - data);    /* Is the int negative? */    if (*bufp & 0x80)	value = -1;		/* integer is negative */    /* Extract the bytes */    while (asn_length--)	value = (value << 8) | *bufp++;    /* That's it! */    *intp = value;    return (bufp);}/* * asn_parse_unsigned_int - pulls an unsigned int out of an ASN int type. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the end of this object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */u_char *asn_parse_unsigned_int(u_char * data, int *datalength,    u_char * type, u_int * intp, int intsize)  /*    u_char *data;          IN     - pointer to start of object */  /*    int    *datalength;    IN/OUT - # of valid bytes left in buffer */  /*    u_char *type;          OUT    - asn type of object */  /*    u_int *intp;           IN/OUT - pointer to start of output buffer */  /*    int     intsize;       IN     - size of output buffer */{    /*     * ASN.1 integer ::= 0x02 asnlength byte {byte}*     */    u_char *bufp = data;    u_int asn_length;    int value = 0;    /* Room to store int? */    if (intsize != sizeof(int)) {	snmp_set_api_error(SNMPERR_ASN_DECODE);	return (NULL);    }    /* Type */    *type = *bufp++;    /* Extract length */    bufp = asn_parse_length(bufp, &asn_length);    if (bufp == NULL)	return (NULL);    /* Make sure the entire int is in the buffer */    if (asn_length + (bufp - data) > *datalength) {	snmp_set_api_error(SNMPERR_ASN_DECODE);	return (NULL);    }    /* Can we store this int? */    if ((asn_length > (intsize + 1)) ||	((asn_length == intsize + 1) && *bufp != 0x00)) {	snmp_set_api_error(SNMPERR_ASN_DECODE);	return (NULL);    }    /* Remaining data */    *datalength -= (int) asn_length + (bufp - data);    /* Is the int negative? */    if (*bufp & 0x80)	value = -1;		/* integer is negative */    /* Extract the bytes */    while (asn_length--)	value = (value << 8) | *bufp++;    /* That's it! */    *intp = value;    return (bufp);}/* * asn_build_int - builds an ASN object containing an integer. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the end of this object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */u_char *asn_build_int(u_char * data, int *datalength,    u_char type, int *intp, int intsize)  /*     u_char *data;         IN - pointer to start of output buffer */  /*     int    *datalength;   IN/OUT - # of valid bytes left in buffer */  /*     u_char  type;         IN - asn type of object */  /*     int   *intp;          IN - pointer to start of integer */  /*     int    intsize;       IN - size of *intp */{    /*     * ASN.1 integer ::= 0x02 asnlength byte {byte}*     */    int integer;    u_int mask;    if (intsize != sizeof(int)) {	snmp_set_api_error(SNMPERR_ASN_ENCODE);	return (NULL);    }    integer = *intp;    /*     * Truncate "unnecessary" bytes off of the most significant end of this     * 2's complement integer.  There should be no sequence of 9     * consecutive 1's or 0's at the most significant end of the     * integer.     */    mask = (u_int) 0x1FF << ((8 * (sizeof(int) - 1)) - 1);    /* mask is 0xFF800000 on a big-endian machine */    while ((((integer & mask) == 0) || ((integer & mask) == mask))	&& intsize > 1) {	intsize--;	integer <<= 8;    }    data = asn_build_header_with_truth(data, datalength, type, intsize, 1);    if (data == NULL)	return (NULL);    /* Enough room for what we just encoded? */    if (*datalength < intsize) {	snmp_set_api_error(SNMPERR_ASN_ENCODE);	return (NULL);    }    /* Insert it */    *datalength -= intsize;    mask = (u_int) 0xFF << (8 * (sizeof(int) - 1));    /* mask is 0xFF000000 on a big-endian machine */    while (intsize--) {	*data++ = (u_char) ((integer & mask) >> (8 * (sizeof(int) - 1)));	integer <<= 8;    }    return (data);}/* * asn_build_unsigned_int - builds an ASN object containing an integer. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the end of this object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */u_char *asn_build_unsigned_int(u_char * data, int *datalength,    u_char type, u_int * intp, int intsize)  /*     u_char *data;         IN     - pointer to start of output buffer */  /*     int    *datalength;   IN/OUT - # of valid bytes left in buffer */  /*     u_char  type;         IN     - asn type of object */  /*     u_int  *intp;         IN     - pointer to start of integer */  /*     int     intsize;      IN     - size of *intp */{    /*     * ASN.1 integer ::= 0x02 asnlength byte {byte}*     */    u_int integer;    u_int mask;    int add_null_byte = 0;    if (intsize != sizeof(int)) {	snmp_set_api_error(SNMPERR_ASN_ENCODE);	return (NULL);    }    integer = *intp;    mask = (u_int) 0xFF << (8 * (sizeof(int) - 1));    /* mask is 0xFF000000 on a big-endian machine */    if ((u_char) ((integer & mask) >> (8 * (sizeof(int) - 1))) & 0x80) {	/* if MSB is set */	add_null_byte = 1;	intsize++;    }    /*     * Truncate "unnecessary" bytes off of the most significant end of     * this 2's complement integer.      * There should be no sequence of 9 consecutive 1's or 0's at the     * most significant end of the integer.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -