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

📄 snmpudpdomain.c

📁 snmp up 2
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <net-snmp/net-snmp-config.h>#include <stdio.h>#include <sys/types.h>#include <ctype.h>#include <errno.h>#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_UNISTD_H#include <unistd.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_NETDB_H#include <netdb.h>#endif#if HAVE_DMALLOC_H#include <dmalloc.h>#endif#include <net-snmp/types.h>#include <net-snmp/output_api.h>#include <net-snmp/config_api.h>#include <net-snmp/library/snmp_transport.h>#include <net-snmp/library/snmpUDPDomain.h>#ifndef INADDR_NONE#define INADDR_NONE	-1#endifstatic netsnmp_tdomain udpDomain;/* * Return a string representing the address in data, or else the "far end" * address if data is NULL.   */static char *netsnmp_udp_fmtaddr(netsnmp_transport *t, void *data, int len){    struct sockaddr_in *to = NULL;    if (data != NULL && len == sizeof(struct sockaddr_in)) {        to = (struct sockaddr_in *) data;    } else if (t != NULL && t->data != NULL) {        to = (struct sockaddr_in *) t->data;    }    if (to == NULL) {        return strdup("UDP: unknown");    } else {	char tmp[64];        /*         * Here we just print the IP address of the peer for compatibility         * purposes.  It would be nice if we could include the port number and         * some indication of the domain (c.f. AAL5PVC).           */        sprintf(tmp, "%s", inet_ntoa(to->sin_addr));        return strdup(tmp);    }}/* * You can write something into opaque that will subsequently get passed back  * to your send function if you like.  For instance, you might want to * remember where a PDU came from, so that you can send a reply there...   */static intnetsnmp_udp_recv(netsnmp_transport *t, void *buf, int size,		 void **opaque, int *olength){    int             rc = -1;    socklen_t       fromlen = sizeof(struct sockaddr);    struct sockaddr *from;    if (t != NULL && t->sock >= 0) {        from = (struct sockaddr *) malloc(sizeof(struct sockaddr_in));        if (from == NULL) {            *opaque = NULL;            *olength = 0;            return -1;        } else {            memset(from, 0, fromlen);        }	while (rc < 0) {	    rc = recvfrom(t->sock, buf, size, 0, from, &fromlen);	    if (rc < 0 && errno != EINTR) {		break;	    }	}        if (rc >= 0) {            char *string = netsnmp_udp_fmtaddr(NULL, from, fromlen);            DEBUGMSGTL(("netsnmp_udp",			"recvfrom fd %d got %d bytes (from %s)\n",			t->sock, rc, string));            free(string);        } else {            DEBUGMSGTL(("netsnmp_udp", "recvfrom fd %d err %d (\"%s\")\n",                        t->sock, errno, strerror(errno)));        }        *opaque = (void *)from;        *olength = sizeof(struct sockaddr_in);    }    return rc;}static intnetsnmp_udp_send(netsnmp_transport *t, void *buf, int size,		 void **opaque, int *olength){    int rc = -1;
	int i;
	char *aa;    struct sockaddr *to = NULL;
    if (opaque != NULL && *opaque != NULL &&        *olength == sizeof(struct sockaddr_in)) {        to = (struct sockaddr *) (*opaque);
    } else if (t != NULL && t->data != NULL &&               t->data_length == sizeof(struct sockaddr_in)) {        to = (struct sockaddr *) (t->data);    }

    if (to != NULL && t != NULL && t->sock >= 0) {        char *string = netsnmp_udp_fmtaddr(NULL, (void *) to,					sizeof(struct sockaddr_in));        DEBUGMSGTL(("netsnmp_udp", "send %d bytes from %p to %s on fd %d\n",                    size, buf, string, t->sock));        free(string);	while (rc < 0) {	    rc = sendto(t->sock, buf, size, 0, to, sizeof(struct sockaddr));	    if (rc < 0 && errno != EINTR) {		break;	    }	}    }    return rc;}static intnetsnmp_udp_close(netsnmp_transport *t){    int rc = -1;    if (t->sock >= 0) {#ifndef HAVE_CLOSESOCKET        rc = close(t->sock);#else        rc = closesocket(t->sock);#endif        t->sock = -1;    }    return rc;}/* * Open a UDP-based transport for SNMP.  Local is TRUE if addr is the local * address to bind to (i.e. this is a server-type session); otherwise addr is  * the remote address to send things to.   */netsnmp_transport *netsnmp_udp_transport(struct sockaddr_in *addr, int local){    netsnmp_transport *t = NULL;    int             rc = 0, udpbuf = (1 << 17);    char           *string = NULL;    if (addr == NULL || addr->sin_family != AF_INET) {        return NULL;    }    t = (netsnmp_transport *) malloc(sizeof(netsnmp_transport));    if (t == NULL) {        return NULL;    }    string = netsnmp_udp_fmtaddr(NULL, (void *)addr, 				 sizeof(struct sockaddr_in));    DEBUGMSGTL(("netsnmp_udp", "open %s %s\n", local ? "local" : "remote",                string));    free(string);    memset(t, 0, sizeof(netsnmp_transport));    t->domain = netsnmpUDPDomain;    t->domain_length = netsnmpUDPDomain_len;    t->sock = socket(PF_INET, SOCK_DGRAM, 0);    if (t->sock < 0) {        netsnmp_transport_free(t);        return NULL;    }#ifdef  SO_BSDCOMPAT    /*     * Patch for Linux.  Without this, UDP packets that fail get an ICMP     * response.  Linux turns the failed ICMP response into an error message     * and return value, unlike all other OS's.       */    {        int             one = 1;        setsockopt(t->sock, SOL_SOCKET, SO_BSDCOMPAT, (void *) &one,                   sizeof(one));    }#endif                          /*SO_BSDCOMPAT */    /*     * SO_REUSEADDR will allow multiple apps to open the same port at     * the same time. Only the last one to open the socket will get     * data. Obviously, for an agent, this is a bad thing. There should     * only be one listener.     */#ifdef ALLOW_PORT_HIJACKING#ifdef  SO_REUSEADDR    /*     * Allow the same port to be specified multiple times without failing.     *    (useful for a listener)     */    {        int             one = 1;        setsockopt(t->sock, SOL_SOCKET, SO_REUSEADDR, (void *) &one,                   sizeof(one));    }#endif                          /*SO_REUSEADDR */#endif    /*     * Try to set the send and receive buffers to a reasonably large value, so     * that we can send and receive big PDUs (defaults to 8192 bytes (!) on     * Solaris, for instance).  Don't worry too much about errors -- just     * plough on regardless.       */#ifdef  SO_SNDBUF    if (setsockopt        (t->sock, SOL_SOCKET, SO_SNDBUF, (void *) &udpbuf,         sizeof(int)) != 0) {        DEBUGMSGTL(("netsnmp_udp", "couldn't set SO_SNDBUF to %d bytes: %s\n",                    udpbuf, strerror(errno)));    }#endif                          /*SO_SNDBUF */#ifdef  SO_RCVBUF    if (setsockopt        (t->sock, SOL_SOCKET, SO_RCVBUF, (void *) &udpbuf,         sizeof(int)) != 0) {        DEBUGMSGTL(("netsnmp_udp", "couldn't set SO_RCVBUF to %d bytes: %s\n",                    udpbuf, strerror(errno)));    }#endif                          /*SO_RCVBUF */    if (local) {        /*         * This session is inteneded as a server, so we must bind on to the         * given IP address, which may include an interface address, or could         * be INADDR_ANY, but certainly includes a port number.         */        t->local = malloc(6);        if (t->local == NULL) {            netsnmp_transport_free(t);            return NULL;        }        memcpy(t->local, (u_char *) & (addr->sin_addr.s_addr), 4);        t->local[4] = (htons(addr->sin_port) & 0xff00) >> 8;        t->local[5] = (htons(addr->sin_port) & 0x00ff) >> 0;        t->local_length = 6;        rc = bind(t->sock, (struct sockaddr *) addr,                  sizeof(struct sockaddr));        if (rc != 0) {            netsnmp_udp_close(t);            netsnmp_transport_free(t);            return NULL;        }        t->data = NULL;        t->data_length = 0;    } else {        /*         * This is a client session.  Save the address in the         * transport-specific data pointer for later use by netsnmp_udp_send.         */        t->data = malloc(sizeof(struct sockaddr_in));        t->remote = malloc(6);        if (t->data == NULL || t->remote == NULL) {            netsnmp_transport_free(t);            return NULL;        }        memcpy(t->remote, (u_char *) & (addr->sin_addr.s_addr), 4);        t->remote[4] = (htons(addr->sin_port) & 0xff00) >> 8;        t->remote[5] = (htons(addr->sin_port) & 0x00ff) >> 0;        t->remote_length = 6;        memcpy(t->data, addr, sizeof(struct sockaddr_in));        t->data_length = sizeof(struct sockaddr_in);    }    /*     * 16-bit length field, 8 byte UDP header, 20 byte IPv4 header       */    t->msgMaxSize = 0xffff - 8 - 20;    t->f_recv     = netsnmp_udp_recv;    t->f_send     = netsnmp_udp_send;    t->f_close    = netsnmp_udp_close;    t->f_accept   = NULL;    t->f_fmtaddr  = netsnmp_udp_fmtaddr;    return t;}intnetsnmp_sockaddr_in(struct sockaddr_in *addr,                    const char *inpeername, int remote_port){    char           *cp = NULL, *peername = NULL;    if (addr == NULL) {        return 0;    }    memset(addr, 0, sizeof(struct sockaddr_in));    DEBUGMSGTL(("netsnmp_sockaddr_in", "addr %p, peername \"%s\"\n",                addr, inpeername ? inpeername : "[NIL]"));    addr->sin_addr.s_addr = htonl(INADDR_ANY);    addr->sin_family = AF_INET;    if (remote_port > 0) {        addr->sin_port = htons(remote_port);    } else if (netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, 				  NETSNMP_DS_LIB_DEFAULT_PORT) > 0) {        addr->sin_port = htons(netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, 						 NETSNMP_DS_LIB_DEFAULT_PORT));    } else {        addr->sin_port = htons(SNMP_PORT);    }    if (inpeername != NULL) {        /*         * Duplicate the peername because we might want to mank around with         * it.           */        peername = strdup(inpeername);        if (peername == NULL) {            return 0;        }        /*         * Try and extract an appended port number.           */        cp = strchr(peername, ':');        if (cp != NULL) {            *cp = '\0';            cp++;            if (atoi(cp) != 0) {                DEBUGMSGTL(("netsnmp_sockaddr_in",                            "port number suffix :%d\n", atoi(cp)));                addr->sin_port = htons(atoi(cp));            }        }        for (cp = peername; *cp && isdigit((int) *cp); cp++);

⌨️ 快捷键说明

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