Created
December 8, 2020 10:00
-
-
Save pamaury/41ee42f5666469652fe189131b5cfc00 to your computer and use it in GitHub Desktop.
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
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <time.h> | |
#include <unistd.h> | |
#if !defined(_WIN32) | |
#include <sys/socket.h> | |
#include <netdb.h> | |
#include <arpa/inet.h> | |
#include <net/if.h> | |
#endif | |
#if defined(_WIN32) | |
#define WINVER 0x0A00 | |
#define _WIN32_WINNT 0x0A00 | |
#include <winsock2.h> | |
#include <windows.h> | |
#include <netioapi.h> | |
#include <ws2tcpip.h> | |
#endif | |
#if defined(_WIN32) | |
void die(const char *msg) { | |
char *wsa_message = NULL; | |
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, | |
NULL, | |
WSAGetLastError(), | |
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | |
(LPSTR)&wsa_message, | |
0, | |
NULL); | |
printf("%s : %s\n", msg, wsa_message); | |
LocalFree(wsa_message); | |
exit(1); | |
} | |
#else | |
void die(const char *msg) { | |
perror(msg); | |
exit(1); | |
} | |
#endif | |
int main(int argc, char **argv) { | |
#if defined (_WIN32) | |
WSADATA WSAData; | |
WSAStartup(MAKEWORD(2,2), &WSAData); | |
#endif | |
/* premier argument: nom de l'interface */ | |
if(argc == 1) { | |
printf("usage: %s intf\n", argv[0]); | |
printf("Interfaces:\n"); | |
for(int i = 0; i < 10; i++) { | |
char ifname[IF_NAMESIZE]; | |
if(if_indextoname(i, ifname)) | |
printf("- %s\n", ifname); | |
} | |
return 1; | |
} | |
const char *intfname = argv[1]; | |
/* socket IPv6 UDP */ | |
int s = socket(AF_INET6, SOCK_DGRAM, 0); | |
if(s < 0) die("impossible de créer la socket"); | |
/* seulement IPv6 */ | |
int value = 1; | |
int rc = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &value, sizeof(value)); | |
if(rc < 0) die("impossible de mettre l'option IPV6_V6ONLY"); | |
rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)); | |
if(rc < 0) die("impossible de mettre l'option SO_REUSEADDR"); | |
rc = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &value, sizeof(value)); | |
if(rc < 0) die("impossible de mettre l'option IPV6_MULTICAST_LOOP"); | |
rc = setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &value, sizeof(value)); | |
if(rc < 0) die("impossible de mettre l'option IPV6_UNICAST_HOPS"); | |
rc = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &value, sizeof(value)); | |
if(rc < 0) die("impossible de mettre l'option IPV6_MULTICAST_HOPS"); | |
/* addresse du groupe */ | |
struct sockaddr_in6 group_addr; | |
memset(&group_addr, 0, sizeof(group_addr)); | |
group_addr.sin6_family = AF_INET6; | |
group_addr.sin6_port = htons(4242); | |
rc = inet_pton(AF_INET6, "ff02::4242:4242", &group_addr.sin6_addr); | |
if(rc < 1) die("impossible de convertir l'adresse"); | |
/* interface */ | |
int ifindex = if_nametoindex(intfname); | |
if(ifindex <= 0) { | |
printf("l'interface %s n'existe pas\n", intfname); | |
return 1; | |
} | |
rc = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)); | |
if(rc < 0) die("impossible de mettre l'option IPV6_MULTICAST_IF"); | |
/* on envoie les messages */ | |
while(1) { | |
char msg[1024]; | |
sprintf(msg, "Bonjour, je suis amaury."); | |
ssize_t size = sendto(s, msg, strlen(msg)+1, 0, (struct sockaddr *)&group_addr, sizeof(group_addr)); | |
if(size < 0) | |
die("impossible d'envoyer le message"); | |
sleep(2); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment