package Socket;
our($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
-$VERSION = "1.81";
+$VERSION = "1.90";
=head1 NAME
-Socket, sockaddr_in, sockaddr_un, inet_aton, inet_ntoa - load the C socket.h defines and structure manipulators
+Socket, sockaddr_in, sockaddr_un, inet_aton, inet_ntoa, inet_pton, inet_ntop - load the C socket.h defines and structure manipulators
=head1 SYNOPSIS
and returns the pathname. Will croak if the structure does not
have AF_UNIX in the right place.
+=item inet_pton ADDRESS_FAMILY, HOSTNAME
+
+Takes an address family, either AF_INET or AF_INET6, and a string giving
+the name of a host, and translates that to an opaque string
+(if programming in C, struct in_addr or struct in6_addr depending on the
+address family passed in). The host string may be a string hostname, such
+as 'www.perl.org', or an IP address. If using an IP address, the type of
+IP address must be consistant with the address family passed into the function.
+
+=item inet_ntop ADDRESS_FAMILY, IP_ADDRESS
+
+Takes an address family, either AF_INET or AF_INET6, and a string
+(an opaque string as returned by inet_aton() or inet_pton()) and
+translates it to an IPv4 or IPv6 address string.
+
=back
=cut
PUSHs(sv_2mortal(newSViv((IV) port)));
PUSHs(sv_2mortal(newSVpvn((char *)&ip_address, sizeof ip_address)));
}
+
+void
+inet_ntop(af, ip_address_sv)
+ int af
+ SV * ip_address_sv
+ CODE:
+#ifdef HAS_INETNTOP
+ STRLEN addrlen, struct_size;
+ struct in6_addr addr;
+ char str[INET6_ADDRSTRLEN];
+ char *ip_address = SvPV(ip_address_sv, addrlen);
+
+ if(af == AF_INET) {
+ struct_size = sizeof(struct in_addr);
+ } else if(af == AF_INET6) {
+ struct_size = sizeof(struct in6_addr);
+ } else {
+ croak("Bad address family for Socket::inet_ntop, got %d, should be either AF_INET or AF_INET6",
+ af);
+ }
+
+ Copy( ip_address, &addr, sizeof addr, char );
+ inet_ntop(af, &addr, str, INET6_ADDRSTRLEN);
+
+ ST(0) = sv_2mortal(newSVpv(str, strlen(str)));
+#else
+ ST(0) = (SV *)not_here("inet_ntop");
+#endif
+
+void
+inet_pton(af, host)
+ int af
+ const char * host
+ CODE:
+#ifdef HAS_INETPTON
+ struct in6_addr ip_address;
+ if(af != AF_INET && af != AF_INET6) {
+ croak("Bad address family for %s, got %d, should be either AF_INET or AF_INET6",
+ "Socket::inet_pton",
+ af);
+ }
+ int ok = (*host != '\0') && inet_pton(af, host, &ip_address);
+
+ ST(0) = sv_newmortal();
+ if (ok) {
+ sv_setpvn( ST(0), (char *)&ip_address, sizeof ip_address );
+ }
+#else
+ ST(0) = (SV *)not_here("inet_pton");
+#endif
use Socket qw(:all);
-print "1..17\n";
+print "1..20\n";
$has_echo = $^O ne 'MSWin32';
$alarmed = 0;
# doesn't have abstract socket support
print "ok 17 - skipped on this platform\n";
}
+
+if($Config{d_inetntop} && $Config{d_inetaton}){
+ print ((inet_ntop(AF_INET, inet_pton(AF_INET, "10.20.30.40")) eq "10.20.30.40") ? "ok 18\n" : "not ok 18\n");
+ print ((inet_ntop(AF_INET, inet_aton("10.20.30.40")) eq "10.20.30.40") ? "ok 19\n" : "not ok 19\n");
+ print (lc(inet_ntop(AF_INET6, inet_pton(AF_INET6, "2001:503:BA3E::2:30")) eq "2001:503:ba3e::2:30") ? "ok 20\n" : "not ok 20\n");
+} else {
+ # no IPv6
+ print "ok 18 - skipped on this platform\n";
+ print "ok 19 - skipped on this platform\n";
+}