bug-inetutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Fwd: freeport(1)


From: Alex Colomar
Subject: Re: Fwd: freeport(1)
Date: Thu, 6 Oct 2022 13:08:31 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.2.2

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 <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;
}


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/>

Attachment: OpenPGP_signature
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]