Created
December 1, 2014 17:22
-
-
Save adongy/7c3544d5a96ea7fe9f55 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
/** | |
* igmp-querier.c - IGMP Querier for Multicast DNS | |
* | |
* Copyright (c) 2014, Anthony Dong <[email protected]> | |
* 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 <[email protected]> | |
* Rewritten to use libnet 1.1 | |
* Many thanks go to Marc Cullen <[email protected]> | |
* 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