--- name: getprotobynumber signature: 'getprotobynumber NUMBER' since: 5.0 status: documented categories: ["Network info"] --- ```{index} single: getprotobynumber; Perl built-in ``` *[Network info](../perlfunc-by-category)* # getprotobynumber Look up a network protocol entry by its assigned protocol number. `getprotobynumber` wraps the system `getprotobynumber(3)` call. Given a numeric protocol identifier — the same values named by constants like `IPPROTO_TCP` (`6`), `IPPROTO_UDP` (`17`), `IPPROTO_ICMP` (`1`) — it returns the matching entry from the system's protocol database (typically `/etc/protocols`). The common use is turning a protocol number pulled off the wire, out of a routing table, or returned by [`getsockopt`](getsockopt) into a human-readable name. ## Synopsis ```perl getprotobynumber NUMBER ``` ## What you get back In list context, a four-element list: ```perl my ($name, $aliases, $proto) = getprotobynumber($number); ``` - `$name` — canonical protocol name (`"tcp"`, `"udp"`, `"icmp"`). - `$aliases` — space-separated string of alternative names for the protocol, or the empty string if none. - `$proto` — the protocol number you passed in, echoed back from the database entry. In scalar context, you get `$name` alone. If the number is not in the database, the scalar return is [`undef`](undef) and the list return is empty. ```perl my $name = getprotobynumber(6); # "tcp" my @rec = getprotobynumber(6); # ("tcp", "", 6) my $none = getprotobynumber(9999); # undef ``` ## Global state it touches Shares the protocol-database cursor with [`getprotobyname`](getprotobyname), [`getprotoent`](getprotoent), [`setprotoent`](setprotoent), and [`endprotoent`](endprotoent). Calling `getprotobynumber` does not disturb an iteration in progress on most systems, but portable code that interleaves single lookups with [`getprotoent`](getprotoent) iteration should call [`setprotoent`](setprotoent) afterwards to reset the cursor. On failure, [`$!`](../perlvar) is set to the underlying `errno`, though most implementations simply return "not found" without setting `errno`. ## Examples Resolve the canonical name of a protocol number: ```perl my $name = getprotobynumber(6); print "$name\n"; # "tcp" ``` Full record with aliases: ```perl my ($name, $aliases, $proto) = getprotobynumber(1); print "$name ($proto): $aliases\n"; # e.g. "icmp (1): ICMP" ``` Reverse-lookup a protocol pulled out of a packet header: ```perl sub protocol_label { my ($num) = @_; my $name = getprotobynumber($num); return defined $name ? $name : "proto-$num"; } ``` Round-trip against [`getprotobyname`](getprotobyname) — useful as a sanity check that your system's protocol database knows the name you expect: ```perl my $num = getprotobyname("tcp"); # 6 my $back = getprotobynumber($num); # "tcp" ``` Pretty-print a `getsockopt` level. The `level` argument to [`getsockopt`](getsockopt) is a protocol number; `getprotobynumber` turns it back into a label for logging: ```perl my ($level) = unpack("I", $packed_level); printf "socket option at level %s\n", getprotobynumber($level) // $level; ``` ## Edge cases - **List-operator precedence trap.** Even though `getprotobynumber` takes a single argument, it parses with list-operator precedence. The function name swallows everything to its right as one big list expression: ```perl getprotobynumber $number eq 'icmp' # WRONG — equivalent to: getprotobynumber($number eq 'icmp') # looks up protocol 0 or 1 getprotobynumber($number) eq 'icmp' # what you meant ``` Always parenthesise the argument when comparing the result, or assign the lookup to a variable first. - **Unknown number**: scalar return is [`undef`](undef); list return is the empty list. Guard with `defined`: ```perl defined(my $name = getprotobynumber($n)) or die "unknown protocol number $n"; ``` - **Non-integer argument**: converted to an integer via the usual numeric coercion before the lookup. A string like `"tcp"` coerces to `0` and you get whatever entry (if any) is registered for protocol `0`, which is usually `"ip"`. For name-based lookup, use [`getprotobyname`](getprotobyname). - **Negative or out-of-range numbers**: no entry, returns empty / [`undef`](undef). No warning is raised. - **The `Net::protoent` object interface**. If you import `Net::protoent`, `getprotobynumber` is overridden to return a blessed object with named accessors (`$p->name`, `$p->aliases`, `$p->proto`). Handy when you do not want to remember positional field order. - **Database lookup, not protocol stack introspection**. This function reads `/etc/protocols` (or the equivalent NSS source). It tells you what name the system assigns to a number; it does not tell you whether the kernel actually supports that protocol or whether a socket of that type can be opened. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`getprotobyname`](getprotobyname) — the inverse: look up a protocol entry by name when you have a label like `"tcp"` and need the number - [`getprotoent`](getprotoent) — iterate every entry in the protocol database, when you want to list or index them all - [`setprotoent`](setprotoent) — reopen / rewind the protocol-database cursor; pair with [`endprotoent`](endprotoent) around an iteration - [`getservbyport`](getservbyport) — the service-table analogue, turning a port number into a service name - [`getsockopt`](getsockopt) — returns a protocol number as its `level` argument; feed it to `getprotobynumber` for readable logs - [`Socket`](../../Socket) — exports the `IPPROTO_*` constants whose numeric values are what you pass in