|
|
| version 1.1.1.2, 2012/05/29 12:34:42 | version 1.1.1.3, 2013/07/22 01:32:01 |
|---|---|
| Line 2 | Line 2 |
| +----------------------------------------------------------------------+ | +----------------------------------------------------------------------+ |
| | PHP Version 5 | | | PHP Version 5 | |
| +----------------------------------------------------------------------+ | +----------------------------------------------------------------------+ |
| | Copyright (c) 1997-2012 The PHP Group | | | Copyright (c) 1997-2013 The PHP Group | |
| +----------------------------------------------------------------------+ | +----------------------------------------------------------------------+ |
| | This source file is subject to version 3.01 of the PHP license, | | | This source file is subject to version 3.01 of the PHP license, | |
| | that is bundled with this package in the file LICENSE, and is | | | that is bundled with this package in the file LICENSE, and is | |
| Line 551 static void php_snmp_error(zval *object, const char *d | Line 551 static void php_snmp_error(zval *object, const char *d |
| static void php_snmp_getvalue(struct variable_list *vars, zval *snmpval TSRMLS_DC, int valueretrieval) | static void php_snmp_getvalue(struct variable_list *vars, zval *snmpval TSRMLS_DC, int valueretrieval) |
| { | { |
| zval *val; | zval *val; |
| #ifdef BUGGY_SNMPRINT_VALUE | char sbuf[512]; |
| char sbuf[2048]; | |
| #else | |
| char sbuf[64]; | |
| #endif | |
| char *buf = &(sbuf[0]); | char *buf = &(sbuf[0]); |
| char *dbuf = (char *)NULL; | char *dbuf = (char *)NULL; |
| int buflen = sizeof(sbuf) - 1; | int buflen = sizeof(sbuf) - 1; |
| int val_len = vars->val_len; | int val_len = vars->val_len; |
| if ((valueretrieval & SNMP_VALUE_PLAIN) == 0) { | /* use emalloc() for large values, use static array otherwize */ |
| val_len += 32; /* snprint_value will add type info into value, make some space for it */ | |
| /* There is no way to know the size of buffer snprint_value() needs in order to print a value there. | |
| * So we are forced to probe it | |
| */ | |
| while ((valueretrieval & SNMP_VALUE_PLAIN) == 0) { | |
| *buf = '\0'; | |
| if (snprint_value(buf, buflen, vars->name, vars->name_length, vars) == -1) { | |
| if (val_len > 512*1024) { | |
| php_error_docref(NULL TSRMLS_CC, E_WARNING, "snprint_value() asks for a buffer more than 512k, Net-SNMP bug?"); | |
| break; | |
| } | |
| /* buffer is not long enough to hold full output, double it */ | |
| val_len *= 2; | |
| } else { | |
| break; | |
| } | |
| if (buf == dbuf) { | |
| dbuf = (char *)erealloc(dbuf, val_len + 1); | |
| } else { | |
| dbuf = (char *)emalloc(val_len + 1); | |
| } | |
| if (!dbuf) { | |
| php_error_docref(NULL TSRMLS_CC, E_WARNING, "emalloc() failed: %s, fallback to static buffer", strerror(errno)); | |
| buf = &(sbuf[0]); | |
| buflen = sizeof(sbuf) - 1; | |
| break; | |
| } | |
| buf = dbuf; | |
| buflen = val_len; | |
| } | } |
| /* use emalloc() for large values, use static array otherwize */ | if((valueretrieval & SNMP_VALUE_PLAIN) && val_len > buflen){ |
| if(val_len > buflen){ | |
| if ((dbuf = (char *)emalloc(val_len + 1))) { | if ((dbuf = (char *)emalloc(val_len + 1))) { |
| buf = dbuf; | buf = dbuf; |
| buflen = val_len; | buflen = val_len; |
| } else { | } else { |
| php_error_docref(NULL TSRMLS_CC, E_WARNING, "emalloc() failed: %s, fallback to static array", strerror(errno)); | php_error_docref(NULL TSRMLS_CC, E_WARNING, "emalloc() failed: %s, fallback to static buffer", strerror(errno)); |
| } | } |
| } | } |
| *buf = 0; | |
| MAKE_STD_ZVAL(val); | MAKE_STD_ZVAL(val); |
| if (valueretrieval & SNMP_VALUE_PLAIN) { | if (valueretrieval & SNMP_VALUE_PLAIN) { |
| *buf = 0; | |
| switch (vars->type) { | switch (vars->type) { |
| case ASN_BIT_STR: /* 0x03, asn1.h */ | case ASN_BIT_STR: /* 0x03, asn1.h */ |
| ZVAL_STRINGL(val, (char *)vars->val.bitstring, vars->val_len, 1); | ZVAL_STRINGL(val, (char *)vars->val.bitstring, vars->val_len, 1); |
| Line 652 static void php_snmp_getvalue(struct variable_list *va | Line 677 static void php_snmp_getvalue(struct variable_list *va |
| break; | break; |
| } | } |
| } else /* use Net-SNMP value translation */ { | } else /* use Net-SNMP value translation */ { |
| snprint_value(buf, buflen, vars->name, vars->name_length, vars); | /* we have desired string in buffer, just use it */ |
| ZVAL_STRING(val, buf, 1); | ZVAL_STRING(val, buf, 1); |
| } | } |
| Line 694 static void php_snmp_internal(INTERNAL_FUNCTION_PARAME | Line 719 static void php_snmp_internal(INTERNAL_FUNCTION_PARAME |
| zval *snmpval = NULL; | zval *snmpval = NULL; |
| int snmp_errno; | int snmp_errno; |
| /* we start with retval=FALSE. If any actual data is aquired, retval will be set to appropriate type */ | /* we start with retval=FALSE. If any actual data is acquired, retval will be set to appropriate type */ |
| RETVAL_FALSE; | RETVAL_FALSE; |
| /* reset errno and errstr */ | /* reset errno and errstr */ |
| Line 832 retry: | Line 857 retry: |
| } | } |
| } else if (st & SNMP_USE_SUFFIX_AS_KEYS && st & SNMP_CMD_WALK) { | } else if (st & SNMP_USE_SUFFIX_AS_KEYS && st & SNMP_CMD_WALK) { |
| snprint_objid(buf2, sizeof(buf2), vars->name, vars->name_length); | snprint_objid(buf2, sizeof(buf2), vars->name, vars->name_length); |
| if (objid_query->vars[0].name_length <= vars->name_length && snmp_oid_compare(objid_query->vars[0].name, objid_query->vars[0].name_length, vars->name, objid_query->vars[0].name_length) == 0) { | if (rootlen <= vars->name_length && snmp_oid_compare(root, rootlen, vars->name, rootlen) == 0) { |
| buf2[0] = '\0'; | buf2[0] = '\0'; |
| count = objid_query->vars[0].name_length; | count = rootlen; |
| while(count < vars->name_length){ | while(count < vars->name_length){ |
| sprintf(buf, "%lu.", vars->name[count]); | sprintf(buf, "%lu.", vars->name[count]); |
| strcat(buf2, buf); | strcat(buf2, buf); |
| Line 1096 static int php_snmp_parse_oid(zval *object, int st, st | Line 1121 static int php_snmp_parse_oid(zval *object, int st, st |
| static int netsnmp_session_init(php_snmp_session **session_p, int version, char *hostname, char *community, int timeout, int retries TSRMLS_DC) | static int netsnmp_session_init(php_snmp_session **session_p, int version, char *hostname, char *community, int timeout, int retries TSRMLS_DC) |
| { | { |
| php_snmp_session *session; | php_snmp_session *session; |
| char *pptr; | char *pptr, *host_ptr; |
| char buf[MAX_NAME_LEN]; | |
| int force_ipv6 = FALSE; | int force_ipv6 = FALSE; |
| int n; | int n; |
| struct sockaddr **psal; | struct sockaddr **psal; |
| Line 1111 static int netsnmp_session_init(php_snmp_session **ses | Line 1135 static int netsnmp_session_init(php_snmp_session **ses |
| } | } |
| memset(session, 0, sizeof(php_snmp_session)); | memset(session, 0, sizeof(php_snmp_session)); |
| strlcpy(buf, hostname, sizeof(buf)); | |
| snmp_sess_init(session); | snmp_sess_init(session); |
| session->version = version; | session->version = version; |
| Line 1123 static int netsnmp_session_init(php_snmp_session **ses | Line 1145 static int netsnmp_session_init(php_snmp_session **ses |
| php_error_docref(NULL TSRMLS_CC, E_WARNING, "emalloc() failed while copying hostname"); | php_error_docref(NULL TSRMLS_CC, E_WARNING, "emalloc() failed while copying hostname"); |
| return (-1); | return (-1); |
| } | } |
| *(session->peername) = '\0'; | /* we copy original hostname for further processing */ |
| strlcpy(session->peername, hostname, MAX_NAME_LEN); | |
| host_ptr = session->peername; | |
| /* Reading the hostname and its optional non-default port number */ | /* Reading the hostname and its optional non-default port number */ |
| if (*hostname == '[') { /* IPv6 address */ | if (*host_ptr == '[') { /* IPv6 address */ |
| force_ipv6 = TRUE; | force_ipv6 = TRUE; |
| hostname++; | host_ptr++; |
| if ((pptr = strchr(hostname, ']'))) { | if ((pptr = strchr(host_ptr, ']'))) { |
| if (pptr[1] == ':') { | if (pptr[1] == ':') { |
| session->remote_port = atoi(pptr + 2); | session->remote_port = atoi(pptr + 2); |
| } | } |
| *pptr = '\0'; | *pptr = '\0'; |
| } else { | } else { |
| php_error_docref(NULL TSRMLS_CC, E_WARNING, "mailformed IPv6 address, closing square bracket missing"); | php_error_docref(NULL TSRMLS_CC, E_WARNING, "malformed IPv6 address, closing square bracket missing"); |
| return (-1); | return (-1); |
| } | } |
| } else { /* IPv4 address */ | } else { /* IPv4 address */ |
| if ((pptr = strchr(hostname, ':'))) { | if ((pptr = strchr(host_ptr, ':'))) { |
| session->remote_port = atoi(pptr + 1); | session->remote_port = atoi(pptr + 1); |
| *pptr = '\0'; | *pptr = '\0'; |
| } | } |
| Line 1147 static int netsnmp_session_init(php_snmp_session **ses | Line 1171 static int netsnmp_session_init(php_snmp_session **ses |
| /* since Net-SNMP library requires 'udp6:' prefix for all IPv6 addresses (in FQDN form too) we need to | /* since Net-SNMP library requires 'udp6:' prefix for all IPv6 addresses (in FQDN form too) we need to |
| perform possible name resolution before running any SNMP queries */ | perform possible name resolution before running any SNMP queries */ |
| if ((n = php_network_getaddresses(hostname, SOCK_DGRAM, &psal, NULL TSRMLS_CC)) == 0) { /* some resover error */ | if ((n = php_network_getaddresses(host_ptr, SOCK_DGRAM, &psal, NULL TSRMLS_CC)) == 0) { /* some resolver error */ |
| /* warnings sent, bailing out */ | /* warnings sent, bailing out */ |
| return (-1); | return (-1); |
| } | } |
| /* we have everything we need in psal, flush peername and fill it properly */ | |
| *(session->peername) = '\0'; | |
| res = psal; | res = psal; |
| while (n-- > 0) { | while (n-- > 0) { |
| pptr = session->peername; | pptr = session->peername; |
| Line 1161 static int netsnmp_session_init(php_snmp_session **ses | Line 1187 static int netsnmp_session_init(php_snmp_session **ses |
| continue; | continue; |
| } | } |
| if ((*res)->sa_family == AF_INET6) { | if ((*res)->sa_family == AF_INET6) { |
| strcpy(session->peername, "udp6:"); | strcpy(session->peername, "udp6:["); |
| pptr = session->peername + strlen(session->peername); | pptr = session->peername + strlen(session->peername); |
| inet_ntop((*res)->sa_family, &(((struct sockaddr_in6*)(*res))->sin6_addr), pptr, MAX_NAME_LEN); | inet_ntop((*res)->sa_family, &(((struct sockaddr_in6*)(*res))->sin6_addr), pptr, MAX_NAME_LEN); |
| strcat(pptr, "]"); | |
| } else if ((*res)->sa_family == AF_INET) { | } else if ((*res)->sa_family == AF_INET) { |
| inet_ntop((*res)->sa_family, &(((struct sockaddr_in*)(*res))->sin_addr), pptr, MAX_NAME_LEN); | inet_ntop((*res)->sa_family, &(((struct sockaddr_in*)(*res))->sin_addr), pptr, MAX_NAME_LEN); |
| } else { | } else { |
| Line 1181 static int netsnmp_session_init(php_snmp_session **ses | Line 1208 static int netsnmp_session_init(php_snmp_session **ses |
| } | } |
| if (strlen(session->peername) == 0) { | if (strlen(session->peername) == 0) { |
| php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown failure while resolving '%s'", buf); | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown failure while resolving '%s'", hostname); |
| return (-1); | return (-1); |
| } | } |
| /* XXX FIXME | /* XXX FIXME |
| Line 1844 PHP_METHOD(snmp, close) | Line 1871 PHP_METHOD(snmp, close) |
| /* }}} */ | /* }}} */ |
| /* {{{ proto mixed SNMP::get(mixed object_id [, bool preserve_keys]) | /* {{{ proto mixed SNMP::get(mixed object_id [, bool preserve_keys]) |
| Fetch a SNMP object returing scalar for single OID and array of oid->value pairs for multi OID request */ | Fetch a SNMP object returning scalar for single OID and array of oid->value pairs for multi OID request */ |
| PHP_METHOD(snmp, get) | PHP_METHOD(snmp, get) |
| { | { |
| php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU, SNMP_CMD_GET, (-1)); | php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU, SNMP_CMD_GET, (-1)); |
| Line 1852 PHP_METHOD(snmp, get) | Line 1879 PHP_METHOD(snmp, get) |
| /* }}} */ | /* }}} */ |
| /* {{{ proto mixed SNMP::getnext(mixed object_id) | /* {{{ proto mixed SNMP::getnext(mixed object_id) |
| Fetch a SNMP object returing scalar for single OID and array of oid->value pairs for multi OID request */ | Fetch a SNMP object returning scalar for single OID and array of oid->value pairs for multi OID request */ |
| PHP_METHOD(snmp, getnext) | PHP_METHOD(snmp, getnext) |
| { | { |
| php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU, SNMP_CMD_GETNEXT, (-1)); | php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU, SNMP_CMD_GETNEXT, (-1)); |