Skip to content

Instantly share code, notes, and snippets.

@pamaury
Created December 8, 2020 10:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pamaury/41ee42f5666469652fe189131b5cfc00 to your computer and use it in GitHub Desktop.
Save pamaury/41ee42f5666469652fe189131b5cfc00 to your computer and use it in GitHub Desktop.
#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