Skip to content

Commit 687ac23

Browse files
committed
Prefer AF_INET results on IPv4-only systems per @thomasvincent suggestion.
On IPv4-only systems, getaddrinfo() can still return AF_INET6 mapped addresses (e.g. ::ffff:127.0.0.1). The code would format these as udp6:[addr] peername that Net-SNMP cannot connect to. When IPv6 is not explicitly requested (no bracket notation), prefer AF_INET results. If no suitable address is found, fall back to the original hostname and let Net-SNMP resolve it itself, matching the behavior of snmprealwalk and other Net-SNMP CLI tools.
1 parent e7dcd6a commit 687ac23

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

ext/snmp/snmp.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,10 @@ static bool netsnmp_session_init(php_snmp_session **session_p, int version, zend
886886
return false;
887887
}
888888

889+
/* Save hostname before clearing peername, since host_ptr may point into the same buffer */
890+
char saved_hostname[MAX_NAME_LEN];
891+
strlcpy(saved_hostname, host_ptr, MAX_NAME_LEN);
892+
889893
/* we have everything we need in psal, flush peername and fill it properly */
890894
*(session->peername) = '\0';
891895
res = psal;
@@ -896,6 +900,13 @@ static bool netsnmp_session_init(php_snmp_session **session_p, int version, zend
896900
res++;
897901
continue;
898902
}
903+
/* When IPv6 is not explicitly requested, prefer IPv4 results to avoid
904+
issues on systems where getaddrinfo() returns AF_INET6 mapped addresses
905+
but IPv6 networking is not actually available */
906+
if (!force_ipv6 && (*res)->sa_family == AF_INET6) {
907+
res++;
908+
continue;
909+
}
899910
if ((*res)->sa_family == AF_INET6) {
900911
if (inet_ntop((*res)->sa_family, &(((struct sockaddr_in6*)(*res))->sin6_addr), name, sizeof(name))) {
901912
snprintf(pptr, MAX_NAME_LEN, "udp6:[%s]", name);
@@ -910,13 +921,11 @@ static bool netsnmp_session_init(php_snmp_session **session_p, int version, zend
910921
break;
911922
}
912923

913-
if (strlen(session->peername) == 0) {
914-
php_error_docref(NULL, E_WARNING, "Unknown failure while resolving '%s'", ZSTR_VAL(hostname));
915-
return false;
924+
/* If no suitable address was found, fall back to the original hostname
925+
and let Net-SNMP resolve it (matches behavior of snmprealwalk et al.) */
926+
if (session->peername[0] == '\0') {
927+
strlcpy(session->peername, saved_hostname, MAX_NAME_LEN);
916928
}
917-
/* XXX FIXME
918-
There should be check for non-empty session->peername!
919-
*/
920929

921930
/* put back non-standard SNMP port */
922931
if (remote_port != SNMP_PORT) {

0 commit comments

Comments
 (0)