Skip to content

Instantly share code, notes, and snippets.

@adongy
Created December 1, 2014 17:22
Show Gist options
  • Save adongy/7c3544d5a96ea7fe9f55 to your computer and use it in GitHub Desktop.
Save adongy/7c3544d5a96ea7fe9f55 to your computer and use it in GitHub Desktop.
/**
* igmp-querier.c - IGMP Querier for Multicast DNS
*
* Copyright (c) 2014, Anthony Dong <aanthony.dong@gmail.com>
* All rights reserved.
*
* This software may be modified and distributed under the terms
* of the BSD license. See the LICENSE file for details.
*
* Original work by Daniel Lorch <dlorch@gmail.com>
* Rewritten to use libnet 1.1
* Many thanks go to Marc Cullen <mcbugs000@gmail.com>
* A detailled analysis of the mDNS issue can be found here:
* http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=736641
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <libnet.h>
#include <string.h>
#include <arpa/inet.h>
#define MCAST_ALL_HOSTS "224.0.0.1"
#define INTERVAL_SECS 60
void rebuild_packet(libnet_t *l) {
u_int32_t ip_addr, ip_dest_addr;
// Destination IP addresses
//ip_addr = libnet_name2addr4(l, MCAST_ALL_HOSTS, LIBNET_DONT_RESOLVE);
//ip_dest_addr = libnet_name2addr4(l, "0.0.0.0", LIBNET_DONT_RESOLVE);
ip_addr = 0xe0000001;
ip_dest_addr = 0x00000000;
/* Build IGMP packet */
if(libnet_build_igmp(IGMP_MEMBERSHIP_QUERY, // packet type
0, // packet code
0, // checksum (autofill)
0, // ipv4 address
NULL, // payload
0, // payload length
l, // context
0) == -1) { // protocol tag
fprintf(stderr, "Error building IGMP packet: %s\n", libnet_geterror(l));
libnet_destroy(l);
exit(EXIT_FAILURE);
}
/* Build IP header */
// Generate random id
u_int16_t id = libnet_get_prand(LIBNET_PR16);
if(libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_IGMP_H, // IP packet length
0, // tos
id, // id
0, // fragmentation bit
1, // ttl
IPPROTO_IGMP, // protocol
0, // checksum (autofill)
0, // source addr
ip_addr, // destination addr
NULL, // payload
0, // payload length
l, // context
0) == -1) { // protocol tag
fprintf(stderr, "Error building IP header: %s\n", libnet_geterror(l));
libnet_destroy(l);
exit(EXIT_FAILURE);
}
}
void do_igmp_query(libnet_t *l) {
if (libnet_write(l) == -1)
fprintf(stderr, "Error writing packet: %s\n", libnet_geterror(l));
}
int main(int argc, char *argv[]) {
pid_t pid = 0, sid = 0;
pid = fork();
if (pid < 0) {
fprintf(stderr, "Error: fork failed.\n");
return -1;
}
if (pid > 0) {
return 0; /* exit parent */
}
umask(0);
sid = setsid();
if (sid < 0) {
fprintf(stderr, "Error: setsid failed.\n");
return -1;
}
chdir("/");
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
/* Initialize libnet */
libnet_t *l;
char errbuf[LIBNET_ERRBUF_SIZE];
char *device = NULL;
if (argc > 1) {
device = argv[1];
}
l = libnet_init(LIBNET_RAW4, device, errbuf);
if (l == NULL) {
fprintf(stderr, "libnet_init() failed: %s\n", errbuf);
exit(EXIT_FAILURE);
}
libnet_seed_prand(l);
/* main loop */
while (1) {
do_igmp_query(l);
rebuild_packet(l);
sleep(INTERVAL_SECS);
}
libnet_destroy(l);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment