Created
February 9, 2018 20:49
-
-
Save daskol/6c13862c634d007a9c42a8a53200771e to your computer and use it in GitHub Desktop.
IPv4 and IPv6 sockets on Linux.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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