Skip to content

Instantly share code, notes, and snippets.

@daskol
Created February 9, 2018 20:49
Show Gist options
  • Save daskol/6c13862c634d007a9c42a8a53200771e to your computer and use it in GitHub Desktop.
Save daskol/6c13862c634d007a9c42a8a53200771e to your computer and use it in GitHub Desktop.
IPv4 and IPv6 sockets on Linux.
// listen.c
//
// This is small tool that helps to clarify how to listen IPv6 socket and it
// is nessesary or not listen IPv4 socket at the same time.
//
// Compile `gcc -std=c11 -o listen listen.c`
//
// Run binary with option `-4` or `-6` and connect to port(default is 5489)
// with netcat in the following way.
// 1. `nc -4 127.0.0.1 5489`
// 2. `nc -6 ::1 5489`
//
// On linux hosts one should listen at least IPv6 socket.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#define MAGIC 5489
void echo(void) {
int ret;
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr = {
AF_INET,
htons(MAGIC),
inet_addr("127.0.0.1"),
};
if ((ret = bind(sock, (const struct sockaddr *)&addr, sizeof(addr))) < 0) {
fprintf(stderr, "listen: %d\n", ret);
return;
}
if ((ret = listen(sock, MAGIC)) < 0) {
fprintf(stderr, "listen: %d\n", ret);
return;
}
while (1) {
struct sockaddr_in client_addr;
socklen_t socklen = sizeof(client_addr);
int client_sock = accept(sock,
(struct sockaddr *)&client_addr,
&socklen);
printf("accept client from %s:%d\n",
inet_ntoa(addr.sin_addr),
htons(addr.sin_port));
close(client_sock);
}
}
void echo6(void) {
int ret;
int sock = socket(AF_INET6, SOCK_STREAM, 0);
struct sockaddr_in6 addr = {
AF_INET6,
htons(MAGIC),
0,
{0},
0,
};
inet_pton(AF_INET, "::1", &addr.sin6_addr);
if ((ret = bind(sock, (const struct sockaddr *)&addr, sizeof(addr))) < 0) {
fprintf(stderr, "listen: %d\n", ret);
printf("%d\n", errno);
return;
}
if ((ret = listen(sock, MAGIC)) < 0) {
fprintf(stderr, "listen: %d\n", ret);
return;
}
while (1) {
static char hostname[255];
struct sockaddr_in6 client_addr;
socklen_t socklen = sizeof(client_addr);
int client_sock = accept(sock,
(struct sockaddr *)&client_addr,
&socklen);
inet_ntop(AF_INET,
&client_addr.sin6_addr,
hostname,
sizeof(client_addr));
printf("accept client from %s:%d\n",
hostname,
htons(addr.sin6_port));
close(client_sock);
}
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("%s: [-4|-6]\n", argv[0]);
return 0;
}
if (!strcmp(argv[1], "-4")) {
echo();
}
else if (!strcmp(argv[1], "-6")) {
echo6();
}
else {
printf("unknown argument: '%s'\n", argv[1]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment