This file is indexed.

/usr/bin/socket_getaddrinfo is in libsocket-getaddrinfo-perl 0.22-3.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#!/usr/bin/perl 

eval 'exec /usr/bin/perl  -S $0 ${1+"$@"}'
    if 0; # not running under some shell

use strict;
use warnings;

use Getopt::Long;
use Socket qw(
   AF_INET
   SOCK_STREAM SOCK_DGRAM SOCK_RAW
   IPPROTO_TCP IPPROTO_UDP IPPROTO_IP
   inet_ntoa unpack_sockaddr_in
);
use Socket::GetAddrInfo qw( getaddrinfo AI_PASSIVE AI_CANONNAME );

# Not sure where we'll find IPv6 things
my $AF_INET6;
BEGIN {
   $AF_INET6 = eval { Socket::AF_INET6() } ||
               eval { require Socket6 and Socket6::AF_INET6() };
   if( defined &Socket::unpack_sockaddr_in6 ) {
      *unpack_sockaddr_in6 = \&Socket::unpack_sockaddr_in6;
      *inet_ntop           = \&Socket::inet_ntop;
   }
   elsif( eval { require Socket6 and defined &Socket6::unpack_sockaddr_in6 } ) {
      *unpack_sockaddr_in6 = \&Socket6::unpack_sockaddr_in6;
      *inet_ntop           = \&Socket6::inet_ntop;
   }
}
use constant CAN_IPv6 => defined &unpack_sockaddr_in6;

sub getfamilybynumber
{
   my ( $family ) = @_;
   return "AF_INET"  if $family == AF_INET;
   return "AF_INET6" if defined $AF_INET6 and $family == $AF_INET6;
   return $family;
}

sub getsocktypebynumber
{
   my ( $socktype ) = @_;
   return "SOCK_STREAM" if $socktype == SOCK_STREAM;
   return "SOCK_DGRAM"  if $socktype == SOCK_DGRAM;
   return "SOCK_RAW"    if $socktype == SOCK_RAW;
   return $socktype;
}

sub getprotocolbynumber
{
   my ( $protocol ) = @_;
   return "IPPROTO_TCP" if $protocol == IPPROTO_TCP;
   return "IPPROTO_UDP" if $protocol == IPPROTO_UDP;
   return "IPPROTO_IP"  if $protocol == IPPROTO_IP;
   return $protocol;
}

sub usage
{
   my ( $exitcode ) = @_;

   my $basename = $0;
   $basename =~ m{/([^/]+?)$} and $basename = $1;

   print STDERR <<"EOF";
Performs a getaddrinfo(3) lookup and prints the returned address structures

Usage:
  $basename [HOST] [SERVICE] [options...]

Options:

  --host, -H HOST       Hostname to resolve
  --service, -S SERVICE Service name or port number to resolve

  -4                    Restrict to just AF_INET (IPv4) results
  -6                    Restrict to just AF_INET6 (IPv6) results

  --stream              Restrict to just SOCK_STREAM results
  --dgram               Restrict to just SOCK_DGRAM results

  --proto PROTO         Restrict to just results of the given IP protocol

  --passive             Set the AI_PASSIVE hint; results will used to bind()
                        and listen() rather than connect()

  --canonical           Retrive the canonical name for the requested host

  --help                Display this help and exit

EOF

   exit $exitcode;
}

my $host;
my $service;
my %hints;

GetOptions(
   'host|H=s'    => \$host,
   'service|S=s' => \$service,

   '4' => sub { $hints{family} = AF_INET },
   '6' => sub { defined $AF_INET6 ? $hints{family} = $AF_INET6
                                  : die "Cannot do AF_INET6\n"; },

   'stream|s' => sub { $hints{socktype} = SOCK_STREAM },
   'dgram'    => sub { $hints{socktype} = SOCK_DGRAM },

   'proto=s' => sub {
      my $proto = $_[1];
      unless( $proto =~ m/^\d+$/ ) {
         my $protonum = getprotobyname( $proto );
         defined $protonum or die "No such protocol - $proto\n";
         $proto = $protonum;
      }
      $hints{protocol} = $proto;
   },

   'passive' => sub { $hints{flags} ||= AI_PASSIVE },

   'canonical' => sub { $hints{flags} ||= AI_CANONNAME },

   'help|h' => sub { usage( 0 ) },
) or usage( 1 );

$host    = shift @ARGV if @ARGV and !defined $host;
$service = shift @ARGV if @ARGV and !defined $service;

defined $host or defined $service or
   usage( 1 );

$host    ||= "";
$service ||= "0";

my ( $err, @res ) = getaddrinfo( $host, $service, \%hints );

die "Cannot getaddrinfo() - $err\n" if $err;

printf "Resolved host '%s', service '%s'\n", $host, $service;

if( $res[0]->{canonname} ) {
   printf "  Canonical name '%s'\n", $res[0]->{canonname};
}

print "\n";

foreach my $res ( @res ) {
   my $address_string;
   if( $res->{family} == AF_INET ) {
      my ( $port, $host ) = unpack_sockaddr_in $res->{addr};
      $address_string = sprintf "%s:%d", inet_ntoa( $host ), $port;
   }
   elsif( CAN_IPv6 and $res->{family} == $AF_INET6 ) {
      my ( $port, $host ) = unpack_sockaddr_in6( $res->{addr} );
      $address_string = sprintf "[%s]:%d", inet_ntop( $res->{family}, $host ), $port;
   }
   else {
      $address_string = sprintf '{family=%d,addr=%v02x}', $res->{family}, $res->{addr};
   }

   printf "socket(%-8s, %-11s, %-11s) + '%s'\n",
      getfamilybynumber($res->{family}),
      getsocktypebynumber($res->{socktype}),
      getprotocolbynumber($res->{protocol}),
      $address_string;
}

__END__

=head1 NAME

C<socket_getaddrinfo> - command-line tool to C<getaddrinfo(3)> resolver

=head1 SYNOPSIS

B<socket_getaddrinfo> [I<options...>] I<host> I<service>

=head1 DESCRIPTION

This tool provides a convenient command-line wrapper around the
C<getaddrinfo(3)> resolver function. It will perform a single lookup and print
the returned results in a human-readable form. This is mainly useful when
debugging address resolution problems, because it allows inspection of the
C<getaddrinfo(3)> behaviour itself, outside of any real program that is trying
to use it.

=head1 OPTIONS

=over 8

=item --host, -H HOST

Hostname to resolve. If not supplied, will use the first positional argument

=item --service, -S SERVICE

Service name or port number to resolve. If not supplied, will use the second
positional argument.

=item -4

Restrict to just C<AF_INET> (IPv4) results

=item -6

Restrict to just C<AF_INET6> (IPv6) results

=item --stream

Restrict to just C<SOCK_STREAM> results

=item --dgram 

Restrict to just C<SOCK_DGRAM> results

=item --proto PROTO

Restrict to just results of the given IP protocol

=item --passive

Set the C<AI_PASSIVE> hint; results will used to bind() and listen() rather
than connect()

=item --canonical

Retrive the canonical name for the requested host

=item --help

Display a help summary and exit

=back

=head1 OUTPUT FORMAT

Each line of output will be given in a form that indicates the four result
fields of C<ai_family>, C<ai_socktype>, C<ai_protocol> and C<ai_addr>. The
first three are printed in the form of a C<socket(2)> call, either
symbolically or numerically, and the latter is printed as a plain string
following it. For example

 socket(AF_INET , SOCK_STREAM, IPPROTO_TCP) + '127.0.0.1:80'

=head1 NOTE

Upstream this script is known as C<getaddrinfo>, but was renamed on Debian.

=head1 AUTHOR

Paul Evans <leonerd@leonerd.org.uk>