What's the purpose of using bind() when SOCK_DGRAM is used?

156 Views Asked by At

Here is a piece of code snippet from tftp

void initsock(int af) {
    struct sockaddr_storage s_in;

    if (f >= 0)
        close(f);

    f = socket(af, SOCK_DGRAM, 0);
    if (f < 0) {
        perror("tftp: socket");
        exit(3);
    }
    printf("protocol family: %d\n", af);

    memset(&s_in, 0, sizeof(s_in));
    s_in.ss_family = af;
    if (bind(f, (struct sockaddr *)&s_in, sizeof (s_in)) < 0) {
        perror("tftp: bind");
        exit(1);
    }
    char ip_str[INET6_ADDRSTRLEN] = {0};

    inet_ntop(s_in.ss_family, get_in_addr((struct sockaddr *)&s_in), ip_str, sizeof ip_str);
    printf("ip address: %s\t port: %d\n", ip_str, get_in_port((struct sockaddr *)&s_in));
}

My question is that why bind() is called here? What's the purpose? The second argument seems empty except for ss_family field, no ip address nor port number.

p.s. Source code from https://packages.ubuntu.com/bionic/tftp

1

There are 1 best solutions below

7
Arkadiusz Drabczyk On

bind() in this example uses INADDR_ANY as an address what means that it binds to all available interfaces and port 0 that man 2 bind refers to as an ephemeral port what means that it lets operating system choose free port to use. You can add the following snippet at the end of this function and use getsockname() to get the number port number chosen by OS:

    struct sockaddr_in sa;
    socklen_t addrlen = sizeof(sa);

    if (getsockname(f, (struct sockaddr *) &sa, &addrlen) == -1) {
      perror("getsockname()");
    }

    printf("Local IP address is: %s\n", inet_ntoa(sa.sin_addr));
    printf("Local port is: %d\n", (int) ntohs(sa.sin_port));