--- name: getservbyname signature: 'getservbyname NAME, PROTO' since: 5.0 status: documented categories: ["Network info"] --- ```{index} single: getservbyname; Perl built-in ``` *[Network info](../perlfunc-by-category)* # getservbyname Look up a network service by its textual name and protocol. `getservbyname` consults the system service database (typically `/etc/services`, or whatever `nsswitch.conf` routes the `services` source to) and returns the entry whose name or alias matches `NAME` under the transport protocol named by `PROTO`. It is the Perl wrapper around the C library's `getservbyname(3)` call, and it is how you turn `"https"` into `443` without hardcoding the number. Both arguments are strings. `NAME` is the service name or alias (`"http"`, `"ssh"`, `"imaps"`); `PROTO` is the protocol name (`"tcp"`, `"udp"`, `"sctp"`) — **not** a number, and **not** a `SOCK_STREAM`-style constant. ## Synopsis ```perl my $port = getservbyname NAME, PROTO; # scalar my ($name, $aliases, $port, $proto) = getservbyname NAME, PROTO; # list ``` ## What you get back In **scalar context**, the port number as a plain integer in host byte order — ready to feed to [`pack`](pack) with `"n"` or to a `sockaddr_in` constructor. If no entry matches, the return is [`undef`](undef). In **list context**, the four fields of the `servent` record: - `$name` — canonical service name (the primary name, not whichever alias you looked up by). - `$aliases` — space-separated string of alternate names. - `$port` — port number, host byte order. - `$proto` — canonical protocol name as returned by the resolver, normally equal to the `PROTO` you passed. If no entry matches in list context the return is the empty list. The port is **host byte order**. Network APIs expect network byte order, so pass it through [`pack`](pack) with the `"n"` template — or let [`Socket`](../../Socket) do it via `sockaddr_in`. ## Global state it touches - Holds an open handle to the services database between calls when the database has been opened with [`setservent`](setservent) using a non-zero STAYOPEN. [`endservent`](endservent) closes it. - Sets [`$!`](../perlvar) on lookup failures that stem from a system-level error (database file missing, NSS backend unreachable). A plain "no such service" is reported by returning [`undef`](undef) / the empty list, not by setting [`$!`](../perlvar). ## Examples Resolve a well-known service to its port: ```perl my $port = getservbyname("https", "tcp"); print $port, "\n"; # 443 ``` Full record in list context: ```perl my ($name, $aliases, $port, $proto) = getservbyname("http", "tcp"); print "$name ($aliases) -> $port/$proto\n"; # www (www-http http) -> 80/tcp # (exact aliases depend on /etc/services) ``` Build a `sockaddr_in` for [`connect`](connect), converting the host-order port to network order with [`pack`](pack): ```perl use Socket; my $port = getservbyname("smtp", "tcp") or die "smtp/tcp not in services db"; my $addr = sockaddr_in($port, inet_aton("mail.example.com")); socket(my $s, AF_INET, SOCK_STREAM, getprotobyname("tcp")) or die $!; connect($s, $addr) or die "connect: $!"; ``` Distinguish "not found" from "wrong protocol" — a service that exists under `tcp` but not `udp` returns [`undef`](undef) when the protocol does not match: ```perl defined(getservbyname("https", "tcp")) or die "expected 443"; defined(getservbyname("https", "udp")) or warn "no https/udp entry"; ``` Look up by alias — aliases resolve the same as the canonical name, but the returned `$name` is always the canonical one: ```perl my ($name) = getservbyname("www", "tcp"); print $name, "\n"; # "http" on most systems ``` ## Edge cases - **Unknown service**: returns [`undef`](undef) in scalar context, the empty list in list context. [`$!`](../perlvar) is **not** set for a plain miss — only for underlying system errors. - **Unknown protocol**: same as an unknown service. `getservbyname("ssh", "xyzzy")` returns nothing; no separate error is raised. - **Case sensitivity**: service and protocol names are compared case-insensitively by the system resolver on every platform we support; `"HTTPS"` and `"https"` give the same answer. - **Port is host byte order**: passing it straight into a wire format is a bug. Use `pack("n", $port)` or `sockaddr_in($port, $addr)` — both handle the conversion. - **`NAME` and `PROTO` are both required**. There is no one-arg form; omitting `PROTO` is a compile-time error. - **Precedence trap**: like every named-unary-lookalike in this family, `getservbyname` is a list operator. Parenthesise when combining with operators: ```perl getservbyname "http", "tcp" == 80 # WRONG: parses as # getservbyname("http", ("tcp" == 80)) getservbyname("http", "tcp") == 80 # right ``` - **Threads**: on systems with `getservbyname_r(3)`, Perl uses the reentrant variant transparently. On the handful of platforms that lack it, concurrent lookups from multiple threads can clobber each other's results. - **By-name interface**: `Net::servent` (core) wraps this call and returns an object with named accessors, at the cost of one allocation per lookup. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`getservbyport`](getservbyport) — inverse lookup: port + protocol → service record - [`getservent`](getservent) — walk every entry in the services database, one record at a time - [`setservent`](setservent) — rewind (or persistently open) the services database before a walk - [`endservent`](endservent) — close the services database opened by [`setservent`](setservent) - [`getprotobyname`](getprotobyname) — companion lookup for the `PROTO` argument when you also need its numeric protocol number - [`Socket`](../../Socket) — `sockaddr_in` and `pack_sockaddr_in` consume the host-order port returned here