PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - standard - dns.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 462
Code covered: 14.7 % Executed lines: 68
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: The typical suspects                                        |
      16                 :    |          Pollita <pollita@php.net>                                   |
      17                 :    |          Marcus Boerger <helly@php.net>                              |
      18                 :    +----------------------------------------------------------------------+
      19                 :  */
      20                 : 
      21                 : /* $Id: dns.c 289700 2009-10-16 16:09:49Z scottmac $ */
      22                 : 
      23                 : /* {{{ includes */
      24                 : #include "php.h"
      25                 : 
      26                 : #if HAVE_SYS_SOCKET_H
      27                 : #include <sys/socket.h>
      28                 : #endif
      29                 : 
      30                 : #ifdef PHP_WIN32
      31                 : #if HAVE_LIBBIND
      32                 : #ifndef WINNT
      33                 : #define WINNT 1
      34                 : #endif
      35                 : /* located in www.php.net/extra/bindlib.zip */
      36                 : #if HAVE_ARPA_INET_H 
      37                 : #include "arpa/inet.h"
      38                 : #endif
      39                 : #include "netdb.h"
      40                 : #if HAVE_ARPA_NAMESERV_H
      41                 : #include "arpa/nameser.h"
      42                 : #endif
      43                 : #if HAVE_RESOLV_H
      44                 : #include "resolv.h"
      45                 : #endif
      46                 : #endif /* HAVE_LIBBIND */
      47                 : #include <winsock2.h>
      48                 : #else   /* This holds good for NetWare too, both for Winsock and Berkeley sockets */
      49                 : #include <netinet/in.h>
      50                 : #if HAVE_ARPA_INET_H
      51                 : #include <arpa/inet.h>
      52                 : #endif
      53                 : #include <netdb.h>
      54                 : #ifdef _OSD_POSIX
      55                 : #undef STATUS
      56                 : #undef T_UNSPEC
      57                 : #endif
      58                 : #if HAVE_ARPA_NAMESER_COMPAT_H
      59                 : #include <arpa/nameser_compat.h>
      60                 : #endif
      61                 : #if HAVE_ARPA_NAMESER_H
      62                 : #include <arpa/nameser.h>
      63                 : #endif
      64                 : #if HAVE_RESOLV_H
      65                 : #include <resolv.h>
      66                 : #endif
      67                 : #endif
      68                 : 
      69                 : /* Borrowed from SYS/SOCKET.H */
      70                 : #if defined(NETWARE) && defined(USE_WINSOCK)
      71                 : #define AF_INET 2   /* internetwork: UDP, TCP, etc. */
      72                 : #endif
      73                 : 
      74                 : #include "php_dns.h"
      75                 : 
      76                 : /* type compat */
      77                 : #ifndef DNS_T_A
      78                 : #define DNS_T_A         1
      79                 : #endif
      80                 : #ifndef DNS_T_NS
      81                 : #define DNS_T_NS        2
      82                 : #endif
      83                 : #ifndef DNS_T_CNAME
      84                 : #define DNS_T_CNAME     5
      85                 : #endif
      86                 : #ifndef DNS_T_SOA
      87                 : #define DNS_T_SOA       6
      88                 : #endif
      89                 : #ifndef DNS_T_PTR
      90                 : #define DNS_T_PTR       12
      91                 : #endif
      92                 : #ifndef DNS_T_HINFO
      93                 : #define DNS_T_HINFO     13
      94                 : #endif
      95                 : #ifndef DNS_T_MINFO
      96                 : #define DNS_T_MINFO     14
      97                 : #endif
      98                 : #ifndef DNS_T_MX
      99                 : #define DNS_T_MX        15
     100                 : #endif
     101                 : #ifndef DNS_T_TXT
     102                 : #define DNS_T_TXT       16
     103                 : #endif
     104                 : #ifndef DNS_T_AAAA
     105                 : #define DNS_T_AAAA      28
     106                 : #endif
     107                 : #ifndef DNS_T_SRV
     108                 : #define DNS_T_SRV       33
     109                 : #endif
     110                 : #ifndef DNS_T_NAPTR
     111                 : #define DNS_T_NAPTR     35
     112                 : #endif
     113                 : #ifndef DNS_T_A6
     114                 : #define DNS_T_A6        38
     115                 : #endif
     116                 : 
     117                 : #ifndef DNS_T_ANY
     118                 : #define DNS_T_ANY       255
     119                 : #endif
     120                 : /* }}} */
     121                 : 
     122                 : static char *php_gethostbyaddr(char *ip);
     123                 : static char *php_gethostbyname(char *name);
     124                 : 
     125                 : /* {{{ proto string gethostbyaddr(string ip_address)
     126                 :    Get the Internet host name corresponding to a given IP address */
     127                 : PHP_FUNCTION(gethostbyaddr)
     128               6 : {
     129                 :         zval **arg;
     130                 :         char *addr;     
     131                 :         
     132               6 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
     133               2 :                 ZEND_WRONG_PARAM_COUNT();
     134                 :         }
     135                 : 
     136               4 :         convert_to_string_ex(arg);
     137                 :         
     138               4 :         addr = php_gethostbyaddr(Z_STRVAL_PP(arg));
     139                 : 
     140               4 :         if (addr == NULL) {
     141                 : #if HAVE_IPV6 && HAVE_INET_PTON
     142               3 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Address is not a valid IPv4 or IPv6 address");
     143                 : #else
     144                 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Address is not in a.b.c.d form");
     145                 : #endif
     146               3 :                 RETVAL_FALSE;
     147                 :         } else {
     148               1 :                 RETVAL_STRING(addr, 0);
     149                 :         }
     150                 : }
     151                 : /* }}} */
     152                 : 
     153                 : /* {{{ php_gethostbyaddr */
     154                 : static char *php_gethostbyaddr(char *ip)
     155               4 : {
     156                 : #if HAVE_IPV6 && HAVE_INET_PTON
     157                 :         struct in6_addr addr6;
     158                 : #endif
     159                 :         struct in_addr addr;
     160                 :         struct hostent *hp;
     161                 : 
     162                 : #if HAVE_IPV6 && HAVE_INET_PTON
     163               4 :         if (inet_pton(AF_INET6, ip, &addr6)) {
     164               0 :                 hp = gethostbyaddr((char *) &addr6, sizeof(addr6), AF_INET6);
     165               4 :         } else if (inet_pton(AF_INET, ip, &addr)) {
     166               1 :                 hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
     167                 :         } else {
     168               3 :                 return NULL;
     169                 :         }
     170                 : #else
     171                 :         addr.s_addr = inet_addr(ip);
     172                 : 
     173                 :         if (addr.s_addr == -1) {
     174                 :                 return NULL;
     175                 :         }
     176                 : 
     177                 :         hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
     178                 : #endif
     179                 : 
     180               1 :         if (!hp || hp->h_name == NULL || hp->h_name[0] == '\0') {
     181               0 :                 return estrdup(ip);
     182                 :         }
     183                 : 
     184               1 :         return estrdup(hp->h_name);
     185                 : }
     186                 : /* }}} */
     187                 : 
     188                 : /* {{{ proto string gethostbyname(string hostname)
     189                 :    Get the IP address corresponding to a given Internet host name */
     190                 : PHP_FUNCTION(gethostbyname)
     191               9 : {
     192                 :         zval **arg;
     193                 :         
     194               9 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
     195               1 :                 ZEND_WRONG_PARAM_COUNT();
     196                 :         }
     197                 : 
     198               8 :         convert_to_string_ex(arg);
     199                 : 
     200               8 :         RETVAL_STRING(php_gethostbyname(Z_STRVAL_PP(arg)), 0);
     201                 : }
     202                 : /* }}} */
     203                 : 
     204                 : /* {{{ proto array gethostbynamel(string hostname)
     205                 :    Return a list of IP addresses that a given hostname resolves to. */
     206                 : PHP_FUNCTION(gethostbynamel)
     207               4 : {
     208                 :         zval **arg;
     209                 :         struct hostent *hp;
     210                 :         struct in_addr in;
     211                 :         int i;
     212                 : 
     213               4 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
     214               2 :                 ZEND_WRONG_PARAM_COUNT();
     215                 :         }
     216               2 :         convert_to_string_ex(arg);
     217                 : 
     218               2 :         hp = gethostbyname(Z_STRVAL_PP(arg));
     219               2 :         if (hp == NULL || hp->h_addr_list == NULL) {
     220               1 :                 RETURN_FALSE;
     221                 :         }
     222                 : 
     223               1 :         array_init(return_value);
     224                 : 
     225               2 :         for (i = 0 ; hp->h_addr_list[i] != 0 ; i++) {
     226               1 :                 in = *(struct in_addr *) hp->h_addr_list[i];
     227               1 :                 add_next_index_string(return_value, inet_ntoa(in), 1);
     228                 :         }
     229                 : }
     230                 : /* }}} */
     231                 : 
     232                 : /* {{{ php_gethostbyname */
     233                 : static char *php_gethostbyname(char *name)
     234               8 : {
     235                 :         struct hostent *hp;
     236                 :         struct in_addr in;
     237                 : 
     238               8 :         hp = gethostbyname(name);
     239                 : 
     240               8 :         if (!hp || !*(hp->h_addr_list)) {
     241               2 :                 return estrdup(name);
     242                 :         }
     243                 : 
     244               6 :         memcpy(&in.s_addr, *(hp->h_addr_list), sizeof(in.s_addr));
     245                 : 
     246               6 :         return estrdup(inet_ntoa(in));
     247                 : }
     248                 : /* }}} */
     249                 : 
     250                 : #if HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(PHP_WIN32) || defined(NETWARE))
     251                 : 
     252                 : /* {{{ proto int dns_check_record(string host [, string type])
     253                 :    Check DNS records corresponding to a given Internet host name or IP address */
     254                 : PHP_FUNCTION(dns_check_record)
     255               2 : {
     256                 :         zval **arg1, **arg2;
     257                 :         int type, i;
     258                 : #ifndef MAXPACKET
     259                 : #define MAXPACKET  8192 /* max packet size used internally by BIND */
     260                 : #endif
     261                 :         u_char ans[MAXPACKET];
     262                 :         
     263               2 :         switch (ZEND_NUM_ARGS()) {
     264                 :                 case 1:
     265               1 :                         if (zend_get_parameters_ex(1, &arg1) == FAILURE) {
     266               0 :                                 WRONG_PARAM_COUNT;
     267                 :                         }
     268               1 :                         type = T_MX;
     269               1 :                         convert_to_string_ex(arg1);
     270                 :                         
     271               1 :                         if (Z_STRLEN_PP(arg1) == 0) {
     272               1 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Host cannot be empty");
     273               1 :                                 RETURN_FALSE;
     274                 :                         }
     275               0 :                         break;
     276                 : 
     277                 :                 case 2:
     278               1 :                         if (zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
     279               0 :                                 WRONG_PARAM_COUNT;
     280                 :                         }
     281               1 :                         convert_to_string_ex(arg1);
     282               1 :                         convert_to_string_ex(arg2);
     283                 : 
     284               1 :                         if (Z_STRLEN_PP(arg1) == 0 || Z_STRLEN_PP(arg2) == 0) {
     285               1 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Host and type cannot be empty");
     286               1 :                                 RETURN_FALSE;
     287                 :                         }
     288                 : 
     289               0 :                         if (!strcasecmp("A", Z_STRVAL_PP(arg2))) type = T_A;
     290               0 :                         else if (!strcasecmp("NS",    Z_STRVAL_PP(arg2))) type = DNS_T_NS;
     291               0 :                         else if (!strcasecmp("MX",    Z_STRVAL_PP(arg2))) type = DNS_T_MX;
     292               0 :                         else if (!strcasecmp("PTR",   Z_STRVAL_PP(arg2))) type = DNS_T_PTR;
     293               0 :                         else if (!strcasecmp("ANY",   Z_STRVAL_PP(arg2))) type = DNS_T_ANY;
     294               0 :                         else if (!strcasecmp("SOA",   Z_STRVAL_PP(arg2))) type = DNS_T_SOA;
     295               0 :                         else if (!strcasecmp("TXT",   Z_STRVAL_PP(arg2))) type = DNS_T_TXT;
     296               0 :                         else if (!strcasecmp("CNAME", Z_STRVAL_PP(arg2))) type = DNS_T_CNAME;
     297               0 :                         else if (!strcasecmp("AAAA",  Z_STRVAL_PP(arg2))) type = DNS_T_AAAA;
     298               0 :                         else if (!strcasecmp("SRV",   Z_STRVAL_PP(arg2))) type = DNS_T_SRV;
     299               0 :                         else if (!strcasecmp("NAPTR", Z_STRVAL_PP(arg2))) type = DNS_T_NAPTR;
     300               0 :                         else if (!strcasecmp("A6", Z_STRVAL_PP(arg2)))    type = DNS_T_A6;
     301                 :                         else {
     302               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type '%s' not supported", Z_STRVAL_PP(arg2));
     303               0 :                                 RETURN_FALSE;
     304                 :                         }
     305               0 :                         break;
     306                 : 
     307                 :                 default:
     308               0 :                         WRONG_PARAM_COUNT;
     309                 :         }
     310                 : 
     311               0 :         i = res_search(Z_STRVAL_PP(arg1), C_IN, type, ans, sizeof(ans));
     312                 : 
     313               0 :         if (i < 0) {
     314               0 :                 RETURN_FALSE;
     315                 :         }
     316                 : 
     317               0 :         RETURN_TRUE;
     318                 : }
     319                 : /* }}} */
     320                 : 
     321                 : #if HAVE_DNS_FUNCS
     322                 : 
     323                 : #define PHP_DNS_NUM_TYPES       12      /* Number of DNS Types Supported by PHP currently */
     324                 : 
     325                 : #define PHP_DNS_A      0x00000001
     326                 : #define PHP_DNS_NS     0x00000002
     327                 : #define PHP_DNS_CNAME  0x00000010
     328                 : #define PHP_DNS_SOA    0x00000020
     329                 : #define PHP_DNS_PTR    0x00000800
     330                 : #define PHP_DNS_HINFO  0x00001000
     331                 : #define PHP_DNS_MX     0x00004000
     332                 : #define PHP_DNS_TXT    0x00008000
     333                 : #define PHP_DNS_A6     0x01000000
     334                 : #define PHP_DNS_SRV    0x02000000
     335                 : #define PHP_DNS_NAPTR  0x04000000    
     336                 : #define PHP_DNS_AAAA   0x08000000
     337                 : #define PHP_DNS_ANY    0x10000000
     338                 : #define PHP_DNS_ALL    (PHP_DNS_A|PHP_DNS_NS|PHP_DNS_CNAME|PHP_DNS_SOA|PHP_DNS_PTR|PHP_DNS_HINFO|PHP_DNS_MX|PHP_DNS_TXT|PHP_DNS_A6|PHP_DNS_SRV|PHP_DNS_NAPTR|PHP_DNS_AAAA)
     339                 : 
     340           13565 : PHP_MINIT_FUNCTION(dns) {
     341           13565 :         REGISTER_LONG_CONSTANT("DNS_A",     PHP_DNS_A,     CONST_CS | CONST_PERSISTENT);
     342           13565 :         REGISTER_LONG_CONSTANT("DNS_NS",    PHP_DNS_NS,    CONST_CS | CONST_PERSISTENT);
     343           13565 :         REGISTER_LONG_CONSTANT("DNS_CNAME", PHP_DNS_CNAME, CONST_CS | CONST_PERSISTENT);
     344           13565 :         REGISTER_LONG_CONSTANT("DNS_SOA",   PHP_DNS_SOA,   CONST_CS | CONST_PERSISTENT);
     345           13565 :         REGISTER_LONG_CONSTANT("DNS_PTR",   PHP_DNS_PTR,   CONST_CS | CONST_PERSISTENT);
     346           13565 :         REGISTER_LONG_CONSTANT("DNS_HINFO", PHP_DNS_HINFO, CONST_CS | CONST_PERSISTENT);
     347           13565 :         REGISTER_LONG_CONSTANT("DNS_MX",    PHP_DNS_MX,    CONST_CS | CONST_PERSISTENT);
     348           13565 :         REGISTER_LONG_CONSTANT("DNS_TXT",   PHP_DNS_TXT,   CONST_CS | CONST_PERSISTENT);
     349           13565 :         REGISTER_LONG_CONSTANT("DNS_SRV",   PHP_DNS_SRV,   CONST_CS | CONST_PERSISTENT);
     350           13565 :         REGISTER_LONG_CONSTANT("DNS_NAPTR", PHP_DNS_NAPTR, CONST_CS | CONST_PERSISTENT);
     351           13565 :         REGISTER_LONG_CONSTANT("DNS_AAAA",  PHP_DNS_AAAA,  CONST_CS | CONST_PERSISTENT);
     352           13565 :         REGISTER_LONG_CONSTANT("DNS_A6",      PHP_DNS_A6,    CONST_CS | CONST_PERSISTENT);
     353           13565 :         REGISTER_LONG_CONSTANT("DNS_ANY",   PHP_DNS_ANY,   CONST_CS | CONST_PERSISTENT);
     354           13565 :         REGISTER_LONG_CONSTANT("DNS_ALL",   PHP_DNS_ALL,   CONST_CS | CONST_PERSISTENT);
     355           13565 :         return SUCCESS;
     356                 : }
     357                 : 
     358                 : #ifndef HFIXEDSZ
     359                 : #define HFIXEDSZ        12      /* fixed data in header <arpa/nameser.h> */
     360                 : #endif /* HFIXEDSZ */
     361                 : 
     362                 : #ifndef QFIXEDSZ
     363                 : #define QFIXEDSZ        4       /* fixed data in query <arpa/nameser.h> */
     364                 : #endif /* QFIXEDSZ */
     365                 : 
     366                 : #undef MAXHOSTNAMELEN
     367                 : #define MAXHOSTNAMELEN  1024
     368                 : 
     369                 : #ifndef MAXRESOURCERECORDS
     370                 : #define MAXRESOURCERECORDS      64
     371                 : #endif /* MAXRESOURCERECORDS */
     372                 : 
     373                 : typedef union {
     374                 :         HEADER qb1;
     375                 :         u_char qb2[65536];
     376                 : } querybuf;
     377                 : 
     378                 : /* just a hack to free resources allocated by glibc in __res_nsend() 
     379                 :  * See also: 
     380                 :  *   res_thread_freeres() in glibc/resolv/res_init.c 
     381                 :  *   __libc_res_nsend()   in resolv/res_send.c 
     382                 :  * */
     383                 : 
     384                 : #ifdef __GLIBC__
     385                 : #define php_dns_free_res(__res__) _php_dns_free_res(__res__)
     386               0 : static void _php_dns_free_res(struct __res_state res) { /* {{{ */
     387                 :         int ns;
     388               0 :         for (ns = 0; ns < MAXNS; ns++) {
     389               0 :                 if (res._u._ext.nsaddrs[ns] != NULL) {
     390               0 :                         free (res._u._ext.nsaddrs[ns]);
     391               0 :                         res._u._ext.nsaddrs[ns] = NULL;
     392                 :                 }
     393                 :         }
     394               0 : } /* }}} */
     395                 : #else
     396                 : #define php_dns_free_res(__res__)
     397                 : #endif
     398                 : 
     399                 : /* {{{ php_parserr */
     400                 : static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int store, zval **subarray)
     401               0 : {
     402                 :         u_short type, class, dlen;
     403                 :         u_long ttl;
     404                 :         long n, i;
     405                 :         u_short s;
     406                 :         u_char *tp, *p;
     407                 :         char name[MAXHOSTNAMELEN];
     408               0 :         int have_v6_break = 0, in_v6_break = 0;
     409                 : 
     410               0 :         *subarray = NULL;
     411                 : 
     412               0 :         n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, sizeof(name) - 2);
     413               0 :         if (n < 0) {
     414               0 :                 return NULL;
     415                 :         }
     416               0 :         cp += n;
     417                 :         
     418               0 :         GETSHORT(type, cp);
     419               0 :         GETSHORT(class, cp);
     420               0 :         GETLONG(ttl, cp);
     421               0 :         GETSHORT(dlen, cp);
     422               0 :         if (type_to_fetch != T_ANY && type != type_to_fetch) {
     423               0 :                 cp += dlen;
     424               0 :                 return cp;
     425                 :         }
     426                 : 
     427               0 :         if (!store) {
     428               0 :                 cp += dlen;
     429               0 :                 return cp;
     430                 :         }
     431                 : 
     432               0 :         ALLOC_INIT_ZVAL(*subarray);
     433               0 :         array_init(*subarray);
     434                 : 
     435               0 :         add_assoc_string(*subarray, "host", name, 1);
     436               0 :         switch (type) {
     437                 :                 case DNS_T_A:
     438               0 :                         add_assoc_string(*subarray, "type", "A", 1);
     439               0 :                         snprintf(name, sizeof(name), "%d.%d.%d.%d", cp[0], cp[1], cp[2], cp[3]);
     440               0 :                         add_assoc_string(*subarray, "ip", name, 1);
     441               0 :                         cp += dlen;
     442               0 :                         break;
     443                 :                 case DNS_T_MX:
     444               0 :                         add_assoc_string(*subarray, "type", "MX", 1);
     445               0 :                         GETSHORT(n, cp);
     446               0 :                         add_assoc_long(*subarray, "pri", n);
     447                 :                         /* no break; */
     448                 :                 case DNS_T_CNAME:
     449               0 :                         if (type == DNS_T_CNAME)
     450               0 :                                 add_assoc_string(*subarray, "type", "CNAME", 1);
     451                 :                         /* no break; */
     452                 :                 case DNS_T_NS:
     453               0 :                         if (type == DNS_T_NS)
     454               0 :                                 add_assoc_string(*subarray, "type", "NS", 1);
     455                 :                         /* no break; */
     456                 :                 case DNS_T_PTR:
     457               0 :                         if (type == DNS_T_PTR)
     458               0 :                                 add_assoc_string(*subarray, "type", "PTR", 1);
     459               0 :                         n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof name) - 2);
     460               0 :                         if (n < 0) {
     461               0 :                                 return NULL;
     462                 :                         }
     463               0 :                         cp += n;
     464               0 :                         add_assoc_string(*subarray, "target", name, 1);
     465               0 :                         break;
     466                 :                 case DNS_T_HINFO:
     467                 :                         /* See RFC 1010 for values */
     468               0 :                         add_assoc_string(*subarray, "type", "HINFO", 1);
     469               0 :                         n = *cp & 0xFF;
     470               0 :                         cp++;
     471               0 :                         add_assoc_stringl(*subarray, "cpu", cp, n, 1);
     472               0 :                         cp += n;
     473               0 :                         n = *cp & 0xFF;
     474               0 :                         cp++;
     475               0 :                         add_assoc_stringl(*subarray, "os", cp, n, 1);
     476               0 :                         cp += n;
     477               0 :                         break;
     478                 :                 case DNS_T_TXT: 
     479                 :                         {
     480               0 :                                 int ll = 0;
     481                 : 
     482               0 :                                 add_assoc_string(*subarray, "type", "TXT", 1);
     483               0 :                                 tp = emalloc(dlen + 1);
     484                 :                                 
     485               0 :                                 while (ll < dlen) {
     486               0 :                                         n = cp[ll];
     487               0 :                                         memcpy(tp + ll , cp + ll + 1, n);
     488               0 :                                         ll = ll + n + 1;
     489                 :                                 }
     490               0 :                                 tp[dlen] = '\0';
     491               0 :                                 cp += dlen;
     492                 : 
     493               0 :                                 add_assoc_stringl(*subarray, "txt", tp, dlen - 1, 0);
     494                 :                         }
     495               0 :                         break;
     496                 :                 case DNS_T_SOA:
     497               0 :                         add_assoc_string(*subarray, "type", "SOA", 1);
     498               0 :                         n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof name) -2);
     499               0 :                         if (n < 0) {
     500               0 :                                 return NULL;
     501                 :                         }
     502               0 :                         cp += n;
     503               0 :                         add_assoc_string(*subarray, "mname", name, 1);
     504               0 :                         n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof name) -2);
     505               0 :                         if (n < 0) {
     506               0 :                                 return NULL;
     507                 :                         }
     508               0 :                         cp += n;
     509               0 :                         add_assoc_string(*subarray, "rname", name, 1);
     510               0 :                         GETLONG(n, cp);
     511               0 :                         add_assoc_long(*subarray, "serial", n);
     512               0 :                         GETLONG(n, cp);
     513               0 :                         add_assoc_long(*subarray, "refresh", n);
     514               0 :                         GETLONG(n, cp);
     515               0 :                         add_assoc_long(*subarray, "retry", n);
     516               0 :                         GETLONG(n, cp);
     517               0 :                         add_assoc_long(*subarray, "expire", n);
     518               0 :                         GETLONG(n, cp);
     519               0 :                         add_assoc_long(*subarray, "minimum-ttl", n);
     520               0 :                         break;
     521                 :                 case DNS_T_AAAA:
     522               0 :                         tp = name;
     523               0 :                         for(i=0; i < 8; i++) {
     524               0 :                                 GETSHORT(s, cp);
     525               0 :                                 if (s != 0) {
     526               0 :                                         if (tp > (u_char *)name) {
     527               0 :                                                 in_v6_break = 0;
     528               0 :                                                 tp[0] = ':';
     529               0 :                                                 tp++;
     530                 :                                         }
     531               0 :                                         tp += sprintf(tp,"%x",s);
     532                 :                                 } else {
     533               0 :                                         if (!have_v6_break) {
     534               0 :                                                 have_v6_break = 1;
     535               0 :                                                 in_v6_break = 1;
     536               0 :                                                 tp[0] = ':';
     537               0 :                                                 tp++;
     538               0 :                                         } else if (!in_v6_break) {
     539               0 :                                                 tp[0] = ':';
     540               0 :                                                 tp++;
     541               0 :                                                 tp[0] = '0';
     542               0 :                                                 tp++;
     543                 :                                         }
     544                 :                                 }
     545                 :                         }
     546               0 :                         if (have_v6_break && in_v6_break) {
     547               0 :                                 tp[0] = ':';
     548               0 :                                 tp++;
     549                 :                         }
     550               0 :                         tp[0] = '\0';
     551               0 :                         add_assoc_string(*subarray, "type", "AAAA", 1);
     552               0 :                         add_assoc_string(*subarray, "ipv6", name, 1);
     553               0 :                         break; 
     554                 :                 case DNS_T_A6:
     555               0 :                         p = cp;
     556               0 :                         add_assoc_string(*subarray, "type", "A6", 1);
     557               0 :                         n = ((int)cp[0]) & 0xFF;
     558               0 :                         cp++;
     559               0 :                         add_assoc_long(*subarray, "masklen", n);
     560               0 :                         tp = name;
     561               0 :                         if (n > 15) {
     562               0 :                                 have_v6_break = 1;
     563               0 :                                 in_v6_break = 1;
     564               0 :                                 tp[0] = ':';
     565               0 :                                 tp++;
     566                 :                         }
     567               0 :                         if (n % 16 > 8) {
     568                 :                                 /* Partial short */
     569               0 :                                 if (cp[0] != 0) {
     570               0 :                                         if (tp > (u_char *)name) {
     571               0 :                                                 in_v6_break = 0;
     572               0 :                                                 tp[0] = ':';
     573               0 :                                                 tp++;
     574                 :                                         }
     575               0 :                                         sprintf(tp, "%x", cp[0] & 0xFF);
     576                 :                                 } else {
     577               0 :                                         if (!have_v6_break) {
     578               0 :                                                 have_v6_break = 1;
     579               0 :                                                 in_v6_break = 1;
     580               0 :                                                 tp[0] = ':';
     581               0 :                                                 tp++;
     582               0 :                                         } else if (!in_v6_break) {
     583               0 :                                                 tp[0] = ':';
     584               0 :                                                 tp++;
     585               0 :                                                 tp[0] = '0';
     586               0 :                                                 tp++;
     587                 :                                         }
     588                 :                                 }
     589               0 :                                 cp++;
     590                 :                         }
     591               0 :                         for(i = (n+8)/16; i < 8; i++) {
     592               0 :                                 GETSHORT(s, cp);
     593               0 :                                 if (s != 0) {
     594               0 :                                         if (tp > (u_char *)name) {
     595               0 :                                                 in_v6_break = 0;
     596               0 :                                                 tp[0] = ':';
     597               0 :                                                 tp++;
     598                 :                                         }
     599               0 :                                         tp += sprintf(tp,"%x",s);
     600                 :                                 } else {
     601               0 :                                         if (!have_v6_break) {
     602               0 :                                                 have_v6_break = 1;
     603               0 :                                                 in_v6_break = 1;
     604               0 :                                                 tp[0] = ':';
     605               0 :                                                 tp++;
     606               0 :                                         } else if (!in_v6_break) {
     607               0 :                                                 tp[0] = ':';
     608               0 :                                                 tp++;
     609               0 :                                                 tp[0] = '0';
     610               0 :                                                 tp++;
     611                 :                                         }
     612                 :                                 }
     613                 :                         }
     614               0 :                         if (have_v6_break && in_v6_break) {
     615               0 :                                 tp[0] = ':';
     616               0 :                                 tp++;
     617                 :                         }
     618               0 :                         tp[0] = '\0';
     619               0 :                         add_assoc_string(*subarray, "ipv6", name, 1);
     620               0 :                         if (cp < p + dlen) {
     621               0 :                                 n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof name) - 2);
     622               0 :                                 if (n < 0) {
     623               0 :                                         return NULL;
     624                 :                                 }
     625               0 :                                 cp += n;
     626               0 :                                 add_assoc_string(*subarray, "chain", name, 1);
     627                 :                         }
     628               0 :                         break;
     629                 :                 case DNS_T_SRV:
     630               0 :                         add_assoc_string(*subarray, "type", "SRV", 1);
     631               0 :                         GETSHORT(n, cp);
     632               0 :                         add_assoc_long(*subarray, "pri", n);
     633               0 :                         GETSHORT(n, cp);
     634               0 :                         add_assoc_long(*subarray, "weight", n);
     635               0 :                         GETSHORT(n, cp);
     636               0 :                         add_assoc_long(*subarray, "port", n);
     637               0 :                         n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof name) - 2);
     638               0 :                         if (n < 0) {
     639               0 :                                 return NULL;
     640                 :                         }
     641               0 :                         cp += n;
     642               0 :                         add_assoc_string(*subarray, "target", name, 1);
     643               0 :                         break;
     644                 :                 case DNS_T_NAPTR:
     645               0 :                         add_assoc_string(*subarray, "type", "NAPTR", 1);
     646               0 :                         GETSHORT(n, cp);
     647               0 :                         add_assoc_long(*subarray, "order", n);
     648               0 :                         GETSHORT(n, cp);
     649               0 :                         add_assoc_long(*subarray, "pref", n);
     650               0 :                         n = (cp[0] & 0xFF);
     651               0 :                         add_assoc_stringl(*subarray, "flags", ++cp, n, 1);
     652               0 :                         cp += n;
     653               0 :                         n = (cp[0] & 0xFF);
     654               0 :                         add_assoc_stringl(*subarray, "services", ++cp, n, 1);
     655               0 :                         cp += n;
     656               0 :                         n = (cp[0] & 0xFF);
     657               0 :                         add_assoc_stringl(*subarray, "regex", ++cp, n, 1);
     658               0 :                         cp += n;
     659               0 :                         n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof name) - 2);
     660               0 :                         if (n < 0) {
     661               0 :                                 return NULL;
     662                 :                         }
     663               0 :                         cp += n;
     664               0 :                         add_assoc_string(*subarray, "replacement", name, 1);
     665               0 :                         break;
     666                 :                 default:
     667               0 :                         cp += dlen;
     668                 :         }
     669                 : 
     670               0 :         add_assoc_string(*subarray, "class", "IN", 1);
     671               0 :         add_assoc_long(*subarray, "ttl", ttl);
     672                 : 
     673               0 :         return cp;
     674                 : }
     675                 : /* }}} */
     676                 : 
     677                 : /* {{{ proto array|false dns_get_record(string hostname [, int type[, array authns, array addtl]])
     678                 :    Get any Resource Record corresponding to a given Internet host name */
     679                 : PHP_FUNCTION(dns_get_record)
     680               0 : {
     681                 :         zval *addtl, *host, *authns, *fetch_type;
     682               0 :         int addtl_recs = 0;
     683               0 :         int type_to_fetch, type_param = PHP_DNS_ANY;
     684                 :         struct __res_state res;
     685                 :         HEADER *hp;
     686                 :         querybuf buf, answer;
     687               0 :         u_char *cp = NULL, *end = NULL;
     688               0 :         int n, qd, an, ns = 0, ar = 0;
     689               0 :         int type, first_query = 1, store_results = 1;
     690                 : 
     691               0 :         switch (ZEND_NUM_ARGS()) {
     692                 :                 case 1:
     693               0 :                         if (zend_get_parameters(ht, 1, &host) == FAILURE) {
     694               0 :                                 WRONG_PARAM_COUNT;
     695                 :                         }
     696               0 :                         break;
     697                 :                 case 2:
     698               0 :                         if (zend_get_parameters(ht, 2, &host, &fetch_type) == FAILURE) {
     699               0 :                                 WRONG_PARAM_COUNT;
     700                 :                         }
     701               0 :                         convert_to_long(fetch_type);
     702               0 :                         type_param = Z_LVAL_P(fetch_type);
     703               0 :                         break;
     704                 :                 case 4:
     705               0 :                         if (zend_get_parameters(ht, 4, &host, &fetch_type, &authns, &addtl) == FAILURE) {
     706               0 :                                 WRONG_PARAM_COUNT;
     707                 :                         }
     708               0 :                         convert_to_long(fetch_type);
     709               0 :                         type_param = Z_LVAL_P(fetch_type);
     710               0 :                         zval_dtor(authns);
     711               0 :                         addtl_recs = 1;         /* We want the additional Records */
     712               0 :                         array_init(authns);
     713               0 :                         zval_dtor(addtl);
     714               0 :                         array_init(addtl);
     715               0 :                         break;
     716                 :                 default:
     717               0 :                         WRONG_PARAM_COUNT;
     718                 :         }
     719                 :         
     720               0 :         convert_to_string(host);
     721                 : 
     722               0 :         if (type_param&~PHP_DNS_ALL && type_param!=PHP_DNS_ANY) {
     723               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type '%d' not supported", type_param);
     724               0 :                 RETURN_FALSE;
     725                 :         }
     726                 : 
     727                 :         /* Initialize the return array */
     728               0 :         array_init(return_value);
     729                 : 
     730                 :         /* - We emulate an or'ed type mask by querying type by type. (Steps 0 - NUMTYPES-1 )
     731                 :          *   If additional info is wanted we check again with DNS_T_ANY (step NUMTYPES / NUMTYPES+1 )
     732                 :          *   store_results is used to skip storing the results retrieved in step
     733                 :          *   NUMTYPES+1 when results were already fetched.
     734                 :          * - In case of PHP_DNS_ANY we use the directly fetch DNS_T_ANY. (step NUMTYPES+1 )
     735                 :          */
     736               0 :         for(type = (type_param==PHP_DNS_ANY ? (PHP_DNS_NUM_TYPES + 1) : 0); type < (addtl_recs ? (PHP_DNS_NUM_TYPES + 2) : PHP_DNS_NUM_TYPES) || first_query; type++)
     737                 :         {
     738               0 :                 first_query = 0;
     739               0 :                 switch (type) {
     740                 :                         case 0: 
     741               0 :                                 type_to_fetch = type_param&PHP_DNS_A     ? DNS_T_A     : 0;
     742               0 :                                 break;
     743                 :                         case 1: 
     744               0 :                                 type_to_fetch = type_param&PHP_DNS_NS    ? DNS_T_NS    : 0;
     745               0 :                                 break;
     746                 :                         case 2: 
     747               0 :                                 type_to_fetch = type_param&PHP_DNS_CNAME ? DNS_T_CNAME : 0;
     748               0 :                                 break;
     749                 :                         case 3: 
     750               0 :                                 type_to_fetch = type_param&PHP_DNS_SOA   ? DNS_T_SOA   : 0;
     751               0 :                                 break;
     752                 :                         case 4: 
     753               0 :                                 type_to_fetch = type_param&PHP_DNS_PTR   ? DNS_T_PTR   : 0;
     754               0 :                                 break;
     755                 :                         case 5: 
     756               0 :                                 type_to_fetch = type_param&PHP_DNS_HINFO ? DNS_T_HINFO : 0;
     757               0 :                                 break;
     758                 :                         case 6: 
     759               0 :                                 type_to_fetch = type_param&PHP_DNS_MX    ? DNS_T_MX    : 0;
     760               0 :                                 break;
     761                 :                         case 7: 
     762               0 :                                 type_to_fetch = type_param&PHP_DNS_TXT   ? DNS_T_TXT   : 0;
     763               0 :                                 break;
     764                 :                         case 8:
     765               0 :                                 type_to_fetch = type_param&PHP_DNS_AAAA      ? DNS_T_AAAA  : 0;
     766               0 :                                 break;
     767                 :                         case 9:
     768               0 :                                 type_to_fetch = type_param&PHP_DNS_SRV   ? DNS_T_SRV   : 0;
     769               0 :                                 break;
     770                 :                         case 10:
     771               0 :                                 type_to_fetch = type_param&PHP_DNS_NAPTR ? DNS_T_NAPTR : 0;
     772               0 :                                 break;
     773                 :                         case 11:
     774               0 :                                 type_to_fetch = type_param&PHP_DNS_A6        ? DNS_T_A6 : 0;
     775               0 :                                 break;
     776                 :                         case PHP_DNS_NUM_TYPES:
     777               0 :                                 store_results = 0;
     778               0 :                                 continue;
     779                 :                         default:
     780                 :                         case (PHP_DNS_NUM_TYPES + 1):
     781               0 :                                 type_to_fetch = DNS_T_ANY;
     782                 :                                 break;
     783                 :                 }
     784               0 :                 if (type_to_fetch) {
     785               0 :                         memset(&res, 0, sizeof(res));
     786               0 :                         res_ninit(&res);
     787               0 :                         res.retrans = 5;
     788               0 :                         res.options &= ~RES_DEFNAMES;
     789                 :                 
     790               0 :                         n = res_nmkquery(&res, QUERY, Z_STRVAL_P(host), C_IN, type_to_fetch, NULL, 0, NULL, buf.qb2, sizeof buf);
     791               0 :                         if (n<0) {
     792               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "res_nmkquery() failed");
     793               0 :                                 zval_dtor(return_value);
     794               0 :                                 res_nclose(&res);
     795               0 :                                 php_dns_free_res(res);
     796               0 :                                 RETURN_FALSE;
     797                 :                         }
     798               0 :                         n = res_nsend(&res, buf.qb2, n, answer.qb2, sizeof answer);
     799               0 :                         if (n<0) {
     800               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "res_nsend() failed");
     801               0 :                                 zval_dtor(return_value);
     802               0 :                                 res_nclose(&res);
     803               0 :                                 php_dns_free_res(res);
     804               0 :                                 RETURN_FALSE;
     805                 :                         }
     806                 :                 
     807               0 :                         cp = answer.qb2 + HFIXEDSZ;
     808               0 :                         end = answer.qb2 + n;
     809               0 :                         hp = (HEADER *)&answer;
     810               0 :                         qd = ntohs(hp->qdcount);
     811               0 :                         an = ntohs(hp->ancount);
     812               0 :                         ns = ntohs(hp->nscount);
     813               0 :                         ar = ntohs(hp->arcount);
     814                 :         
     815                 :                         /* Skip QD entries, they're only used by dn_expand later on */
     816               0 :                         while (qd-- > 0) {
     817               0 :                                 n = dn_skipname(cp, end);
     818               0 :                                 if (n < 0) {
     819               0 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse DNS data received");
     820               0 :                                         zval_dtor(return_value);
     821               0 :                                         res_nclose(&res);
     822               0 :                                         php_dns_free_res(res);
     823               0 :                                         RETURN_FALSE;
     824                 :                                 }
     825               0 :                                 cp += n + QFIXEDSZ;
     826                 :                         }
     827                 :                 
     828                 :                         /* YAY! Our real answers! */
     829               0 :                         while (an-- && cp && cp < end) {
     830                 :                                 zval *retval;
     831                 : 
     832               0 :                                 cp = php_parserr(cp, &answer, type_to_fetch, store_results, &retval);
     833               0 :                                 if (retval != NULL && store_results) {
     834               0 :                                         add_next_index_zval(return_value, retval);
     835                 :                                 }
     836                 :                         }
     837               0 :                         res_nclose(&res);
     838               0 :                         php_dns_free_res(res);
     839                 :                 }
     840                 :         }
     841                 : 
     842               0 :         if (addtl_recs) {
     843                 :                 /* List of Authoritative Name Servers */
     844               0 :                 while (ns-- > 0 && cp && cp < end) {
     845                 :                         zval *retval;
     846                 : 
     847               0 :                         cp = php_parserr(cp, &answer, DNS_T_ANY, 1, &retval);
     848               0 :                         if (retval != NULL) {
     849               0 :                                 add_next_index_zval(authns, retval);
     850                 :                         }
     851                 :                 }
     852                 :                 /* Additional records associated with authoritative name servers */
     853               0 :                 while (ar-- > 0 && cp && cp < end) {
     854                 :                         zval *retval;
     855                 : 
     856               0 :                         cp = php_parserr(cp, &answer, DNS_T_ANY, 1, &retval);
     857               0 :                         if (retval != NULL) {
     858               0 :                                 add_next_index_zval(addtl, retval);
     859                 :                         }
     860                 :                 }
     861                 :         }
     862                 : }
     863                 : /* }}} */
     864                 : #endif /* HAVE_DNS_FUNCS */
     865                 : 
     866                 : #if HAVE_DN_SKIPNAME && HAVE_DN_EXPAND
     867                 : /* {{{ proto bool dns_get_mx(string hostname, array mxhosts [, array weight])
     868                 :    Get MX records corresponding to a given Internet host name */
     869                 : PHP_FUNCTION(dns_get_mx)
     870               0 : {
     871                 :         zval *host, *mx_list, *weight_list;
     872               0 :         int need_weight = 0;
     873                 :         int count, qdc;
     874                 :         u_short type, weight;
     875                 :         u_char ans[MAXPACKET];
     876                 :         char buf[MAXHOSTNAMELEN];
     877                 :         HEADER *hp;
     878                 :         u_char *cp, *end;
     879                 :         int i;
     880                 : 
     881               0 :         switch (ZEND_NUM_ARGS()) {
     882                 :                 case 2:
     883               0 :                         if (zend_get_parameters(ht, 2, &host, &mx_list) == FAILURE) {
     884               0 :                                 WRONG_PARAM_COUNT;
     885                 :                         }
     886               0 :                         break;
     887                 : 
     888                 :                 case 3:
     889               0 :                         if (zend_get_parameters(ht, 3, &host, &mx_list, &weight_list) == FAILURE) {
     890               0 :                                 WRONG_PARAM_COUNT;
     891                 :                         }
     892               0 :                         need_weight = 1;
     893               0 :                         zval_dtor(weight_list); /* start with clean array */
     894               0 :                         array_init(weight_list);
     895               0 :                         break;
     896                 : 
     897                 :                 default:
     898               0 :                         WRONG_PARAM_COUNT;
     899                 :         }
     900                 : 
     901               0 :         convert_to_string(host);
     902               0 :         zval_dtor(mx_list); /* start with clean array */
     903               0 :         array_init(mx_list);
     904                 : 
     905                 :         /* Go! */
     906               0 :         i = res_search(Z_STRVAL_P(host), C_IN, DNS_T_MX, (u_char *)&ans, sizeof(ans));
     907               0 :         if (i < 0) {
     908               0 :                 RETURN_FALSE;
     909                 :         }
     910               0 :         if (i > (int)sizeof(ans)) {
     911               0 :                 i = sizeof(ans);
     912                 :         }
     913               0 :         hp = (HEADER *)&ans;
     914               0 :         cp = (u_char *)&ans + HFIXEDSZ;
     915               0 :         end = (u_char *)&ans +i;
     916               0 :         for (qdc = ntohs((unsigned short)hp->qdcount); qdc--; cp += i + QFIXEDSZ) {
     917               0 :                 if ((i = dn_skipname(cp, end)) < 0 ) {
     918               0 :                         RETURN_FALSE;
     919                 :                 }
     920                 :         }
     921               0 :         count = ntohs((unsigned short)hp->ancount);
     922               0 :         while (--count >= 0 && cp < end) {
     923               0 :                 if ((i = dn_skipname(cp, end)) < 0 ) {
     924               0 :                         RETURN_FALSE;
     925                 :                 }
     926               0 :                 cp += i;
     927               0 :                 GETSHORT(type, cp);
     928               0 :                 cp += INT16SZ + INT32SZ;
     929               0 :                 GETSHORT(i, cp);
     930               0 :                 if (type != DNS_T_MX) {
     931               0 :                         cp += i;
     932               0 :                         continue;
     933                 :                 }
     934               0 :                 GETSHORT(weight, cp);
     935               0 :                 if ((i = dn_expand(ans, end, cp, buf, sizeof(buf)-1)) < 0) {
     936               0 :                         RETURN_FALSE;
     937                 :                 }
     938               0 :                 cp += i;
     939               0 :                 add_next_index_string(mx_list, buf, 1);
     940               0 :                 if (need_weight) {
     941               0 :                         add_next_index_long(weight_list, weight);
     942                 :                 }
     943                 :         }
     944               0 :         RETURN_TRUE;
     945                 : }
     946                 : /* }}} */
     947                 : #endif /* HAVE_DN_SKIPNAME && HAVE_DN_EXPAND */
     948                 : 
     949                 : #endif /* HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(PHP_WIN32) || defined(NETWARE)) */
     950                 : 
     951                 : /*
     952                 :  * Local variables:
     953                 :  * tab-width: 4
     954                 :  * c-basic-offset: 4
     955                 :  * End:
     956                 :  * vim600: sw=4 ts=4 fdm=marker
     957                 :  * vim<600: sw=4 ts=4
     958                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:23 +0000 (5 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.