Re: Fwd: freeport(1)

Alex Colomar <[email protected]>
Newsgroups gmane.comp.gnu.inetutils.bugs
Message-ID <[email protected]>
On 10/2/22 00:22, Alejandro Colomar wrote:
[...]

> 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 <[email protected]>
>    */
> 
> 
> #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;
> }
> 

And here's a sh(1) implementation:

     $ cat freeport
     #!/bin/sh

     nc -l localhost 0 &

     lsof -i \
     | grep $! \
     | awk '{print $9}' \
     | cut -d':' -f2;

     kill $!;

Cheers,

Alex


-- 
<http://www.alejandro-colomar.es/>
OpenPGP_signature (application/pgp-signature, 833 B) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.