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

View file

@ -7,30 +7,24 @@
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, "\nOptions:\n");
fprintf(stderr,
" -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,
" -g <group> Specify the destination IGMP group (e.g., 224.0.0.1)\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, "Usage: %s [options]\n", basename(name));
fprintf(stderr, "\nOptions:\n");
fprintf(stderr, " -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, " -g <group> Specify the destination IGMP group (e.g., 224.0.0.1)\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;
while (pkt_ptr->igmp_version || pkt_ptr->igmp_tag) {
fprintf(stderr, " - %d.%s\n", pkt_ptr->igmp_version,
pkt_ptr->igmp_tag);
pkt_ptr++;
}
fprintf(stderr, "\n");
pkt_ptr = g_igmp_pkts;
while(pkt_ptr->igmp_version || pkt_ptr->igmp_tag){
fprintf(stderr," - %d.%s\n", pkt_ptr->igmp_version, pkt_ptr->igmp_tag);
pkt_ptr++;
}
fprintf(stderr, "\n");
}