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

@ -29,4 +29,3 @@ typedef struct {
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

@ -32,7 +32,9 @@ ipg_igmp_extra_t g_igmp_pkts[] = {
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,
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;
@ -85,10 +87,8 @@ int main(int argc, char **argv)
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': case 'i':
printf(" Net interface = [%s]\n", optarg); printf(" Net interface = [%s]\n", optarg);
device = optarg; device = optarg;
@ -105,7 +105,8 @@ int main(int argc, char **argv)
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",
igmp_version, cp);
usage(argv[0]); usage(argv[0]);
exit(1); exit(1);
} }
@ -114,7 +115,8 @@ int main(int argc, char **argv)
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",
pkt_ptr->igmp_tag, igmp_version);
break; break;
case 'g': case 'g':
@ -135,27 +137,27 @@ int main(int argc, char **argv)
* 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", 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; *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, src_prt); printf(" Source = ip [%s] port [%d]\n", ip_src_str,
src_prt);
break; break;
default: default:
@ -164,15 +166,13 @@ int main(int argc, char **argv)
} }
} }
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);
@ -198,8 +198,7 @@ int main(int argc, char **argv)
/* 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
@ -209,7 +208,8 @@ int main(int argc, char **argv)
0 // ptag 0 // ptag
); );
if (ptag == -1) { if (ptag == -1) {
fprintf(stderr, "Error building IGMP header: %s\n", 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);
} }
@ -218,7 +218,8 @@ int main(int argc, char **argv)
/* 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",
libnet_geterror(netcontext));
} else { } else {
printf("Packet sent successfully.\n"); printf("Packet sent successfully.\n");
} }
@ -255,22 +256,24 @@ int main(int argc, char **argv)
} }
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 =
libnet_name2addr4(netcontext, igmp_group_str, LIBNET_RESOLVE)))
{ {
fprintf(stderr, "Bad group IP address: %s\n", optarg); fprintf(stderr, "Bad group IP address: %s\n", optarg);
fprintf(stderr, "%s\n", libnet_geterror(netcontext)); fprintf(stderr, "%s\n", libnet_geterror(netcontext));
@ -295,8 +298,7 @@ int main(int argc, char **argv)
} }
*/ */
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
@ -304,26 +306,26 @@ int main(int argc, char **argv)
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,
fprintf(stderr, "Error while building IGMP header data (err %d)\n", ptag); "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]; u_int8_t ipopt[2];
ipopt[0] = IPOPT_RA; ipopt[0] = IPOPT_RA;
ipopt[1] = 4; ipopt[1] = 4;
ptag = libnet_build_ipv4_options( ptag = libnet_build_ipv4_options(ipopt, // options
ipopt, // options
2, // options_s (length of option string) 2, // options_s (length of option string)
netcontext, // libnet context netcontext, // libnet context
0 // ptag 0 // ptag
); );
if (ptag < 0) if (ptag < 0) {
{ fprintf(stderr,
fprintf(stderr, "Error while building IPv4 options data (err %d)\n", ptag); "Error while building IPv4 options data (err %d)\n",
ptag);
} }
ptag = libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_IGMP_H, // pkg size + data ptag = libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_IGMP_H, // pkg size + data
@ -340,9 +342,10 @@ int main(int argc, char **argv)
netcontext, // libnet context netcontext, // libnet context
0 // build a new header 0 // build a new header
); );
if (ptag < 0) if (ptag < 0) {
{ fprintf(stderr,
fprintf(stderr, "Error while building IPv4 header data (err %d)\n", ptag); "Error while building IPv4 header data (err %d)\n",
ptag);
fprintf(stderr, "%s\n", libnet_geterror(netcontext)); fprintf(stderr, "%s\n", libnet_geterror(netcontext));
exit(1); exit(1);
} }
@ -350,13 +353,12 @@ int main(int argc, char **argv)
printf(" done\n"); //IGMP content printf(" done\n"); //IGMP content
c = libnet_write(netcontext); c = libnet_write(netcontext);
if (c < 0) if (c < 0) {
{
fprintf(stderr, "%s\n", libnet_geterror(netcontext)); fprintf(stderr, "%s\n", libnet_geterror(netcontext));
} } else {
else printf
{ ("construction and injection completed, wrote all %d bytes\n",
printf("construction and injection completed, wrote all %d bytes\n", c); c);
} }
/* /*

View file

@ -11,20 +11,26 @@ void usage(const char *name)
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->igmp_tag);
pkt_ptr++; pkt_ptr++;
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }