Compare commits

..

No commits in common. "c92f1580df52b573301adf8355dc3212e8222a29" and "d8eb38dd1668f7a9a30c20a9160f908ed6103147" have entirely different histories.

8 changed files with 342 additions and 454 deletions

View file

@ -33,9 +33,6 @@ target_link_libraries(igmpgen ${LIBNET_LIBRARY})
# Installation instructions # Installation instructions
install(TARGETS igmpgen DESTINATION bin) install(TARGETS igmpgen DESTINATION bin)
# Install the man page
install(FILES misc/igmpgen.man.1 DESTINATION share/man/man1 RENAME igmpgen.1)
# Include CPack for packaging # Include CPack for packaging
include(InstallRequiredSystemLibraries) include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt")

View file

@ -1,24 +0,0 @@
BUILD_DIR=_build
all: build
$(BUILD_DIR):
mkdir -p $(BUILD_DIR)
cmake -S . -B _build -D CMAKE_BUILD_TYPE=Debug
build: | $(BUILD_DIR)
cmake --build _build
debug: | $(BUILD_DIR)
gdb _build/igmpgen
run: | $(BUILD_DIR)
_build/igmpgen
install: | $(BUILD_DIR)
cmake --install _build
package: | $(BUILD_DIR)
make -C _build package

5
build.sh Executable file
View file

@ -0,0 +1,5 @@
#!/bin/sh
mkdir -p _build
cmake -S . -B _build -D CMAKE_BUILD_TYPE=Debug
cmake --build _build

View file

@ -1,86 +0,0 @@
.TH IGMPGEN 1 "Your Date Here" "Version Number Here" "IGMPGEN Manual"
.SH NAME
igmpgen \- IGMP packet generator
.SH SYNOPSIS
.B igmpgen
[options]
.SH DESCRIPTION
.PP
The
.B igmpgen
utility is used to generate IGMP (Internet Group Management Protocol) network packets.
.SH OPTIONS
.TP
.B \-i <interface>
Specify the network interface (e.g., eth0).
.TP
.B \-t <type>
Specify the IGMP packet type and version (e.g., 1.query).
.TP
.B \-g <group>
Specify the destination IGMP group (e.g., 224.0.0.1).
.TP
.B \-s <source>
Specify the source IP and port (e.g., 192.168.1.1:1234).
.TP
.B \-d <destination>
Specify the destination IP and port (e.g., 224.0.0.2:5678).
.TP
.B \-n <number>
Specify delay between packets in seconds (optional).
.SH AVAILABLE IGMP PACKET TYPES
.PP
The following IGMP packet types are available:
.PP
\- 1.query
.br
\- 1.report
.br
\- 1.dvmrp
.br
\- 2.query
.br
\- 2.report
.br
\- 2.leave
.br
\- 3.report
.SH EXAMPLES
.PP
To generate a 1.query IGMP packet on eth0:
.PP
.nf
\fB$ igmpgen -i eth0 -t 1.query\fR
.fi
.SH AUTHOR
.PP
Written by Your Name.
.SH "SEE ALSO"
.PP
Related commands or documentation.
.SH BUGS
.PP
No known bugs.
.SH LICENSE
.PP
Specify license information or refer to the LICENSE file.
.SH "REPORTING BUGS"
.PP
Provide information on how to report bugs.

3
run.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
gdb _build/igmpgen

View file

@ -2,30 +2,31 @@
#ifndef IGP_TYPES_H #ifndef IGP_TYPES_H
#define IGP_TYPES_H #define IGP_TYPES_H
#define IPOPT_RA 148 /* router alert */ #define IPOPT_RA 148 /* router alert */
#define IGMP_V3_MEMBERSHIP_REPORT 0x22 #define IGMP_V3_MEMBERSHIP_REPORT 0x22
#include <sys/types.h> #include <sys/types.h>
/* Structure to represent IGMP extra information */ /* Structure to represent IGMP extra information */
typedef struct { typedef struct {
u_int8_t igmp_version; u_int8_t igmp_version;
char *igmp_tag; char *igmp_tag;
u_int8_t igmp_type; /* IGMP type */ u_int8_t igmp_type; /* IGMP type */
u_int8_t igmp_code; /* routing code */ u_int8_t igmp_code; /* routing code */
char *igmp_dst; char *igmp_dst;
int group_override_dst; int group_override_dst;
} ipg_igmp_extra_t; } ipg_igmp_extra_t;
typedef struct { typedef struct {
char *device; char *device;
char *igmp_type_version; // Combined type and version char *igmp_type_version; // Combined type and version
char *igmp_group; char *igmp_group;
char *source_ip_port; // Combined source IP and port char *source_ip_port; // Combined source IP and port
char *destination_ip_port; // Combined destination IP and port char *destination_ip_port; // Combined destination IP and port
int delay_between_packets; // Optional, can be 0 if not specified int delay_between_packets; // Optional, can be 0 if not specified
} ipg_cmdline_options_t; } ipg_cmdline_options_t;
extern ipg_igmp_extra_t g_igmp_pkts[]; extern ipg_igmp_extra_t g_igmp_pkts[];
#endif /* IGP_TYPES_H */ #endif /* IGP_TYPES_H */

View file

@ -5,10 +5,10 @@
#include <sys/types.h> #include <sys/types.h>
/* missing type definitions (depending on system) */ /* missing type definitions (depending on system) */
typedef unsigned char unchar; typedef unsigned char unchar;
typedef unsigned short ushort; typedef unsigned short ushort;
typedef unsigned int uint; typedef unsigned int uint;
typedef unsigned long ulong; typedef unsigned long ulong;
#include <libnet.h> #include <libnet.h>
#include <netinet/igmp.h> #include <netinet/igmp.h>
@ -17,358 +17,356 @@ typedef unsigned long ulong;
/* global table of IGMP packet types*/ /* global table of IGMP packet types*/
ipg_igmp_extra_t g_igmp_pkts[] = { ipg_igmp_extra_t g_igmp_pkts[] = {
/* name, type (or version+type), code */ /* name, type (or version+type), code */
{1, "query", 0x11, 0, "224.0.0.1", 0}, { 1, "query", 0x11, 0, "224.0.0.1", 0 },
{1, "report", 0x12, 0, "224.0.0.1", 1}, { 1, "report", 0x12, 0, "224.0.0.1", 1 },
{1, "dvmrp", 0x13, 0, "224.0.0.1", 0}, { 1, "dvmrp", 0x13, 0, "224.0.0.1", 0 },
{2, "query", 0x11, 1, "224.0.0.1", 0}, { 2, "query", 0x11, 1, "224.0.0.1", 0 },
{2, "report", 0x16, 1, "224.0.0.2", 1}, { 2, "report", 0x16, 1, "224.0.0.2", 1 },
{2, "leave", 0x17, 1, "224.0.0.2", 0}, { 2, "leave", 0x17, 1, "224.0.0.2", 0 },
{3, "report", 0x22, 1, "224.0.0.22", 0}, { 3, "report", 0x22, 1, "224.0.0.22", 0 },
/* Note: end of list (please keep) */ /* Note: end of list (please keep) */
{0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0 },
}; };
void usage(char *); void usage(char *);
ipg_igmp_extra_t *igmp_packet_type_find(u_int8_t igmp_version, ipg_igmp_extra_t * igmp_packet_type_find(u_int8_t igmp_version, char *igmp_request) {
char *igmp_request) ipg_igmp_extra_t *pkt_ptr;
{
ipg_igmp_extra_t *pkt_ptr;
pkt_ptr = g_igmp_pkts; pkt_ptr = g_igmp_pkts;
while (pkt_ptr->igmp_version || pkt_ptr->igmp_tag) { while(pkt_ptr->igmp_version || pkt_ptr->igmp_tag){
// if ((strcasecmp(pkt_ptr->igmp_tag, optarg) == 0) // if ((strcasecmp(pkt_ptr->igmp_tag, optarg) == 0)
if ((strcasecmp(pkt_ptr->igmp_tag, igmp_request) == 0) if ((strcasecmp(pkt_ptr->igmp_tag, igmp_request) == 0)
&& (igmp_version == pkt_ptr->igmp_version)) { && (igmp_version == pkt_ptr->igmp_version)){
return pkt_ptr; return pkt_ptr;
} }
pkt_ptr++; pkt_ptr++;
} }
return NULL; return NULL;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
u_int32_t ip_src = 0; u_int32_t ip_src = 0;
u_int32_t ip_dst = 0; u_int32_t ip_dst = 0;
u_int32_t igmp_group = 0; u_int32_t igmp_group = 0;
char *igmp_group_str = NULL; char *igmp_group_str = NULL;
char *ip_src_str = NULL; char *ip_src_str = NULL;
char *ip_dst_str = NULL; char *ip_dst_str = NULL;
u_char igmp_type = 0; u_char igmp_type = 0;
u_char igmp_code = 0; u_char igmp_code = 0;
ipg_igmp_extra_t *pkt_ptr; ipg_igmp_extra_t *pkt_ptr;
int igmp_override; int igmp_override;
/* ports */ /* ports */
u_short src_prt = 3141; u_short src_prt = 3141;
u_short dst_prt = 5926; u_short dst_prt = 5926;
/* igmp stuff */ /* igmp stuff */
u_int8_t igmp_version = 0; u_int8_t igmp_version = 0;
int ip_src_test = 1; int ip_src_test = 1;
int ip_dst_test = 1; int ip_dst_test = 1;
int igmp_group_test = 1; int igmp_group_test =1;
/* libnet stuff */ /* libnet stuff */
char neterr[LIBNET_ERRBUF_SIZE]; char neterr[LIBNET_ERRBUF_SIZE];
libnet_ptag_t ptag; libnet_ptag_t ptag;
libnet_t *netcontext = NULL; libnet_t *netcontext = NULL;
/* misc */ /* misc */
char *device = "eth0"; char *device = "eth0";
int c; int c;
char *cp = NULL; char *cp = NULL;
printf("IGMP packet generator\n\n"); printf("IGMP packet generator\n\n");
printf("Detected options:\n"); printf("Detected options:\n");
/* Parsing command line */ /* Parsing command line */
while ((c = getopt(argc, argv, "i:t:g:d:s:")) != EOF) { while((c = getopt(argc, argv, "i:t:g:d:s:")) != EOF)
switch (c) { {
case 'i': switch (c)
printf(" Net interface = [%s]\n", optarg); {
device = optarg; case 'i':
break; printf(" Net interface = [%s]\n",optarg);
device = optarg;
break;
case 't': case 't':
if (!(cp = strrchr(optarg, '.'))) { if (!(cp = strrchr(optarg, '.'))) {
usage(argv[0]); usage(argv[0]);
exit(1); exit(1);
} }
*cp++ = 0; *cp++ = 0;
igmp_version = (u_short) atoi(optarg); igmp_version = (u_short)atoi(optarg);
pkt_ptr = igmp_packet_type_find(igmp_version, cp); pkt_ptr = igmp_packet_type_find(igmp_version, cp);
if (!pkt_ptr) { if (!pkt_ptr) {
printf("ERROR: Packet type %d.%s not found!\n", printf("ERROR: Packet type %d.%s not found!\n", igmp_version, cp);
igmp_version, cp); usage(argv[0]);
usage(argv[0]); exit(1);
exit(1); }
}
igmp_type = pkt_ptr->igmp_type; igmp_type = pkt_ptr->igmp_type;
igmp_code = pkt_ptr->igmp_code; igmp_code = pkt_ptr->igmp_code;
ip_dst_str = pkt_ptr->igmp_dst; ip_dst_str = pkt_ptr->igmp_dst;
igmp_override = pkt_ptr->group_override_dst; igmp_override = pkt_ptr->group_override_dst;
printf(" Packet = [%s] version [%d]\n", printf(" Packet = [%s] version [%d]\n", pkt_ptr->igmp_tag, igmp_version);
pkt_ptr->igmp_tag, igmp_version); break;
break;
case 'g': case 'g':
// Group argument handling logic // Group argument handling logic
printf(" Group = [%s]\n", optarg); printf(" Group = [%s]\n", optarg);
igmp_group_str = optarg; igmp_group_str = optarg;
break; break;
case 'n': case 'n':
// delay between packets in sec // delay between packets in sec
break; break;
case 'd': case 'd':
/* /*
* We expect the input to be of the form `ip.ip.ip.ip:port`. We * We expect the input to be of the form `ip.ip.ip.ip:port`. We
* point cp to the last dot of the IP address/port string and * point cp to the last dot of the IP address/port string and
* then seperate them with a NULL byte. The optarg now points to * then seperate them with a NULL byte. The optarg now points to
* just the IP address, and cp points to the port. * just the IP address, and cp points to the port.
*/ */
if ((cp = strrchr(optarg, ':'))) { if ((cp = strrchr(optarg, ':')))
*cp++ = 0; {
dst_prt = (u_short) atoi(cp); *cp++ = 0;
} else { dst_prt = (u_short)atoi(cp);
dst_prt = 0; } else {
} dst_prt = 0;
ip_dst_str = strdup(optarg); }
printf(" Destination = ip [%s] port [%d]\n", ip_dst_str = strdup(optarg);
ip_dst_str, dst_prt); printf(" Destination = ip [%s] port [%d]\n", ip_dst_str, dst_prt);
break; break;
case 's': case 's':
if ((cp = strrchr(optarg, ':'))) { if ((cp = strrchr(optarg, ':')))
*cp++ = 0; {
src_prt = (u_short) atoi(cp); *cp++ = 0;
} else { src_prt = (u_short)atoi(cp);
src_prt = 0; } else {
} src_prt = 0;
ip_src_str = strdup(optarg); }
printf(" Source = ip [%s] port [%d]\n", ip_src_str, ip_src_str = strdup(optarg);
src_prt); printf(" Source = ip [%s] port [%d]\n", ip_src_str, src_prt);
break; break;
default: default:
usage(argv[0]); usage(argv[0]);
exit(1); exit(1);
} }
} }
if (!igmp_group_str) { if (!igmp_group_str)
usage(argv[0]); {
fprintf(stderr, "ERROR: missing destination IGMP group\n"); usage(argv[0]);
exit(EXIT_FAILURE); fprintf(stderr, "ERROR: missing destination IGMP group\n");
} exit(EXIT_FAILURE);
}
if (!device) { if (!device)
usage(argv[0]); {
fprintf(stderr, "ERROR: missing device\n"); usage(argv[0]);
exit(EXIT_FAILURE); fprintf(stderr, "ERROR: missing device\n");
} exit(EXIT_FAILURE);
}
printf("done\n"); printf("done\n");
/* Memory initialization */ /* Memory initialization */
printf("Initializing libnet context...\n"); printf("Initializing libnet context...\n");
netcontext = libnet_init(LIBNET_RAW4, device, neterr); netcontext = libnet_init(LIBNET_RAW4, device, neterr);
if (!netcontext) { if (!netcontext) {
fprintf(stderr, "%s\n", neterr); fprintf(stderr, "%s\n", neterr);
exit(1); exit(1);
} }
libnet_clear_packet(netcontext); libnet_clear_packet(netcontext);
if (!ip_src_str) { if (!ip_src_str) {
ip_src = libnet_get_ipaddr4(netcontext); ip_src = libnet_get_ipaddr4(netcontext);
ip_src_str = libnet_addr2name4(ip_src, LIBNET_DONT_RESOLVE); ip_src_str = libnet_addr2name4(ip_src, LIBNET_DONT_RESOLVE);
} }
printf("Packet construction...\n"); printf("Packet construction...\n");
/* Packet construction: IGMP */ /* Packet construction: IGMP */
printf(" Building IGMP content...\n"); printf(" Building IGMP content...\n");
ptag = libnet_build_igmp(igmp_type, // IGMP type ptag = libnet_build_igmp(
igmp_code, // IGMP code igmp_type, // IGMP type
0, // checksum igmp_code, // IGMP code
0, // group address 0, // checksum
NULL, // payload 0, // group address
0, // payload size NULL, // payload
netcontext, // libnet context 0, // payload size
0 // ptag netcontext, // libnet context
); 0 // ptag
if (ptag == -1) { );
fprintf(stderr, "Error building IGMP header: %s\n", if (ptag == -1) {
libnet_geterror(netcontext)); fprintf(stderr, "Error building IGMP header: %s\n", libnet_geterror(netcontext));
libnet_destroy(netcontext); libnet_destroy(netcontext);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
printf(" done\n"); printf(" done\n");
/* Send packet */ /* Send packet */
if (libnet_write(netcontext) == -1) { if (libnet_write(netcontext) == -1) {
fprintf(stderr, "Error sending packet: %s\n", fprintf(stderr, "Error sending packet: %s\n", libnet_geterror(netcontext));
libnet_geterror(netcontext)); } else {
} else { printf("Packet sent successfully.\n");
printf("Packet sent successfully.\n"); }
}
printf("Packet construction...\n"); printf("Packet construction...\n");
/* /*
* Packet construction : IGMP * Packet construction : IGMP
*/ */
printf(" Building IGMP content...\n"); printf(" Building IGMP content...\n");
// Override dest with group info when needed // Override dest with group info when needed
if (igmp_override) { if (igmp_override) {
ip_dst_str = igmp_group_str; ip_dst_str = igmp_group_str;
} }
switch (igmp_type) { switch ( igmp_type ) {
case 0x11: // IGMP_MEMBERSHIP_QUERY case 0x11: // IGMP_MEMBERSHIP_QUERY
if (igmp_version == 2) { if (igmp_version == 2){
// group specific // group specific
} else if (igmp_version == 1) { } else if (igmp_version == 1) {
// general // general
igmp_group = 0; igmp_group = 0;
igmp_group_str = "0.0.0.0"; igmp_group_str = "0.0.0.0";
igmp_group_test = 0; igmp_group_test = 0;
} }
// DST = 224.0.0.1 // DST = 224.0.0.1
//igmp_group = 0; //igmp_group = 0;
//igmp_group_test = 0; //igmp_group_test = 0;
break; break;
case 0x12: // case 0x12: //
default: default:
break; break;
} }
if (ip_src_test if (ip_src_test
&& !(ip_src = && !(ip_src = libnet_name2addr4(netcontext, ip_src_str, LIBNET_RESOLVE)))
libnet_name2addr4(netcontext, ip_src_str, LIBNET_RESOLVE))) { {
fprintf(stderr, "Bad source IP address: %s\n", ip_src_str); fprintf(stderr,"Bad source IP address: %s\n", ip_src_str);
fprintf(stderr, "%s\n", libnet_geterror(netcontext)); fprintf(stderr,"%s\n", libnet_geterror(netcontext));
exit(1); exit(1);
} }
if (ip_dst_test if (ip_dst_test
&& !(ip_dst = && !(ip_dst = libnet_name2addr4(netcontext, ip_dst_str, LIBNET_RESOLVE)))
libnet_name2addr4(netcontext, ip_dst_str, LIBNET_RESOLVE))) { {
fprintf(stderr, "Bad destination IP address: %s\n", ip_dst_str); fprintf(stderr,"Bad destination IP address: %s\n", ip_dst_str);
fprintf(stderr, "%s\n", libnet_geterror(netcontext)); fprintf(stderr,"%s\n", libnet_geterror(netcontext));
exit(1); exit(1);
} }
if (igmp_group_test if (igmp_group_test && !(igmp_group = libnet_name2addr4(netcontext, igmp_group_str, LIBNET_RESOLVE)))
&& !(igmp_group = {
libnet_name2addr4(netcontext, igmp_group_str, LIBNET_RESOLVE))) fprintf(stderr,"Bad group IP address: %s\n", optarg);
{ fprintf(stderr,"%s\n", libnet_geterror(netcontext));
fprintf(stderr, "Bad group IP address: %s\n", optarg); exit(1);
fprintf(stderr, "%s\n", libnet_geterror(netcontext)); }
exit(1);
}
printf(" IP SRC IP = %s\n", ip_src_str); printf(" IP SRC IP = %s\n", ip_src_str);
printf(" IP DEST IP = %s\n", ip_dst_str); printf(" IP DEST IP = %s\n", ip_dst_str);
printf(" IGMP TYPE = 0x%02x\n", igmp_type); printf(" IGMP TYPE = 0x%02x\n", igmp_type);
printf(" IGMP CODE = 0x%02x\n", igmp_code); printf(" IGMP CODE = 0x%02x\n", igmp_code);
printf(" IGMP GROUP = %s\n", igmp_group_str); printf(" IGMP GROUP = %s\n", igmp_group_str);
printf(" GROUP TEST = %d\n", igmp_group_test); printf(" GROUP TEST = %d\n", igmp_group_test);
/* /*
int test = 1; int test = 1;
if ( *(char *) test == 1) { if ( *(char *) test == 1) {
// little endian // little endian
printf("little endian\n"); printf("little endian\n");
} else { } else {
// big endian // big endian
printf("big endian\n"); printf("big endian\n");
} }
*/ */
ptag = libnet_build_igmp(igmp_type, // IGMP type ptag = libnet_build_igmp(
igmp_code, // IGMP code or TTL igmp_type, // IGMP type
0, // checksum igmp_code, // IGMP code or TTL
htonl(igmp_group), // ip addr 0, // checksum
NULL, // Ptr to packet data (or null) htonl(igmp_group), // ip addr
0, // Packet payload length NULL, // Ptr to packet data (or null)
netcontext, // Ptr to libnet context 0, // Packet payload length
0); // Build a new packet header netcontext, // Ptr to libnet context
if (ptag < 0) { 0); // Build a new packet header
fprintf(stderr, if (ptag < 0)
"Error while building IGMP header data (err %d)\n", {
ptag); fprintf(stderr, "Error while building IGMP header data (err %d)\n", ptag);
fprintf(stderr, "%s\n", libnet_geterror(netcontext)); fprintf(stderr,"%s\n", libnet_geterror(netcontext));
exit(1); exit(1);
} }
u_int8_t ipopt[2];
ipopt[0] = IPOPT_RA;
ipopt[1] = 4;
ptag = libnet_build_ipv4_options(ipopt, // options
2, // options_s (length of option string)
netcontext, // libnet context
0 // ptag
);
if (ptag < 0) {
fprintf(stderr,
"Error while building IPv4 options data (err %d)\n",
ptag);
}
ptag = libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_IGMP_H, // pkg size + data u_int8_t ipopt[2];
0, // IP tos ipopt[0] = IPOPT_RA;
getpid(), // IP ID ipopt[1] = 4;
IP_DF, // frag flags and offset ptag = libnet_build_ipv4_options(
1, // TTL ipopt, // options
IPPROTO_IGMP, // transport protocol 2, // options_s (length of option string)
0, // checksum netcontext, // libnet context
ip_src, // source IP 0 // ptag
ip_dst, // destination IP );
NULL, // payload (none) if (ptag < 0)
0, // payload length {
netcontext, // libnet context fprintf(stderr, "Error while building IPv4 options data (err %d)\n", ptag);
0 // build a new header }
);
if (ptag < 0) {
fprintf(stderr,
"Error while building IPv4 header data (err %d)\n",
ptag);
fprintf(stderr, "%s\n", libnet_geterror(netcontext));
exit(1);
}
printf(" done\n"); //IGMP content ptag = libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_IGMP_H, // pkg size + data
0, // IP tos
getpid(), // IP ID
IP_DF, // frag flags and offset
1, // TTL
IPPROTO_IGMP, // transport protocol
0, // checksum
ip_src, // source IP
ip_dst, // destination IP
NULL, // payload (none)
0, // payload length
netcontext, // libnet context
0 // build a new header
);
if (ptag < 0)
{
fprintf(stderr, "Error while building IPv4 header data (err %d)\n", ptag);
fprintf(stderr,"%s\n", libnet_geterror(netcontext));
exit(1);
}
c = libnet_write(netcontext); printf(" done\n"); //IGMP content
if (c < 0) {
fprintf(stderr, "%s\n", libnet_geterror(netcontext));
} else {
printf
("construction and injection completed, wrote all %d bytes\n",
c);
}
/* c = libnet_write(netcontext);
* Free packet memory. if (c < 0)
*/ {
libnet_diag_dump_pblock(netcontext); fprintf(stderr,"%s\n", libnet_geterror(netcontext));
libnet_destroy(netcontext); }
exit(0); else
{
printf("construction and injection completed, wrote all %d bytes\n", c);
}
return (c == -1 ? EXIT_FAILURE : EXIT_SUCCESS); /*
* Free packet memory.
*/
libnet_diag_dump_pblock(netcontext);
libnet_destroy(netcontext);
exit(0);
return (c == -1 ? EXIT_FAILURE : EXIT_SUCCESS);
} }
// vim: ts=4 sts=4 sw=4 et // vim: ts=4 sts=4 sw=4 et

View file

@ -7,30 +7,24 @@
void usage(const char *name) void usage(const char *name)
{ {
ipg_igmp_extra_t *pkt_ptr; ipg_igmp_extra_t *pkt_ptr;
fprintf(stderr, "Usage: %s [options]\n", basename(name)); fprintf(stderr, "Usage: %s [options]\n", basename(name));
fprintf(stderr, "\nOptions:\n"); fprintf(stderr, "\nOptions:\n");
fprintf(stderr, fprintf(stderr, " -i <interface> Specify the network interface (e.g., eth0)\n");
" -i <interface> Specify the network interface (e.g., eth0)\n"); fprintf(stderr, " -t <type> Specify the IGMP packet type and version (e.g., 1.query)\n");
fprintf(stderr, fprintf(stderr, " -g <group> Specify the destination IGMP group (e.g., 224.0.0.1)\n");
" -t <type> Specify the IGMP packet type and version (e.g., 1.query)\n"); fprintf(stderr, " -s <source> Specify the source IP and port (e.g., 192.168.1.1:1234)\n");
fprintf(stderr, fprintf(stderr, " -d <destination> Specify the destination IP and port (e.g., 224.0.0.2:5678)\n");
" -g <group> Specify the destination IGMP group (e.g., 224.0.0.1)\n"); fprintf(stderr, " -n <number> Specify delay between packets in seconds (optional)\n");
fprintf(stderr,
" -s <source> Specify the source IP and port (e.g., 192.168.1.1:1234)\n");
fprintf(stderr,
" -d <destination> Specify the destination IP and port (e.g., 224.0.0.2:5678)\n");
fprintf(stderr,
" -n <number> Specify delay between packets in seconds (optional)\n");
fprintf(stderr, "\nAvailable IGMP packet types:\n"); fprintf(stderr, "\nAvailable IGMP packet types:\n");
pkt_ptr = g_igmp_pkts; pkt_ptr = g_igmp_pkts;
while (pkt_ptr->igmp_version || pkt_ptr->igmp_tag) { while(pkt_ptr->igmp_version || pkt_ptr->igmp_tag){
fprintf(stderr, " - %d.%s\n", pkt_ptr->igmp_version, fprintf(stderr," - %d.%s\n", pkt_ptr->igmp_version, pkt_ptr->igmp_tag);
pkt_ptr->igmp_tag); pkt_ptr++;
pkt_ptr++; }
} fprintf(stderr, "\n");
fprintf(stderr, "\n");
} }