1 /* 2 This file is part of GNU Radius SNMP Library. 3 Copyright (C) 2001,2007 Free Software Foundation, Inc. 4 Written by Sergey Poznyakoff 5 6 This library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public License as 8 published by the Free Software Foundation; either version 3 of the 9 License, or (at your option) any later version. 10 11 This library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with this library; see the file COPYING.LIB. If not, 18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 Boston, MA 02111-1307, USA. */ 20 21 #include <sys/types.h> 22 #include <sys/socket.h> 23 #include <netinet/in.h> 24 #include <string.h> 25 26 typedef u_int ip_addr_t; 27 28 #define SNMP_PORT 161 29 #define SNMP_PACKET_LENGTH 4500 30 31 /* error definitions */ 32 #define E_ASN_ENCODE 1 33 #define E_ASN_DECODE 2 34 #define E_SNMP_NOMEM 3 35 #define E_SNMP_BAD_OID 4 36 #define E_SNMP_BAD_ADDRESS 5 37 #define E_SNMP_SOCKET 6 38 #define E_SNMP_BIND 7 39 #define E_SNMP_SEND 8 40 #define E_SNMP_NOT_SUPPORTED 9 41 #define E_SNMP_DECODE 10 42 #define E_SNMP_BAD_VERSION 11 43 #define E_SNMP_UNKNOWN_REQ 12 44 #define E_SNMP_BAD_VARTYPE 13 45 46 extern int * __snmp_errno_location(); 47 #define snmp_errno (*__snmp_errno_location()) 48 #define SNMP_SET_ERRNO(e) snmp_errno = (e) 49 50 #define SMI_INTEGER ASN_INTEGER 51 #define SMI_STRING ASN_OCTET_STR 52 #define SMI_OBJID ASN_OBJECT_ID 53 #define SMI_NULLOBJ ASN_NULL 54 #define SMI_IPADDRESS ASN_IPADDRESS 55 #define SMI_COUNTER32 ASN_COUNTER 56 #define SMI_GAUGE32 ASN_GAUGE 57 #define SMI_UNSIGNED32 SMI_GAUGE32 58 #define SMI_TIMETICKS ASN_TIMETICKS 59 #define SMI_OPAQUE ASN_OPAQUE 60 #define SMI_COUNTER64 ASN_COUNTER64 61 62 /* PDU types */ 63 #define SNMP_PDU_GET (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x0) 64 #define SNMP_PDU_GETNEXT (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x1) 65 #define SNMP_PDU_RESPONSE (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x2) 66 #define SNMP_PDU_SET (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x3) 67 #define SNMP_MSG_TRAP (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x4) 68 69 /* PDU error values */ 70 #define SNMP_ERR_NOERROR 0x0 71 #define SNMP_ERR_TOOBIG 0x1 72 #define SNMP_ERR_NOSUCHNAME 0x2 73 #define SNMP_ERR_BADVALUE 0x3 74 #define SNMP_ERR_READONLY 0x4 75 #define SNMP_ERR_GENERR 0x5 76 #define SNMP_ERR_NOACCESS 0x6 77 #define SNMP_ERR_WRONGTYPE 0x7 78 #define SNMP_ERR_WRONGLENGTH 0x8 79 #define SNMP_ERR_WRONGENCODING 0x9 80 #define SNMP_ERR_WRONGVALUE 0x10 81 #define SNMP_ERR_NOCREATION 0x11 82 #define SNMP_ERR_INCONSISTENTVALUE 0x12 83 #define SNMP_ERR_RESOURCEUNAVAILABLE 0x13 84 #define SNMP_ERR_COMMITFAILED 0x14 85 #define SNMP_ERR_UNDOFAILED 0x15 86 #define SNMP_ERR_AUTHORIZATIONERROR 0x16 87 #define SNMP_ERR_NOTWRITABLE 0x17 88 #define SNMP_ERR_INCONSISTENTNAME 0x18 89 90 /* Versions */ 91 #define SNMP_VERSION_1 0 92 93 /* variable */ 94 struct snmp_var { 95 struct snmp_var *next; 96 oid_t name; 97 int val_length; 98 u_char type; 99 union { 100 int i; 101 u_char *s; 102 oid_t o; 103 } v; 104 #define var_int v.i 105 #define var_str v.s 106 #define var_oid v.o 107 }; 108 109 struct snmp_pdu { 110 u_char type; 111 struct sockaddr_in peer_sin; /*??*/ 112 int req_id; 113 int err_stat; 114 int err_ind; 115 struct snmp_var *var; 116 }; 117 118 /* request list */ 119 struct snmp_request { 120 struct snmp_request *next; 121 int retries; /* number of retries this request already 122 suffered */ 123 int timeout; /* timeout for next retry */ 124 struct timeval expire; /* when this request will expire */ 125 struct snmp_pdu *pdu; /* PDU of the request */ 126 }; 127 128 #define SNMP_CONV_TIMEOUT 0 129 #define SNMP_CONV_RECV_MSG 1 130 #define SNMP_CONV_COMMUNITY_MISMATCH 2 131 132 struct snmp_session; 133 134 typedef int (*snmp_cfn)(int type, struct snmp_session *sp, struct snmp_pdu *pdu, void *closure); 135 136 struct snmp_session { 137 struct snmp_session *next; 138 139 int version; 140 struct { 141 u_char *str; 142 int len; 143 } community; 144 int retries; 145 int timeout; 146 char *remote_host; 147 u_short remote_port; 148 u_short local_port; 149 int sd; 150 struct sockaddr_in local_sin; 151 struct sockaddr_in remote_sin; 152 153 snmp_cfn converse; 154 void *app_closure; 155 156 struct snmp_pdu *pdu; 157 struct snmp_request *request_list; /* list of outstanding requests */ 158 }; 159 160 typedef void *(*snmp_alloc_t)(size_t); 161 typedef void *(*snmp_free_t)(void*); 162 163 void *snmp_alloc(size_t); 164 void snmp_free(void*); 165 char *snmp_strdup(char *str); 166 167 void snmp_init(int retries, int timeout, 168 snmp_alloc_t memalloc, snmp_free_t memfree); 169 170 oid_t oid_dup(oid_t oid); 171 oid_t oid_create(int len); 172 oid_t oid_create_from_string(char *str); 173 oid_t oid_create_from_subid(int len, subid_t *subid); 174 int oid_cmp(oid_t a, oid_t b); 175 176 char * sprint_oid(char *buf, int buflen, oid_t oid); 177 178 struct snmp_pdu *snmp_pdu_create(int type); 179 void snmp_pdu_free(struct snmp_pdu *pdu); 180 void snmp_pdu_add_var(struct snmp_pdu *pdu, struct snmp_var *var); 181 u_char *snmp_pdu_encode(u_char *data, int *length, struct snmp_pdu *pdu); 182 u_char *snmp_pdu_decode(u_char *data, int *length, struct snmp_pdu *pdu); 183 184 int snmp_send(struct snmp_session *sess, struct snmp_pdu *pdu); 185 int snmp_request_xmit(struct snmp_session *sess, struct snmp_request *req); 186 187 int snmp_req_id(void); 188 struct snmp_session *snmp_session_create(char *community, char *host, 189 int port, snmp_cfn cfn, 190 void *closure); 191 int snmp_session_open(struct snmp_session *sp, ip_addr_t local_ip, 192 int local_port, int timeout, int retries); 193 void snmp_session_close(struct snmp_session *sess); 194 void snmp_session_free(struct snmp_session *sess); 195 196 void snmp_var_free(struct snmp_var *var); 197 void snmp_var_free_list(struct snmp_var *var); 198 struct snmp_var *snmp_var_create(oid_t oid); 199 struct snmp_var *snmp_var_dup(struct snmp_var *src); 200 struct snmp_var *snmp_var_dup_list(struct snmp_var *var); 201 u_char *snmp_var_encode(u_char *data, int *length, struct snmp_var *var, 202 int version); 203 u_char *snmp_var_decode(u_char *data, int *length, struct snmp_var **var, 204 int version); 205 206 int snmp_encode_request(struct snmp_session *sess, struct snmp_pdu *pdu, 207 u_char *packet_buf, int *length); 208 int snmp_decode_request(struct snmp_session *sess, struct snmp_pdu *pdu, 209 u_char *packet, int length, char *comm, int *comm_len); 210 211 void snmp_poll(struct snmp_session *sess); 212 int snmp_query(struct snmp_session *sess, struct snmp_pdu *pdu); 213 void snmp_timeout(struct snmp_session *sess); 214 void snmp_read(struct snmp_session *sess, fd_set *fdset); 215 216 char *snmp_strerror(int en); 217