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
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")

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[];
#endif /* IGP_TYPES_H */

View file

@ -18,28 +18,30 @@ 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 },
{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 },
{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 *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){
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)){
&& (igmp_version == pkt_ptr->igmp_version)) {
return pkt_ptr;
}
pkt_ptr++;
@ -69,7 +71,7 @@ int main(int argc, char **argv)
int ip_src_test = 1;
int ip_dst_test = 1;
int igmp_group_test =1;
int igmp_group_test = 1;
/* libnet stuff */
char neterr[LIBNET_ERRBUF_SIZE];
@ -85,12 +87,10 @@ int main(int argc, char **argv)
printf("Detected options:\n");
/* Parsing command line */
while((c = getopt(argc, argv, "i:t:g:d:s:")) != EOF)
{
switch (c)
{
while ((c = getopt(argc, argv, "i:t:g:d:s:")) != EOF) {
switch (c) {
case 'i':
printf(" Net interface = [%s]\n",optarg);
printf(" Net interface = [%s]\n", optarg);
device = optarg;
break;
@ -101,11 +101,12 @@ int main(int argc, char **argv)
}
*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);
printf("ERROR: Packet type %d.%s not found!\n",
igmp_version, cp);
usage(argv[0]);
exit(1);
}
@ -114,7 +115,8 @@ int main(int argc, char **argv)
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);
printf(" Packet = [%s] version [%d]\n",
pkt_ptr->igmp_tag, igmp_version);
break;
case 'g':
@ -135,27 +137,27 @@ int main(int argc, char **argv)
* 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);
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);
printf(" Destination = ip [%s] port [%d]\n",
ip_dst_str, dst_prt);
break;
case 's':
if ((cp = strrchr(optarg, ':')))
{
if ((cp = strrchr(optarg, ':'))) {
*cp++ = 0;
src_prt = (u_short)atoi(cp);
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);
printf(" Source = ip [%s] port [%d]\n", ip_src_str,
src_prt);
break;
default:
@ -164,15 +166,13 @@ int main(int argc, char **argv)
}
}
if (!igmp_group_str)
{
if (!igmp_group_str) {
usage(argv[0]);
fprintf(stderr, "ERROR: missing destination IGMP group\n");
exit(EXIT_FAILURE);
}
if (!device)
{
if (!device) {
usage(argv[0]);
fprintf(stderr, "ERROR: missing device\n");
exit(EXIT_FAILURE);
@ -198,8 +198,7 @@ int main(int argc, char **argv)
/* Packet construction: IGMP */
printf(" Building IGMP content...\n");
ptag = libnet_build_igmp(
igmp_type, // IGMP type
ptag = libnet_build_igmp(igmp_type, // IGMP type
igmp_code, // IGMP code
0, // checksum
0, // group address
@ -209,7 +208,8 @@ int main(int argc, char **argv)
0 // ptag
);
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);
exit(EXIT_FAILURE);
}
@ -218,7 +218,8 @@ int main(int argc, char **argv)
/* Send packet */
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 {
printf("Packet sent successfully.\n");
}
@ -235,9 +236,9 @@ int main(int argc, char **argv)
ip_dst_str = igmp_group_str;
}
switch ( igmp_type ) {
switch (igmp_type) {
case 0x11: // IGMP_MEMBERSHIP_QUERY
if (igmp_version == 2){
if (igmp_version == 2) {
// group specific
} else if (igmp_version == 1) {
// general
@ -255,25 +256,27 @@ int main(int argc, char **argv)
}
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));
&& !(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));
&& !(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)))
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));
fprintf(stderr, "Bad group IP address: %s\n", optarg);
fprintf(stderr, "%s\n", libnet_geterror(netcontext));
exit(1);
}
@ -295,8 +298,7 @@ int main(int argc, char **argv)
}
*/
ptag = libnet_build_igmp(
igmp_type, // IGMP type
ptag = libnet_build_igmp(igmp_type, // IGMP type
igmp_code, // IGMP code or TTL
0, // checksum
htonl(igmp_group), // ip addr
@ -304,26 +306,26 @@ int main(int argc, char **argv)
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));
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
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);
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
@ -340,23 +342,23 @@ int main(int argc, char **argv)
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));
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);
if (c < 0) {
fprintf(stderr, "%s\n", libnet_geterror(netcontext));
} else {
printf
("construction and injection completed, wrote all %d bytes\n",
c);
}
/*

View file

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