gethostbyaddr#
מחפש רשומת מארח לפי כתובת ה־IP הארוזה שלו.
gethostbyaddr מבצע חיפוש DNS הפוך: בהינתן כתובת בינארית ארוזה (ארבעה בתים עבור IPv4, שישה־עשר עבור IPv6) ומשפחת הכתובות התואמת, הוא קורא לשגרת ה־C של המערכת gethostbyaddr(3) ומחזיר את רשומת המארח. מקרה השימוש הטיפוסי - ״ממכונת מי הגיע החבילה הזו?״ - רוצה את הצורה בהקשר סקלר: שם מארח יחיד. הצורה בהקשר רשימה חושפת את ה־struct hostent המלא: שם קנוני, כינויים, משפחת כתובות, אורך כתובת, וכל כתובת שה־resolver יודע למארח הזה.
תקציר#
my $name = gethostbyaddr $packed_addr, $addrtype;
my ($name, $aliases, $addrtype, $length, @addrs) = gethostbyaddr $packed_addr, $addrtype;
מה מקבלים בחזרה#
הקשר סקלר - שם המארח הקנוני כמחרוזת רגילה, או undef אם החיפוש ההפוך נכשל.
הקשר רשימה - רשימה בת חמישה אלמנטים שמשקפת את struct hostent של C:
$name- שם המארח הקנוני שאליו ה־resolver מיפה את הכתובת.$aliases- מחרוזת מופרדת ברווחים של שמות חלופיים. סקלר יחיד, לא רשימה.$addrtype- משפחת הכתובות של הכתובות המוחזרות, בדרך כללAF_INET(2) אוAF_INET6(10).$length- אורך כל כתובת בבתים (4עבור IPv4,16עבור IPv6).@addrs- כל הכתובות שהוחזרו עבור המארח, כל אחת מחרוזת בינארית ארוזה באורך$lengthבתים. לעיתים קרובות אחת בלבד, אך מארחים multi-homed יכולים להניב כמה.
בכישלון חיפוש בהקשר רשימה, ההחזרה היא הרשימה הריקה.
מצב גלובלי שהוא נוגע בו#
$?- נקבע לערךh_errnoשל C בכישלון, כאשר הפלטפורמה חושפת אותו. יש לבדוק עם$? != 0כדי להבחין ביןHOST_NOT_FOUNDל־TRY_AGAINושגיאות חולפות דומות.$!- אינו נקבע באופן משמעותי על־ידי כשלי DNS. חיפושים הפוכים נכשלים דרךh_errno, לאerrno; אין לבדוק את$!לאחר קריאה שנכשלה.סמן האיטרציה של מסד נתוני המארחים המשותף עם
gethostent,sethostent, ו־endhostent. קריאה ל־gethostbyaddrעשויה לאפס סמן שנשאר פתוח על־ידיgethostent.
דוגמאות#
צורת סקלר - מיפוי dotted-quad לשם מארח:
use Socket;
my $packed = inet_aton("127.0.0.1");
my $name = gethostbyaddr($packed, AF_INET);
print defined $name ? "$name\n" : "no PTR record\n";
נסיעה חזור - חיפוש קדימה, ואז חיפוש הפוך של הכתובת הראשונה:
use Socket;
my $packed = gethostbyname("www.perl.org");
my $name = gethostbyaddr($packed, AF_INET);
print "$name\n";
זיהוי העמית בחיבור סוקט שהתקבל:
use Socket;
my $peer = getpeername($sock);
my ($port, $iaddr) = sockaddr_in($peer);
my $host = gethostbyaddr($iaddr, AF_INET);
printf "connection from %s:%d\n", $host // inet_ntoa($iaddr), $port;
צורת רשימה - כל שם וכתובת שה־resolver יודע על המארח:
use Socket;
my $packed = inet_aton("8.8.8.8");
my ($name, $aliases, $type, $len, @addrs) = gethostbyaddr($packed, AF_INET);
print "canonical: $name\n";
print "aliases: $_\n" for split ' ', $aliases;
print "address: ", inet_ntoa($_), "\n" for @addrs;
ממשק לפי־שם דרך העקיפה של Net::hostent - מתודות accessor במקום פריסה לפי מיקום:
use Net::hostent;
use Socket;
my $h = gethostbyaddr(inet_aton("127.0.0.1"), AF_INET);
print $h->name, "\n" if $h;
מקרי קצה#
ADDRהוא מחרוזת בינארית ארוזה, לא dotted-quad. העברת"127.0.0.1"ישירות לא עובדת - Perl יקרא ל־resolver עם תשעה בתים גולמיים ולא יקבל בחזרה שום דבר שימושי. יש לעבור תמיד דרךSocket::inet_aton,Socket::inet_pton, או packer שווה־ערך קודם.ADDRTYPEחייב להתאים לרוחב הכתובת.AF_INETרוצהADDRבן ארבעה בתים;AF_INET6רוצה שישה־עשר. אי־התאמה מחזירהundefאו, בפלטפורמות מסוימות, קוראת מעבר לבופר. יש להשתמש בקבוע מ־Socket, לא במספר שלם שהוקלד ביד.יש לבדוק
undefבצורת הסקלר. רשומת PTR חסרה מחזירהundef, לא מחרוזת ריקה. לכתובות רבות באינטרנט הציבורי אין מיפוי הפוך כלל.@addrsעשויה לא לכלול את הכתובת שנשאלה. ה־resolver מחזיר את הרשומה המלאה עבור המארח הקנוני, שעשויה להכיל כתובות נוספות שבמקרה חולקות את שם המארח.הקשר סקלר מריץ את קריאת ה־resolver המלאה בכל מקרה. שגרת ה־C תמיד ממלאת את כל ה־
hostent; Perl פשוט משליך את הרשימה. אין יתרון ביצועים לצורת הסקלר מעבר לקוד ברור יותר.היפוך של חיפוש קדימה אינו מובטח לנסיעה חזור.
gethostbyaddr(gethostbyname($h), AF_INET)עשוי להחזיר שם שונה מ־$h- DNS הפוך ממפה לשם המארח הקנוני, ששונה לעיתים קרובות מהכינוי שהשתמש בשאילתה קדימה.תמיכת IPv6 תלוית פלטפורמה. לא כל
gethostbyaddr(3)של libc מטפל ב־AF_INET6בנקיון. לפתרון הפוך נייד dual-stack יש להשתמש ב־Socket::getnameinfo.בטיחות thread. שגרת ה־C הבסיסית שומרת מצב סטטי לכל־תהליך עבור סמן המארח. קריאות בו־זמניות מ־threads מרובים עשויות לשזור תוצאות. סקריפטים שדורשים פתרון הפוך בטוח־thread צריכים להשתמש ב־
Socket::getnameinfo.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
gethostbyname- החיפוש קדימה: שם מארח → כתובת ארוזהgethostent- מעבר על כל רשומה במסד נתוני המארחים במקום חיפוש כתובת אחתsethostent- להחזיר את המצביע של איטרטור המארחים ולשלוט האם הקובץ נשאר פתוח בין חיפושיםSocket::inet_aton- לבנות את ארגומנט ה־ADDRהארוז ממחרוזת dotted-quadSocket::inet_ntoa- לעבד כתובת ארוזה מתוך@addrsחזרה לצורת dotted-quadSocket::getnameinfo- resolver הפוך מודרני, אגנוסטי לפרוטוקול, שמטפל ב־IPv6 ובטוח־thread