2017-09-19 5 views
0

Ich habe eine application which uses Perl's gethostbyname to check if a hostname exists in DNS. Ich möchte den Quellcode der Anwendung, die nicht von mir geschrieben wurde, nicht patchen. Aber ich überlege, gethostbyname in einer der Perl-geschriebenen Konfigurationsdateien zu überschreiben.Ist es möglich, Gethostbyname in Perl zu überschreiben oder zu affen, damit es IPv6 unterstützt?

Also frage ich mich, ob es eine Chance gibt, diese Funktion zu überschreiben, indem man sie irgendwie monkey-patchen.

Die documentation of that application says that its hostname lookups work as follows:

$ perl -e 'print(gethostbyname("ipv6.google.com") ? "ok\n" : "not found\n");' 
not found 

Bisher habe ich versucht:

$ perl -E 'use Socket qw(:DEFAULT getaddrinfo); sub gethostbyname { my ($err, @result) = getaddrinfo(@_); return @result; }; print(gethostbyname("ipv6.google.com") ? "ok\n" : "not found\n");' 
not found 

Und:.

$ perl -E 'use Socket qw(:DEFAULT getaddrinfo); use Monkey::Patch::Action qw(patch_package); patch_package("*", "gethostbyname", "add", sub { my ($err, @result) = getaddrinfo(@_); return @result; }); print(gethostbyname("ipv6.google.com") ? "ok\n" : "not found\n");' 
not found 

(Ich habe auch versucht main statt * und replace statt addreplace gerettet wie folgt: Replacing *::gethostbyname: must already exist at /usr/share/perl5/Monkey/Patch/Action.pm line 31.)

+2

Im zweiten Abschnitt benötigen Sie nur 'uses subs qw (gethostbyname);'. – ikegami

+0

Im dritten Snippet denke ich, dass '' patch_package '' mit 'BEGIN' versehen werden kann. – ikegami

+2

Aber wahrscheinlich möchten Sie von außerhalb des Moduls, das die Aufrufe von 'gethostbyname' hat (oder Sie würden einfach die richtige sub aufrufen). Sie können das tun, indem Sie Ihre Überschreibung 'CORE :: GLOBAL :: gethostbyname' benennen (bevor das Modul mit' gethostbyname' geladen wird). Siehe [Überschreiben von integrierten Funktionen] (https://perldoc.perl.org/perlsub.html#Overriding-Built-in-Functions). Sie können 'caller' verwenden, um die Überschreibung nur für ausgewählte Module bereitzustellen. – ikegami

Antwort

3

TL; TR: Das ist nicht zu erklären, wie gethostbyname (die bisherigen außer Kraft setzen sollte erklären, tut das), sondern hilft, dass dies nicht Ihr eigentliches Problem nicht behebt diesen spezifischen Code machen IPv6 bereit .


Zuerst, was sollte ein IPv6 bereit gethostbyname zurückgeben? Mit IPv4 wird eine gepackte IPv4-Adresse zurückgegeben, und dies wird von Code erwartet, der gethostbyname aufruft. Auf diesen Code folgen normalerweise sockaddr_in, PF_INET Sockets usw. Bei IPv6 muss dieser Code stattdessen und PF_INET6 verwenden, was bedeutet, dass es nicht ausreicht, gethostbyname zu patchen.

Und schauen Sie weiter in den Code, den Sie beheben müssen, ist dies tatsächlich der Fall. Sie haben gerade in Ihrer Frage einen Aufruf von gethostbyname verknüpft, der nur prüft, ob ein definierter Wert zurückgegeben wird. Aber wenn Sie further in the code schauen, werden Sie die explizite Verwendung von inet_aton, PF_INET Sockets usw. sehen, d. H. Alles nimmt nur IPv4-Adressen an.

+0

Danke für den Fang. Ich habe nicht verursacht, dass ich in Eile war, aber deshalb habe ich Kommentare anstatt einer Antwort gepostet :) – ikegami

+0

Danke für das Graben so tief. Ich dachte tatsächlich, es würde nur überprüft, ob ein Hostname aufgelöst wird oder nicht, und daher ist der tatsächliche Typ des Rückgabewerts irrelevant. –

Verwandte Themen