Compare commits

..

3 commits

Author SHA1 Message Date
c92f1580df chore: re-indent code (linux style)
Some checks failed
continuous-integration/drone/push Build is failing
2023-12-27 10:24:06 +01:00
429f9aced8 chore: merge run.sh and build.sh as makefile 2023-12-27 10:23:44 +01:00
61a4872d88 doc: add manpage for igmpgen 2023-12-27 10:23:13 +01:00
8 changed files with 454 additions and 342 deletions

View file

@ -33,6 +33,9 @@ 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")

24
Makefile Normal file
View file

@ -0,0 +1,24 @@
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

View file

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

86
misc/igmpgen.man.1 Normal file
View file

@ -0,0 +1,86 @@
.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
View file

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

View file

@ -2,31 +2,30 @@
#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,356 +17,358 @@ 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, char *igmp_request) { ipg_igmp_extra_t *igmp_packet_type_find(u_int8_t igmp_version,
ipg_igmp_extra_t *pkt_ptr; char *igmp_request)
{
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) {
switch (c) case 'i':
{ printf(" Net interface = [%s]\n", optarg);
case 'i': device = optarg;
printf(" Net interface = [%s]\n",optarg); break;
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", igmp_version, cp); printf("ERROR: Packet type %d.%s not found!\n",
usage(argv[0]); igmp_version, cp);
exit(1); usage(argv[0]);
} 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", pkt_ptr->igmp_tag, igmp_version); printf(" Packet = [%s] version [%d]\n",
break; pkt_ptr->igmp_tag, igmp_version);
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;
*cp++ = 0; dst_prt = (u_short) atoi(cp);
dst_prt = (u_short)atoi(cp); } else {
} else { dst_prt = 0;
dst_prt = 0; }
} ip_dst_str = strdup(optarg);
ip_dst_str = strdup(optarg); printf(" Destination = ip [%s] port [%d]\n",
printf(" Destination = ip [%s] port [%d]\n", ip_dst_str, dst_prt); ip_dst_str, dst_prt);
break; break;
case 's': case 's':
if ((cp = strrchr(optarg, ':'))) if ((cp = strrchr(optarg, ':'))) {
{ *cp++ = 0;
*cp++ = 0; src_prt = (u_short) atoi(cp);
src_prt = (u_short)atoi(cp); } else {
} else { src_prt = 0;
src_prt = 0; }
} ip_src_str = strdup(optarg);
ip_src_str = strdup(optarg); printf(" Source = ip [%s] port [%d]\n", ip_src_str,
printf(" Source = ip [%s] port [%d]\n", ip_src_str, src_prt); 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]);
usage(argv[0]); fprintf(stderr, "ERROR: missing destination IGMP group\n");
fprintf(stderr, "ERROR: missing destination IGMP group\n"); exit(EXIT_FAILURE);
exit(EXIT_FAILURE); }
}
if (!device) if (!device) {
{ usage(argv[0]);
usage(argv[0]); fprintf(stderr, "ERROR: missing device\n");
fprintf(stderr, "ERROR: missing device\n"); exit(EXIT_FAILURE);
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( ptag = libnet_build_igmp(igmp_type, // IGMP type
igmp_type, // IGMP type igmp_code, // IGMP code
igmp_code, // IGMP code 0, // checksum
0, // checksum 0, // group address
0, // group address NULL, // payload
NULL, // payload 0, // payload size
0, // payload size netcontext, // libnet context
netcontext, // libnet context 0 // ptag
0 // ptag );
); if (ptag == -1) {
if (ptag == -1) { fprintf(stderr, "Error building IGMP header: %s\n",
fprintf(stderr, "Error building IGMP header: %s\n", libnet_geterror(netcontext)); 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", libnet_geterror(netcontext)); fprintf(stderr, "Error sending packet: %s\n",
} else { libnet_geterror(netcontext));
printf("Packet sent successfully.\n"); } else {
} 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 = libnet_name2addr4(netcontext, ip_src_str, LIBNET_RESOLVE))) && !(ip_src =
{ 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 = libnet_name2addr4(netcontext, ip_dst_str, LIBNET_RESOLVE))) && !(ip_dst =
{ 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 && !(igmp_group = libnet_name2addr4(netcontext, igmp_group_str, LIBNET_RESOLVE))) if (igmp_group_test
{ && !(igmp_group =
fprintf(stderr,"Bad group IP address: %s\n", optarg); libnet_name2addr4(netcontext, igmp_group_str, LIBNET_RESOLVE)))
fprintf(stderr,"%s\n", libnet_geterror(netcontext)); {
exit(1); 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 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( ptag = libnet_build_igmp(igmp_type, // IGMP type
igmp_type, // IGMP type igmp_code, // IGMP code or TTL
igmp_code, // IGMP code or TTL 0, // checksum
0, // checksum htonl(igmp_group), // ip addr
htonl(igmp_group), // ip addr NULL, // Ptr to packet data (or null)
NULL, // Ptr to packet data (or null) 0, // Packet payload length
0, // Packet payload length netcontext, // Ptr to libnet context
netcontext, // Ptr to libnet context 0); // Build a new packet header
0); // Build a new packet header if (ptag < 0) {
if (ptag < 0) fprintf(stderr,
{ "Error while building IGMP header data (err %d)\n",
fprintf(stderr, "Error while building IGMP header data (err %d)\n", ptag); 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);
}
u_int8_t ipopt[2]; ptag = libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_IGMP_H, // pkg size + data
ipopt[0] = IPOPT_RA; 0, // IP tos
ipopt[1] = 4; getpid(), // IP ID
ptag = libnet_build_ipv4_options( IP_DF, // frag flags and offset
ipopt, // options 1, // TTL
2, // options_s (length of option string) IPPROTO_IGMP, // transport protocol
netcontext, // libnet context 0, // checksum
0 // ptag ip_src, // source IP
); ip_dst, // destination IP
if (ptag < 0) NULL, // payload (none)
{ 0, // payload length
fprintf(stderr, "Error while building IPv4 options data (err %d)\n", ptag); 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);
}
ptag = libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_IGMP_H, // pkg size + data printf(" done\n"); //IGMP content
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);
}
printf(" done\n"); //IGMP content 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);
}
c = libnet_write(netcontext); /*
if (c < 0) * Free packet memory.
{ */
fprintf(stderr,"%s\n", libnet_geterror(netcontext)); libnet_diag_dump_pblock(netcontext);
} libnet_destroy(netcontext);
else exit(0);
{
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,24 +7,30 @@
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, " -i <interface> Specify the network interface (e.g., eth0)\n"); fprintf(stderr,
fprintf(stderr, " -t <type> Specify the IGMP packet type and version (e.g., 1.query)\n"); " -i <interface> Specify the network interface (e.g., eth0)\n");
fprintf(stderr, " -g <group> Specify the destination IGMP group (e.g., 224.0.0.1)\n"); fprintf(stderr,
fprintf(stderr, " -s <source> Specify the source IP and port (e.g., 192.168.1.1:1234)\n"); " -t <type> Specify the IGMP packet type and version (e.g., 1.query)\n");
fprintf(stderr, " -d <destination> Specify the destination IP and port (e.g., 224.0.0.2:5678)\n"); fprintf(stderr,
fprintf(stderr, " -n <number> Specify delay between packets in seconds (optional)\n"); " -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; 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, pkt_ptr->igmp_tag); fprintf(stderr, " - %d.%s\n", pkt_ptr->igmp_version,
pkt_ptr++; pkt_ptr->igmp_tag);
} pkt_ptr++;
fprintf(stderr, "\n"); }
fprintf(stderr, "\n");
} }