Net::netent - Perl 內建 getnetbyname() 和 getnetbyaddr() 函式的依名稱介面
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」物件的方式取代它們。此物件有方法可以回傳 C 的 netent 結構中來自 netdb.h 的同名結構欄位名稱;也就是 name、aliases、addrtype 和 net。aliases 方法會回傳陣列參考,其餘則為純量。
您也可以使用 :FIELDS 匯入標籤,將所有結構欄位直接匯入您的命名空間中,作為一般變數。(請注意,這仍然會覆寫您的核心函式。)存取這些欄位時,請使用以 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