summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Kochan <vadim4j@gmail.com>2015-03-02 13:16:55 +0200
committerTobias Klauser <tklauser@distanz.ch>2015-03-17 11:45:33 +0100
commit6f542884d002d55d517a50dd9892068e95400b25 (patch)
tree6d1075d2ae80cf6deb83cb361518890dc8d66d1a
parent814902086268083d4d024853027fdc99b345ebf9 (diff)
mz: Add igmp v1/v2 packet type crafting support
Signed-off-by: Vadim Kochan <vadim4j@gmail.com> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
-rw-r--r--staging/layer3.c18
-rw-r--r--staging/layer4.c101
-rw-r--r--staging/mausezahn.c28
-rw-r--r--staging/mz.h38
4 files changed, 153 insertions, 32 deletions
diff --git a/staging/layer3.c b/staging/layer3.c
index 3eca55d..0b17db1 100644
--- a/staging/layer3.c
+++ b/staging/layer3.c
@@ -154,17 +154,14 @@ libnet_ptag_t create_ip_packet (libnet_t *l)
tx.ip_frag = 0; // Flags and Offset !!!
tx.ip_sum = 0; // default: automatically calculate checksum
tx.ip_tos = 0;
- tx.ip_ttl = 255;
-
// temporary variables
unsigned int dummy;
size_t len;
char *s;
-
T = tx.packet_mode; // >0 means automatic L2 creation
-
+
if ( (getarg(tx.arg_string,"help", NULL)==1) && (mode==IP) )
{
if (mz_port)
@@ -284,13 +281,12 @@ libnet_ptag_t create_ip_packet (libnet_t *l)
{
tx.ip_frag |= 0x8000;
}
-
-
- if (getarg(tx.arg_string,"ttl", argval)==1)
- {
- tx.ip_ttl = (u_int8_t) str2int(argval);
- }
-
+
+ if (getarg(tx.arg_string, "ttl", argval) == 1)
+ tx.ip_ttl = (u_int8_t)str2int(argval);
+ else if (tx.ip_ttl == 0)
+ tx.ip_ttl = 255;
+
if (getarg(tx.arg_string,"proto", argval)==1)
{
tx.ip_proto = (u_int8_t) str2int(argval);
diff --git a/staging/layer4.c b/staging/layer4.c
index a4431a1..8ccf80c 100644
--- a/staging/layer4.c
+++ b/staging/layer4.c
@@ -136,7 +136,32 @@
"| Of course all Ethernet fields can also be accessed.\n"\
"|\n"
+#define MZ_IGMP_HELP \
+ "| IGMP type: Send raw IGMP packets.\n" \
+ "|\n" \
+ "| Parameters Values Explanation \n" \
+ "| ---------- ------------------------------------ -------------------\n" \
+ "| v,ver 1-2 version\n" \
+ "| t,type packet type:\n" \
+ "| q,qry,query - memberhsip query\n" \
+ "| j,join - join group\n" \
+ "| l,lv,leave - leave group\n" \
+ "| resp_time max response time (v2 only)\n" \
+ "| igmp_sum checksum (optional)\n" \
+ "| g,group group ipv4 address\n" \
+ "\n"
+int print_packet_help(char *help)
+{
+ if (mz_port) {
+ cli_print(gcli, "%s", help);
+ } else {
+ fprintf(stderr,"\n" MAUSEZAHN_VERSION "\n%s", help);
+ exit(0);
+ }
+
+ return -1;
+}
// Note: If another function specified tx.udp_payload then it must also
// set tx.udp_payload_s AND tx.udp_len = tx.udp_payload_s + 8
@@ -884,3 +909,79 @@ libnet_ptag_t create_tcp_packet (libnet_t *l)
return t;
}
+
+libnet_ptag_t create_igmp_packet(libnet_t *l)
+{
+ libnet_ptag_t t;
+ char argval[MAX_PAYLOAD_SIZE];
+ int ver = 2;
+ uint8_t type = IGMP_MEMBERSHIP_QUERY;
+ uint8_t resp_time = 10;
+ uint16_t sum = 0;
+ uint32_t group = 0;
+
+ if ((getarg(tx.arg_string, "help", NULL) == 1) && (mode == IGMP))
+ return print_packet_help(MZ_IGMP_HELP);
+
+ if (getarg(tx.arg_string, "ver", argval) == 1 ||
+ getarg(tx.arg_string, "v", argval) == 1) {
+
+ ver = str2int(argval);
+ if (ver == 1)
+ resp_time = 0;
+ }
+
+ if (getarg(tx.arg_string, "type", argval) == 1 ||
+ getarg(tx.arg_string, "t", argval) == 1) {
+
+ if (strcmp("j", argval) == 0 || strcmp("join", argval) == 0) {
+
+ if (ver == 1)
+ type = IGMP_V1_MEMBERSHIP_REPORT;
+ else if (ver == 2)
+ type = IGMP_V2_MEMBERSHIP_REPORT;
+
+ } else if (strcmp("l", argval) == 0 || strcmp("lv", argval) == 0 ||
+ strcmp("leave", argval) == 0) {
+
+ type = IGMP_LEAVE_GROUP;
+ }
+ }
+
+ if (getarg(tx.arg_string, "resp_time", argval) == 1)
+ resp_time = (uint8_t)str2int(argval);
+
+ if (getarg(tx.arg_string, "igmp_sum", argval) == 1)
+ sum = (uint16_t)str2int(argval);
+
+ if (getarg(tx.arg_string, "group", argval) == 1 ||
+ getarg(tx.arg_string, "g", argval) == 1) {
+
+ group = str2ip32_rev(argval);
+ }
+
+ if (type == IGMP_LEAVE_GROUP) {
+ tx.ip_dst = str2ip32_rev("224.0.0.2");
+ } else if (type == IGMP_MEMBERSHIP_QUERY) {
+ if (ver == 1 || group == 0)
+ tx.ip_dst = str2ip32_rev("224.0.0.1");
+ else if (ver == 2 && group != 0)
+ tx.ip_dst = group;
+ } else if (type == IGMP_V1_MEMBERSHIP_REPORT ||
+ type == IGMP_V2_MEMBERSHIP_REPORT) {
+
+ tx.ip_dst = group;
+ }
+
+ if (getarg(tx.arg_string, "ttl", argval) == 0)
+ tx.ip_ttl = 1;
+
+ t = libnet_build_igmp(type, resp_time, sum, group, NULL, 0, l, 0);
+ if (t == -1) {
+ fprintf(stderr, " mz/create_igmp_packet: Can't build IGMP header: %s\n",
+ libnet_geterror(l));
+ exit (0);
+ }
+
+ return t;
+}
diff --git a/staging/mausezahn.c b/staging/mausezahn.c
index c06a1d8..5051bcb 100644
--- a/staging/mausezahn.c
+++ b/staging/mausezahn.c
@@ -281,6 +281,7 @@ int reset(void)
tx.ip_dst_stop = 0;
tx.ip_dst_isrange = 0;
+ tx.ip_ttl = 0;
tx.ip_len = 0;
tx.ip_payload[0]= '\0';
tx.ip_payload_s = 0;
@@ -361,6 +362,7 @@ static void print_packet_types(void)
"| udp ... sends UDP datagrams\n"
"| tcp ... sends TCP segments\n"
"| icmp ... sends ICMP messages\n"
+ "| igmp ... sends IGMP messages\n"
"| dns ... sends DNS messages\n"
"| rtp ... sends RTP datagrams\n"
"| syslog ... sends Syslog messages\n"
@@ -814,6 +816,9 @@ int getopts (int argc, char *argv[])
else if (strcmp(packet_type,"syslog")==0) {
mode = SYSLOG;
}
+ else if (strcmp(packet_type, "igmp") == 0) {
+ mode = IGMP;
+ }
else if (strcmp(packet_type,"lldp")==0) {
mode = LLDP;
tx.packet_mode=0; // create whole frame by ourself
@@ -928,9 +933,9 @@ int main(int argc, char **argv)
else
send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
break;
-
+
case TCP:
- tx.ip_proto = 6;
+ tx.ip_proto = 6;
l = get_link_context();
t4 = create_tcp_packet(l); // t4 can be used for later header changes
t3 = create_ip_packet(l); // t3 can be used for later header changes
@@ -942,7 +947,24 @@ int main(int argc, char **argv)
else
send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
break;
-
+
+ case IGMP:
+ tx.ip_proto = 2;
+ l = get_link_context();
+ t4 = create_igmp_packet(l);
+ /* t3 can be used for later header changes */
+ t3 = create_ip_packet(l);
+ if (!quiet)
+ complexity();
+
+ /* Ethernet manipulation features does NOT use ARP to determine eth_dst
+ * */
+ if (tx.packet_mode == 0)
+ t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
+ else
+ send_frame(l, t3, t4); // NOTE: send_frame also destroys context finaly
+ break;
+
case DNS:
tx.ip_proto = 17;
l = get_link_context();
diff --git a/staging/mz.h b/staging/mz.h
index ade4da3..339be31 100644
--- a/staging/mz.h
+++ b/staging/mz.h
@@ -256,20 +256,21 @@ struct struct_rtp {
enum operating_modes
{
- BYTE_STREAM,
- ARP,
- BPDU,
- IP,
- ICMP,
- ICMP6,
- UDP,
- TCP,
- DNS,
- CDP,
- RTP,
- RX_RTP,
- SYSLOG,
- LLDP
+ BYTE_STREAM,
+ ARP,
+ BPDU,
+ IP,
+ ICMP,
+ ICMP6,
+ UDP,
+ TCP,
+ DNS,
+ CDP,
+ RTP,
+ RX_RTP,
+ SYSLOG,
+ LLDP,
+ IGMP
} mode;
@@ -561,10 +562,11 @@ int send_frame (libnet_t *l, libnet_ptag_t t3, libnet_ptag_t t4);
// Prototypes: Layer 4
//
// ************************************
-libnet_ptag_t create_udp_packet (libnet_t *l);
-libnet_ptag_t create_icmp_packet (libnet_t *l);
-libnet_ptag_t create_icmp6_packet (libnet_t *l);
-libnet_ptag_t create_tcp_packet (libnet_t *l);
+libnet_ptag_t create_udp_packet(libnet_t *l);
+libnet_ptag_t create_icmp_packet(libnet_t *l);
+libnet_ptag_t create_icmp6_packet(libnet_t *l);
+libnet_ptag_t create_tcp_packet(libnet_t *l);
+libnet_ptag_t create_igmp_packet(libnet_t *l);
// ************************************