From Code to Community: Sponsoring The Perl and Raku Conference 2025 Learn more

# Copyright (c) 2024 Yuki Kimoto
# MIT License
class IO::Socket::IP::Import::IPv4 : interface_t {
version_from IO;
allow IO::Socket::IP;
use Sys::Socket::Constant as SOCKET;
use Sys::Socket::Sockaddr;
use Sys::Socket::Sockaddr::In;
use Sys::Socket::In_addr_base;
use Sys::Socket::Util;
use IO::Socket::IP;
use Net::DNS::Native;
# Interface Methods
method sockname : Sys::Socket::Sockaddr ();
method peername : Sys::Socket::Sockaddr ();
# Instance Methods
method sockaddr : Sys::Socket::In_addr_base () {
my $sockaddr_in_sock = (Sys::Socket::Sockaddr::In)$self->sockname;
my $sockaddr = $sockaddr_in_sock->sin_addr;
return $sockaddr;
}
method sockhost : string () {
my $in_addr_sock = $self->sockaddr;
my $sockhost = (string)undef;
if ($in_addr_sock) {
$sockhost = Sys::Socket::Util->inet_ntop(SOCKET->AF_INET, $in_addr_sock);
}
return $sockhost;
}
method sockport : int () {
my $sockaddr_in_sock = (Sys::Socket::Sockaddr::In)$self->sockname;
my $sockport_network_byte_order = $sockaddr_in_sock->sin_port;
my $sockport_short_unsigned = Sys::Socket->ntohs((short)$sockport_network_byte_order);
my $sockport = $sockport_short_unsigned->(int) & 0xFFFF;
return $sockport;
}
method peeraddr : Sys::Socket::In_addr_base () {
my $sockaddr_in = $self->peername;
my $in_addr = $sockaddr_in->(Sys::Socket::Sockaddr::In)->sin_addr;
return $in_addr;
}
method peerhost : string () {
my $in_addr_peer = $self->peeraddr;
my $peerhost = (string)undef;
if ($in_addr_peer) {
$peerhost = Sys::Socket::Util->inet_ntop(SOCKET->AF_INET, $in_addr_peer);
}
return $peerhost;
}
method peerport : int () {
my $sockaddr_in_peer = (Sys::Socket::Sockaddr::In)$self->peername;
my $peerport_network_byte_order = $sockaddr_in_peer->sin_port;
my $peerport_short_unsigned = Sys::Socket->ntohs((short)$peerport_network_byte_order);
my $peerport = $peerport_short_unsigned->(int) & 0xFFFF;
return $peerport;
}
method create_sockaddr : Sys::Socket::Sockaddr ($address : string, $port : int) {
my $dns = Net::DNS::Native->new;
my $hints = Sys::Socket::Addrinfo->new;
$hints->set_ai_family(SOCKET->AF_INET);
my $service = (string)undef;
my $addrinfo_list_ref = new Sys::Socket::AddrinfoLinkedList[1];
$dns->getaddrinfo($address, $service, $hints, $addrinfo_list_ref);
my $addrinfo_list = $addrinfo_list_ref->[0];
my $sockaddr = (Sys::Socket::Sockaddr)undef;
if ($addrinfo_list) {
my $addrinfo_list_array = $addrinfo_list->to_array;
my $in_addr = $addrinfo_list_array->[0]->ai_addr->(Sys::Socket::Sockaddr::In)->sin_addr;
my $sockaddr_in = Sys::Socket::Util->sockaddr_in($port, $in_addr);
$sockaddr = $sockaddr_in;
}
else {
die "getaddrinfo cannot get an address.";
}
return $sockaddr;
}
}