C Programming

How to Implement IPv6 Addresses for Sockets in C

We all know about the IPv4 address. Now, with the exhaustion of IPv4 addresses, IPv6 is introduced to provide a larger address space.

Let us discuss about the implementation of IPv6 addresses for sockets in the C language. Understanding and implementing the IPv6 addresses in socket programming enables the seamless communication in an IPv6-enabled network and ensures compatibility.

Understanding the IPv6 Address

IPv6 addresses are an integral part of the Internet Protocol version 6 (IPv6) and plays a very important role in identifying and locating the devices on a network. With the exhaustion of IPv4 addresses, IPv6 was introduced to overcome the limitations and provide a significantly larger address space. The IPv6 addresses are 128-bit numbers. This results in a total of 2^128 unique addresses.

The structure of an IPv6 address is represented as:

aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:aaaa

Here, each “a” represents a 4-digit hexadecimal number which range from 0000 to FFFF.

The leading zeros within a 16-bit block is skipped in IPV6 address representation. For example, the “2001:0DB8:0000:0000:0000:0000:0000:0001” address can be written as “2001:DB8::1”. The “::” notation allows for a more concise representation, particularly for addresses with long strings of zeros. However, we must use it with caution as it can introduce ambiguity when multiple “::” occurrences are possible. In that scenario, we should expand the address completely to maintain clarity.

The IPv6 addresses are case-insensitive which allows both the uppercase and lowercase letters in the hexadecimal digits. However, the convention is to use the lowercase letters for consistency. The IPv6 addresses serve various purposes including identifying the network interfaces, routing the packets, and enabling the communication between devices. They are assigned to devices either manually or automatically through protocols like Dynamic Host Configuration Protocol version 6 (DHCPv6). So, implementing the IPv6 addresses for sockets in C is important because it enables a seamless communication in an IPv6-enabled network which helps to grow in number of devices and ensures compatibility with the evolving internet infrastructure.

Steps to Implement the IPv6 Addresses for a Socket in C

Let us consider the following steps about the methods to implement the IPv6 addresses for a socket in the C language:

  • At first, we have to include the required headers that provide structures and functions to work with sockets in our C program.
  • Then, we have to create a socket. We have to use the socket() function to create an IPv6 socket. Then, we specify the domain as AF_INET6 and the type as either SOCK_STREAM for TCP or SOCK_DGRAM for UDP.
  • Then, bind the socket. We associate the socket with a specific IPv6 address and port using the bind() function. Then, we create a structure named “struct sockaddr_in6” and provide it with the information.
  • We then listen for connections using the listen() function to prepare the socket for incoming connections.
  • At last, to accept the connections, we use the accept() function to accept the incoming connections on the bound socket which returns a new socket file descriptor.

Programming Example 1: Implement the IPv6 Addresses for Sockets

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define PORT 7070
#define BACKLOG 5

int main ()
 {
    int server_fd, new_socket;
    struct sockaddr_in6 server_addr, client_addr;
    socklen_t client_addr_len;

    //  We create IPv6 socket
    server_fd = socket (AF_INET6, SOCK_STREAM, 0);
    if (server_fd == -1)
 {
        perror ("Socket creation failed");
        exit (EXIT_FAILURE);
    }
    //  we Bind the socket
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin6_family = AF_INET6;
    server_addr.sin6_port = htons (PORT);
    server_addr.sin6_addr = in6addr_any;
    if (bind (server_fd, (struct sockaddr*) & server_addr, sizeof (server_addr)) == -1) {
        perror ("Socket bind failed");
        exit (EXIT_FAILURE);
    }

    Printf ("Listening for connections on IPv6 address ...\n");

    // Listen for incoming connections
    if (listen (server_fd, BACKLOG) == -1) {
        perror ("Socket listen failed");
        exit (EXIT_FAILURE);
    }

    printf ("Waiting for incoming connections ...\n");

    // we Accept connections
    client_addr_len = sizeof (client_addr);
    new_socket = accept (server_fd, (struct sockaddr*) & client_addr, & client_addr_len);
    if (new_socket == -1) {
        perror ("Socket accept failed");
        exit (EXIT_FAILURE);
    }

    printf ("Connection successful on IPv6 address! \n");

    // Convert and display client IPv6 address
    char client_ip_str [INET6_ADDRSTRLEN];
    inet_ntop (AF_INET6, & (client_addr.sin6_addr), client_ip_str, INET6_ADDRSTRLEN);
    printf ("Connected client IP: %s\n", client_ip_str);

    // now we Close sockets
    Close (new_socket);
    close (server_fd);

    return 0;
}

Output:

$ gcc srr.c -o srr
$ ./srr
Listening for connections on IPv6 address ...
Waiting for incoming connections ...

Explanation:

In this programming example, we first setup an IPv6 socket, bind it to the specified port, and then listen for incoming connections. Then, we display the messages which indicate that it is listening for connections and is waiting for incoming connections. When a client successfully connects, it prints a message which confirms the connection and displays the client’s IPv6 address. Finally, we close all the sockets. This programming example allows for communication with clients over an IPv6 network.

Conclusion

The implementation of IPv6 addresses for sockets in C is important to enable the communication in an IPv6-enabled network. In this article, we explained the creation of an IPv6 socket, bound it to a specific address and port, listened for incoming connections, accepted the connections, and displayed the client’s IPv6 address. By following these steps and using the appropriate functions and structures, we can successfully implement the IPv6 address handling in the C language.

About the author

Bamdeb Ghosh

Bamdeb Ghosh is having hands-on experience in Wireless networking domain.He's an expert in Wireshark capture analysis on Wireless or Wired Networking along with knowledge of Android, Bluetooth, Linux commands and python. Follow his site: wifisharks.com