Diff for /embedaddon/php/ext/snmp/snmp.c between versions 1.1.1.2 and 1.1.1.5

version 1.1.1.2, 2012/05/29 12:34:42 version 1.1.1.5, 2014/06/15 20:03:55
Line 2 Line 2
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | PHP Version 5                                                        |     | PHP Version 5                                                        |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
   | Copyright (c) 1997-2012 The PHP Group                                |   | Copyright (c) 1997-2014 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 514  static zend_object_value php_snmp_object_new(zend_clas Line 514  static zend_object_value php_snmp_object_new(zend_clas
 static void php_snmp_error(zval *object, const char *docref TSRMLS_DC, int type, const char *format, ...)  static void php_snmp_error(zval *object, const char *docref TSRMLS_DC, int type, const char *format, ...)
 {  {
         va_list args;          va_list args;
        php_snmp_object *snmp_object;        php_snmp_object *snmp_object = NULL;
   
         if (object) {          if (object) {
                 snmp_object = (php_snmp_object *)zend_object_store_get_object(object TSRMLS_CC);                  snmp_object = (php_snmp_object *)zend_object_store_get_object(object TSRMLS_CC);
Line 533  static void php_snmp_error(zval *object, const char *d Line 533  static void php_snmp_error(zval *object, const char *d
         }          }
   
         if (object && (snmp_object->exceptions_enabled & type)) {          if (object && (snmp_object->exceptions_enabled & type)) {
                zend_throw_exception_ex(php_snmp_exception_ce, type, snmp_object->snmp_errstr TSRMLS_CC);                zend_throw_exception_ex(php_snmp_exception_ce, type TSRMLS_CC, snmp_object->snmp_errstr);
         } else {          } else {
                 va_start(args, format);                  va_start(args, format);
                 php_verror(docref, "", E_WARNING, format, args TSRMLS_CC);                  php_verror(docref, "", E_WARNING, format, args TSRMLS_CC);
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 871  retry: Line 896  retry:
                                         keepwalking = 1;                                          keepwalking = 1;
                                 }                                  }
                         } else {                          } else {
                                   if (st & SNMP_CMD_WALK && response->errstat == SNMP_ERR_TOOBIG && objid_query->max_repetitions > 1) { /* Answer will not fit into single packet */
                                           objid_query->max_repetitions /= 2;
                                           snmp_free_pdu(response);
                                           keepwalking = 1;
                                           continue;
                                   }
                                 if (!(st & SNMP_CMD_WALK) || response->errstat != SNMP_ERR_NOSUCHNAME || Z_TYPE_P(return_value) == IS_BOOL) {                                  if (!(st & SNMP_CMD_WALK) || response->errstat != SNMP_ERR_NOSUCHNAME || Z_TYPE_P(return_value) == IS_BOOL) {
                                         for (   count=1, vars = response->variables;                                          for (   count=1, vars = response->variables;
                                                 vars && count != response->errindex;                                                  vars && count != response->errindex;
Line 1096  static int php_snmp_parse_oid(zval *object, int st, st Line 1127  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 1141  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 1151  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 1177  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 1193  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 1214  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 1877  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 1885  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));

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.5


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>