Net::netent - Perl 内置 getnet*() 函数的按名称接口
use Net::netent qw(:FIELDS);
getnetbyname("loopback") or die "bad net";
printf "%s is %08X\n", $n_name, $n_net;
use Net::netent;
$n = getnetbyname("loopback") or die "bad net";
{ # there's gotta be a better way, eh?
@bytes = unpack("C4", pack("N", $n->net));
shift @bytes while @bytes && $bytes[0] == 0;
}
printf "%s is %08X [%d.%d.%d.%d]\n", $n->name, $n->net, @bytes;
此模块的默认导出会覆盖核心 getnetbyname() 和 getnetbyaddr() 函数,用返回“Net::netent”对象的版本替换它们。此对象具有从 netdb.h 中的 C 的 netent 结构返回同名结构字段名称的方法;即 name、aliases、addrtype 和 net。aliases 方法返回数组引用,其余为标量。
您还可以使用 :FIELDS import 标记将所有结构字段直接导入到您的命名空间中作为常规变量。(请注意,这仍然会覆盖您的核心函数。)使用以 n_
开头的变量名访问这些字段。因此,如果您导入字段,则 $net_obj->name()
对应于 $n_name。数组引用可用作常规数组变量,因此例如 @{ $net_obj->aliases() }
将简单地变为 @n_aliases。
getnet() 函数是一个简单的前端,它将一个数字参数转发到 getnetbyaddr(),并将其余参数转发到 getnetbyname()。
要访问此功能而不覆盖核心,请将 use
传递一个空导入列表,然后使用其完全限定名称访问函数函数。另一方面,内置函数仍然可以通过 CORE::
伪包使用。
getnet() 函数在 Perl 核心执行此操作
sv_setiv(sv, (I32)nent->n_net);
gethost() 函数在 Perl 核心执行此操作
sv_setpvn(sv, hent->h_addr, len);
这意味着对于主机函数,地址以二进制形式返回,而对于网络函数,地址以常规 perl 整数形式返回。这似乎是一个错误,但以下是如何处理此错误
use strict;
use Socket;
use Net::netent;
@ARGV = ('loopback') unless @ARGV;
my($n, $net);
for $net ( @ARGV ) {
unless ($n = getnetbyname($net)) {
warn "$0: no such net: $net\n";
next;
}
printf "\n%s is %s%s\n",
$net,
lc($n->name) eq lc($net) ? "" : "*really* ",
$n->name;
print "\taliases are ", join(", ", @{$n->aliases}), "\n"
if @{$n->aliases};
# this is stupid; first, why is this not in binary?
# second, why am i going through these convolutions
# to make it looks right
{
my @a = unpack("C4", pack("N", $n->net));
shift @a while @a && $a[0] == 0;
printf "\taddr is %s [%d.%d.%d.%d]\n", $n->net, @a;
}
if ($n = getnetbyaddr($n->net)) {
if (lc($n->name) ne lc($net)) {
printf "\tThat addr reverses to net %s!\n", $n->name;
$net = $n->name;
redo;
}
}
}
虽然此类当前使用 Class::Struct 模块实现以构建类似结构的类,但您不应该依赖于此。
Tom Christiansen