NAME
freeport - get a random unused port number
SYNOPSIS
freeport
DESCRIPTION
This program prints an available IPv4 port and exits.
The port is chosen at random from the ephemeral ports range
(see ip(7)).
EXIT STATUS
0 Success
1 Error
On error, a message is printed on standard error.
And the source code is:
$ cat freeport.c
/*
* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2022 NGINX, Inc.
* Copyright 2022 F5, Inc.
*
* Author: Alejandro Colomar <alx@nginx.com>
*/
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/socket.h>
#include <unistd.h>
int32_t get_free_port(void);
int
main(void)
{
int32_t port;
port = get_free_port();
if (port == -1)
exit(EXIT_FAILURE);
printf("%d\n", port);
exit(EXIT_SUCCESS);
}
int32_t
get_free_port(void)
{
int sfd;
int32_t port;
socklen_t len;
struct sockaddr_in addr;
sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("socket()");
return -1;
}
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = htons(0); // random port
len = sizeof(addr);
if (bind(sfd, (struct sockaddr *) &addr, len)) {
perror("bind()");
goto fail;
}
if (getsockname(sfd, (struct sockaddr *) &addr, &len)) {
perror("getsockname()");
goto fail;
}
port = ntohs(addr.sin_port);
fail:
close(sfd);
return port;
}