Πληροφορίες δικτύου

getprotobyname#

Αναζητά ένα πρωτόκολλο IP βάσει του ονόματος κειμένου του και επιστρέφει την εγγραφή της βάσης δεδομένων του.

Η getprotobyname είναι το περιτύλιγμα της Perl γύρω από την getprotobyname(3) της C library του συστήματος. Δοθέντος ενός ονόματος πρωτοκόλλου όπως "tcp", "udp", ή "icmp", επιστρέφει την αντίστοιχη εγγραφή από τη βάση δεδομένων /etc/protocols του συστήματος (ή όποιο backend κατευθύνει το nsswitch.conf). Η τυπική χρήση είναι η μετατροπή ενός αναγνώσιμου από άνθρωπο ονόματος πρωτοκόλλου στην αριθμητική τιμή που θέλουν οι socket και setsockopt.

Σύνοψη#

getprotobyname NAME
my ($name, $aliases, $proto) = getprotobyname NAME;
my $proto                    = getprotobyname NAME;   # scalar context

Τι επιστρέφεται#

Σε περιβάλλον λίστας, μια λίστα που μοιάζει με τετραστοιχειακή με τρία πεδία:

my ($name, $aliases, $proto) = getprotobyname("tcp");
# $name    => canonical name, e.g. "tcp"
# $aliases => space-separated alias list, e.g. "TCP"
# $proto   => numeric protocol number, e.g. 6

Σε βαθμωτό περιβάλλον, μόνο τον αριθμητικό αριθμό πρωτοκόλλου ($proto). Αυτή είναι η συνηθισμένη μορφή, επειδή ο αριθμός πρωτοκόλλου είναι ολόκληρος ο λόγος για τον οποίο έγινε η αναζήτηση:

my $tcp = getprotobyname("tcp");   # 6

Αν το πρωτόκολλο δεν βρεθεί, η επιστροφή είναι κενή λίστα σε περιβάλλον λίστας και undef σε βαθμωτό περιβάλλον. Πάντα ελέγχετε την οριστικότητα πριν χρησιμοποιήσετε το αποτέλεσμα - το 0 είναι έγκυρος αριθμός πρωτοκόλλου ("ip"), οπότε ο έλεγχος μόνο για αλήθεια είναι λάθος.

defined(my $tcp = getprotobyname("tcp"))
    or die "tcp protocol not in /etc/protocols";

Καθολική κατάσταση που επηρεάζει#

  • Μοιράζεται τον δρομέα επανάληψης της βάσης δεδομένων πρωτοκόλλων με τις getprotobynumber, getprotoent, setprotoent, και endprotoent. Μια κλήση στην getprotobyname μπορεί να επανατοποθετήσει ή να επαναφέρει αυτόν τον δρομέα ανάλογα με την C library του συστήματος· μη διαπλέκετε αναζητήσεις βάσει ονόματος με βρόχο επανάληψης getprotoent.

  • Σε ορισμένες πλατφόρμες η υποκείμενη getprotobyname(3) θέτει το $! / errno σε περίπτωση αποτυχίας. Φορητός κώδικας δεν πρέπει να βασίζεται σε αυτό - αντιμετωπίστε μια απροσδιόριστη επιστροφή ως «δεν βρέθηκε» και προχωρήστε.

Παραδείγματα#

Μετατροπή ονόματος σε αριθμό πρωτοκόλλου για την socket:

use Socket;
my $proto = getprotobyname("tcp")
    // die "tcp not configured";
socket(my $sock, PF_INET, SOCK_STREAM, $proto)
    or die "socket: $!";

Μορφή λίστας, για να δείτε το κανονικό όνομα και τα ψευδώνυμα που χρησιμοποιεί ένα σύστημα:

my ($name, $aliases, $proto) = getprotobyname("TCP");
print "name=$name aliases=$aliases number=$proto\n";
# name=tcp aliases=TCP number=6

Αμυντική αναζήτηση με εφεδρεία για τα δύο πρωτόκολλα που πραγματικά χρειάζεται κάθε σενάριο:

my %num_for = (tcp => 6, udp => 17, icmp => 1);
sub proto_num {
    my ($name) = @_;
    return getprotobyname($name) // $num_for{lc $name};
}

Το βαθμωτό περιβάλλον απαιτείται όταν η τιμή επιστροφής τροφοδοτεί έκφραση· το περιβάλλον λίστας θα ισοπεδωνόταν στην περιβάλλουσα λίστα:

my @args = (SOCK_STREAM, scalar getprotobyname("tcp"));

Οριακές περιπτώσεις#

  • Η ευαισθησία στα πεζά/κεφαλαία εξαρτάται από το σύστημα. Η getprotobyname(3) της glibc ταιριάζει το κανονικό όνομα και κάθε ψευδώνυμο χωρίς διάκριση πεζών-κεφαλαίων· άλλες C libraries μπορεί να μην το κάνουν. Αν έχει σημασία η φορητότητα, περάστε τη μορφή πεζών ("tcp", όχι "TCP").

  • Ο αριθμός πρωτοκόλλου 0 είναι έγκυρος ("ip"). Χρησιμοποιήστε defined(...), όχι λογική αλήθεια, όταν ελέγχετε για επιτυχία.

  • Δεν είναι το ίδιο με αριθμό θύρας. Η getprotobyname("http") επιστρέφει undef - το "http" είναι όνομα υπηρεσίας, όχι πρωτοκόλλου. Χρησιμοποιήστε την getservbyname για αναζητήσεις υπηρεσιών.

  • Η κενή συμβολοσειρά ψευδωνύμου είναι κανονική. Πολλές εγγραφές δεν έχουν ψευδώνυμα· η δεύτερη τιμή επιστροφής είναι τότε η κενή συμβολοσειρά, όχι undef.

  • Παρενέργειες του δρομέα επανάληψης. Αν το πρόγραμμά σας είναι στη μέση ενός βρόχου getprotoent, η κλήση της getprotobyname μπορεί να επαναφέρει τον δρομέα και να παραλείψει ή να επαναλάβει εγγραφές. Ολοκληρώστε την επανάληψη, ή αποθηκεύστε την κατάσταση, πριν κάνετε αναζητήσεις βάσει ονόματος.

  • Ασφάλεια threads. Η υποκείμενη κλήση C δεν είναι thread-safe σε κάθε πλατφόρμα - τυπικά χρησιμοποιεί στατικό ενταμιευτή ανά διεργασία. Η Perl μπορεί να χρησιμοποιήσει την επανεισόδιμη μορφή getprotobyname_r όταν είναι διαθέσιμη, αλλά μην το υποθέτετε.

  • Λείπει η εγγραφή /etc/protocols. Σε minimal containers η βάση δεδομένων μπορεί να απουσιάζει, οπότε κάθε κλήση επιστρέφει undef. Δομήστε πίνακες πρωτοκόλλων μέσα στον κώδικά σας όταν το περιβάλλον στόχος δεν εγγυάται την παρουσία βάσης πρωτοκόλλων.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • getprotobynumber - η αντίστροφη αναζήτηση· χρησιμοποιήστε την όταν έχετε το αριθμητικό πρωτόκολλο και θέλετε το όνομά του

  • getprotoent - επανάληψη σε κάθε εγγραφή της βάσης δεδομένων πρωτοκόλλων μία εγγραφή τη φορά

  • setprotoent / endprotoent - έλεγχος του δρομέα επανάληψης που μοιράζονται με αυτή τη συνάρτηση

  • getservbyname - η ισοδύναμη αναζήτηση για υπηρεσίες (θύρες), όχι πρωτόκολλα· τα δύο συγχέονται συχνά

  • socket - ο συνήθης καταναλωτής του επιστρεφόμενου αριθμού πρωτοκόλλου

  • Net::protoent - αντικειμενοστραφές περιτύλιγμα που επιστρέφει blessed εγγραφή με ονομασμένους accessors αντί για λίστα κατά θέση