"raw mode". In this mide, $type (2nd parameter) is the numeric type of the record, and
the responses are not parsed -- the "type" element will be numeric and there will be
a "data" element with the raw data of the response buffer, which the programmer will
have to parse.
- Fixed bug in the Win32 implementation of dns_get_record, where the 3rd and 4th arguments
would only be filled if the 2nd ($type) was DNS_ANY.
- [DOC] The 3rd and 4th parameters can now be NULL (changed their arginfo).
ZEND_END_ARG_INFO()
# if defined(PHP_WIN32) || HAVE_FULL_DNS_FUNCS
-ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_record, 1, 0, 1)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_record, 0, 0, 1)
ZEND_ARG_INFO(0, hostname)
ZEND_ARG_INFO(0, type)
- ZEND_ARG_INFO(1, authns) /* ARRAY_INFO(1, authns, 1) */
- ZEND_ARG_INFO(1, addtl) /* ARRAY_INFO(1, addtl, 1) */
+ ZEND_ARG_ARRAY_INFO(1, authns, 1)
+ ZEND_ARG_ARRAY_INFO(1, addtl, 1)
+ ZEND_ARG_INFO(0, raw)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_mx, 0, 0, 2)
#if HAVE_FULL_DNS_FUNCS
/* {{{ php_parserr */
-static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int store, zval **subarray)
+static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int store, int raw, zval **subarray)
{
u_short type, class, dlen;
u_long ttl;
array_init(*subarray);
add_assoc_string(*subarray, "host", name, 1);
+ add_assoc_string(*subarray, "class", "IN", 1);
+ add_assoc_long(*subarray, "ttl", ttl);
+
+ if (raw) {
+ add_assoc_long(*subarray, "type", type);
+ add_assoc_stringl(*subarray, "data", (char*) cp, (uint) dlen, 1);
+ cp += dlen;
+ return cp;
+ }
+
switch (type) {
case DNS_T_A:
add_assoc_string(*subarray, "type", "A", 1);
add_assoc_string(*subarray, "replacement", name, 1);
break;
default:
- {
- char buf[10]; /* max length of short + sizeof(id #) */
- snprintf(buf, 10, "id #%hu", type);
- buf[10-1] = '\0';
- add_assoc_string(*subarray, "type", buf, 1);
- add_assoc_stringl(*subarray, "data", (char*) cp, (uint) dlen, 1);
- cp += dlen;
- break;
- }
+ zval_ptr_dtor(subarray);
+ *subarray = NULL;
+ cp += dlen;
+ break;
}
- add_assoc_string(*subarray, "class", "IN", 1);
- add_assoc_long(*subarray, "ttl", ttl);
-
return cp;
}
/* }}} */
u_char *cp = NULL, *end = NULL;
int n, qd, an, ns = 0, ar = 0;
int type, first_query = 1, store_results = 1;
+ zend_bool raw = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lzz", &hostname, &hostname_len, &type_param, &authns, &addtl) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz!z!b",
+ &hostname, &hostname_len, &type_param, &authns, &addtl, &raw) == FAILURE) {
return;
}
addtl_recs = 1;
}
- if (type_param & ~PHP_DNS_ALL && type_param != PHP_DNS_ANY) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type '%ld' not supported", type_param);
- RETURN_FALSE;
+ if (!raw) {
+ if ((type_param & ~PHP_DNS_ALL) && (type_param != PHP_DNS_ANY)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type '%ld' not supported", type_param);
+ RETURN_FALSE;
+ }
+ } else {
+ if ((type_param < 1) || (type_param > 0xFFFF)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Numeric DNS record type must be between 1 and 65535, '%ld' given", type_param);
+ RETURN_FALSE;
+ }
}
/* Initialize the return array */
* store_results is used to skip storing the results retrieved in step
* NUMTYPES+1 when results were already fetched.
* - In case of PHP_DNS_ANY we use the directly fetch DNS_T_ANY. (step NUMTYPES+1 )
+ * - In case of raw mode, we query only the requestd type instead of looping type by type
+ * before going with the additional info stuff.
*/
- for (type = (type_param == PHP_DNS_ANY ? (PHP_DNS_NUM_TYPES + 1) : 0);
+
+ if (raw) {
+ type = -1;
+ } else if (type_param == PHP_DNS_ANY) {
+ type = PHP_DNS_NUM_TYPES + 1;
+ } else {
+ type = 0;
+ }
+
+ for ( ;
type < (addtl_recs ? (PHP_DNS_NUM_TYPES + 2) : PHP_DNS_NUM_TYPES) || first_query;
type++
) {
first_query = 0;
switch (type) {
+ case -1: /* raw */
+ type_to_fetch = type_param;
+ /* skip over the rest and go directly to additional records */
+ type = PHP_DNS_NUM_TYPES - 1;
+ break;
case 0:
type_to_fetch = type_param&PHP_DNS_A ? DNS_T_A : 0;
break;
while (an-- && cp && cp < end) {
zval *retval;
- cp = php_parserr(cp, &answer, type_to_fetch, store_results, &retval);
+ cp = php_parserr(cp, &answer, type_to_fetch, store_results, raw, &retval);
if (retval != NULL && store_results) {
add_next_index_zval(return_value, retval);
}
while (ns-- > 0 && cp && cp < end) {
zval *retval = NULL;
- cp = php_parserr(cp, &answer, DNS_T_ANY, authns != NULL, &retval);
+ cp = php_parserr(cp, &answer, DNS_T_ANY, authns != NULL, raw, &retval);
if (retval != NULL) {
add_next_index_zval(authns, retval);
}
while (ar-- > 0 && cp && cp < end) {
zval *retval = NULL;
- cp = php_parserr(cp, &answer, DNS_T_ANY, 1, &retval);
+ cp = php_parserr(cp, &answer, DNS_T_ANY, 1, raw, &retval);
if (retval != NULL) {
add_next_index_zval(addtl, retval);
}
/* }}} */
/* {{{ php_parserr */
-static void php_parserr(PDNS_RECORD pRec, int type_to_fetch, int store, zval **subarray)
+static void php_parserr(PDNS_RECORD pRec, int type_to_fetch, int store, int raw, zval **subarray)
{
int type;
u_long ttl;
array_init(*subarray);
add_assoc_string(*subarray, "host", pRec->pName, 1);
+ add_assoc_string(*subarray, "class", "IN", 1);
+ add_assoc_long(*subarray, "ttl", ttl);
+
+ if (raw) {
+ add_assoc_long(*subarray, "type", type);
+ add_assoc_stringl(*subarray, "data", (char*) &pRec->Data, (uint) pRec->wDataLength, 1);
+ return;
+ }
+
switch (type) {
case DNS_TYPE_A: {
IN_ADDR ipaddr;
}
break;
+#if _MSC_VER >= 1500
case DNS_TYPE_NAPTR:
{
-#if _MSC_VER >= 1500
DNS_NAPTR_DATA * data_naptr = &pRec->Data.Naptr;
add_assoc_string(*subarray, "type", "NAPTR", 1);
add_assoc_string(*subarray, "services", data_naptr->pService, 1);
add_assoc_string(*subarray, "regex", data_naptr->pRegularExpression, 1);
add_assoc_string(*subarray, "replacement", data_naptr->pReplacement, 1);
-#endif
}
break;
+#endif
default:
- {
- char buf[10]; /* max length of short + sizeof(id #) */
- snprintf(buf, 10, "id #%hu", (unsigned short) type);
- buf[10-1] = '\0';
- add_assoc_string(*subarray, "type", buf, 1);
- add_assoc_stringl(*subarray, "data", (char*) &pRec->Data, (uint) pRec->wDataLength, 1);
- break;
- }
+ /* unkown type */
+ zval_ptr_dtor(subarray);
+ *subarray = NULL;
+ return;
}
- add_assoc_string(*subarray, "class", "IN", 1);
- add_assoc_long(*subarray, "ttl", ttl);
}
/* }}} */
zval *authns = NULL, *addtl = NULL;
int type, type_to_fetch, first_query = 1, store_results = 1;
int addtl_recs = 0;
+ zend_bool raw = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lzz", &hostname, &hostname_len, &type_param, &authns, &addtl) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz!z!b",
+ &hostname, &hostname_len, &type_param, &authns, &addtl, &raw) == FAILURE) {
return;
}
if (addtl) {
zval_dtor(addtl);
array_init(addtl);
+ addtl_recs = 1;
}
- if (type_param & ~PHP_DNS_ALL && type_param != PHP_DNS_ANY) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type '%ld' not supported", type_param);
- RETURN_FALSE;
+ if (!raw) {
+ if ((type_param & ~PHP_DNS_ALL) && (type_param != PHP_DNS_ANY)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type '%ld' not supported", type_param);
+ RETURN_FALSE;
+ }
+ } else {
+ if ((type_param < 1) || (type_param > 0xFFFF)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Numeric DNS record type must be between 1 and 65535, '%ld' given", type_param);
+ RETURN_FALSE;
+ }
}
/* Initialize the return array */
array_init(return_value);
- for (type = (type_param == PHP_DNS_ANY ? (PHP_DNS_NUM_TYPES + 1) : 0);
+ if (raw) {
+ type = -1;
+ } else if (type_param == PHP_DNS_ANY) {
+ type = PHP_DNS_NUM_TYPES + 1;
+ } else {
+ type = 0;
+ }
+
+ for ( ;
type < (addtl_recs ? (PHP_DNS_NUM_TYPES + 2) : PHP_DNS_NUM_TYPES) || first_query;
type++
) {
first_query = 0;
switch (type) {
+ case -1: /* raw */
+ type_to_fetch = type_param;
+ /* skip over the rest and go directly to additional records */
+ type = PHP_DNS_NUM_TYPES - 1;
+ break;
case 0:
type_to_fetch = type_param&PHP_DNS_A ? DNS_TYPE_A : 0;
break;
zval *retval = NULL;
if (pRec->Flags.S.Section == DnsSectionAnswer) {
- php_parserr(pRec, type_to_fetch, store_results, &retval);
+ php_parserr(pRec, type_to_fetch, store_results, raw, &retval);
if (retval != NULL && store_results) {
add_next_index_zval(return_value, retval);
}
if (authns && pRec->Flags.S.Section == DnsSectionAuthority) {
- php_parserr(pRec, type_to_fetch, store_results, &retval);
+ php_parserr(pRec, type_to_fetch, 1, raw, &retval);
if (retval != NULL) {
add_next_index_zval(authns, retval);
}
# endif
#endif
if (addtl && pRec->Flags.S.Section == DnsSectionAdditional) {
- php_parserr(pRec, type_to_fetch, store_results, &retval);
+ php_parserr(pRec, type_to_fetch, 1, raw, &retval);
if (retval != NULL) {
add_next_index_zval(addtl, retval);
}