The initially submitted patch is unfortunately incomplete.
Here comes a more complete and hopefully more attractive
patch suggestion.

The patch is a git formatted text, built on top of #714256.
Please consider attending to both, as the present patch
version was instrumental in resolving #710403 for rarpd.

Regards,
  Mats Erik Andersson, maintainer of rarpd, DM
>From b1c6b5d4b1ca5da459fca5baebb97994cee9b15d Mon Sep 17 00:00:00 2001
From: Mats Erik Andersson <g...@gisladisker.se>
Date: Thu, 27 Jun 2013 11:36:00 +0200
Subject: [PATCH 3/3] Implement RARP packet support.

With limited modifications of existing
ARP code, it is possible to enhance the
source to produce and distinguish also
RARP packets.
---
 man/packit.8.in          | 15 ++++++++-------
 src/main.c               | 17 +++++++++++++++++
 src/print_arp_hdr.c      |  7 ++++++-
 src/print_capture.c      |  6 ++++--
 src/print_injection.c    | 10 +++++++---
 src/shape_ethernet_hdr.c |  7 ++++---
 src/shape_ethernet_hdr.h |  2 +-
 src/shape_packet.c       |  5 +++--
 src/usage.c              |  5 +++--
 9 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/man/packit.8.in b/man/packit.8.in
index 2f69b2f..f6d1b19 100644
--- a/man/packit.8.in
+++ b/man/packit.8.in
@@ -143,10 +143,11 @@ and general TCP/IP auditing.
 Specify the type of packet to inject. Supported values are: \fBARP\fR, 
 .br
 .ti +5
-\fBTCP\fR, \fBUDP\fR and \fBICMP\fR. This option defaults to \fBTCP\fR 
+\fBRARP\fR, \fBTCP\fR, \fBUDP\fR and \fBICMP\fR.
+This option defaults to \fBTCP\fR in inject
 .br
 .ti +5
-in inject mode and ICMP in trace mode. 
+mode and to \fBICMP\fR in trace mode.
 .br
 
 .SH PACKET INJECTION / TRACE GENERAL
@@ -683,13 +684,13 @@ Define the 32-bit transmit timestamp. This value is 0
 by default.
 .br
 
-.SH ARP HEADER OPTIONS
-This section documents the ARP header command-line options. In my opinion, 
+.SH ARP AND RARP HEADER OPTIONS
+This section documents the ARP/RARP header command-line options. In my opinion,
 these options have the ability to do the most damage with the least effort, especially 
 on large cable and DSL networks. Use with caution. 
 .br
 
-Packit only supports ARP protocol addresses in IPv4 format
+Packit only supports ARP/RARP protocol addresses in IPv4 format
 
 \fB-A\fR \fIoperation type\fR
 .br
@@ -701,13 +702,13 @@ are as follows:
 .br
 
 .ti +5
-- 1 : ARP Request   
+- 1 : ARP Request (Default for ARP packages.)
 .br
 .ti +5
 - 2 : ARP Reply    
 .br
 .ti +5
-- 3 : Reverse ARP Request  
+- 3 : Reverse ARP Request (Default for RARP packages.)
 .br
 .ti +5
 - 4 : Reverse ARP Reply
diff --git a/src/main.c b/src/main.c
index 3cb3d5f..f7b6eea 100644
--- a/src/main.c
+++ b/src/main.c
@@ -158,6 +158,23 @@ parse_inject_options(int argc, char *argv[], u_int16_t iopt)
                     opts = "A:b:c:e:E:i:p:Rs:S:vx:X:y:Y:";
                 }
                 else
+                if(!strncasecmp(optarg, "RARP", 4))
+                {
+                    if(p_mode == M_TRACE)
+                        fatal_error("RARP is not supported with trace mode.");
+#ifdef DEBUG
+                    fprintf(stdout, "DEBUG: RARP injection\n");
+#endif
+#ifdef MACOS
+                    fprintf(stderr, "\nError: RARP injection is not yet supported on this OS platform.\n");
+                    exit(FAILURE);
+#endif
+                    injection_type = ETHERTYPE_REVARP;
+                    ahdr_o.op_type = ARPOP_REVREQUEST; /* Update init */
+                    init_type = 0;
+                    opts = "A:b:c:e:E:i:p:Rs:S:vx:X:y:Y:";
+                }
+                else
                 if(!strncasecmp(optarg, "RAWIP", 3)) 
                 { 
                     if(p_mode == M_TRACE)
diff --git a/src/print_arp_hdr.c b/src/print_arp_hdr.c
index 24f52d2..85eeeb3 100644
--- a/src/print_arp_hdr.c
+++ b/src/print_arp_hdr.c
@@ -26,6 +26,7 @@ void
 print_arp_hdr(u_int8_t *packet)
 {
     u_int8_t *arp_t, *arp_hw_t;
+    u_int16_t frame_t;
     
     struct libnet_arp_hdr *ahdr;
 
@@ -38,7 +39,11 @@ print_arp_hdr(u_int8_t *packet)
     arp_t = retrieve_arp_type(htons(ahdr->ar_op));
     arp_hw_t = retrieve_arp_hw_type(htons(ahdr->ar_hrd));
 
-    fprintf(stdout, "ARP header:  Type: %s(%d)\n", arp_t, htons(ahdr->ar_op));
+    frame_t = ntohs(*(u_int16_t *)(packet + hdr_len - sizeof(u_int16_t)));
+
+    fprintf(stdout, "%s header:  Type: %s(%d)\n",
+            (frame_t == ETHERTYPE_REVARP) ? "RARP": "ARP",
+            arp_t, htons(ahdr->ar_op));
     fprintf(stdout, "     Hardware Format: %s  Length: %d\n",
         arp_hw_t, 
 	ahdr->ar_hln);
diff --git a/src/print_capture.c b/src/print_capture.c
index a59847b..a2d0d51 100644
--- a/src/print_capture.c
+++ b/src/print_capture.c
@@ -96,10 +96,12 @@ print_capture(struct pcap_pkthdr *pkthdr, u_int8_t *packet)
             }
         }
         else 
-        if(ehdr->ether_type == htons(ETHERTYPE_ARP))
+        if(ehdr->ether_type == htons(ETHERTYPE_ARP)
+           || ehdr->ether_type == htons(ETHERTYPE_REVARP))
         {
 #ifdef DEBUG
-            fprintf(stdout, "DEBUG: ether_type: ARP\n");
+            fprintf(stdout, "DEBUG: ether_type: %s\n",
+                    (ehdr->ether_type == ETHERTYPE_REVARP) ? "RARP" : "ARP");
 #endif
 
             if(p_mode == M_CAPTURE)
diff --git a/src/print_injection.c b/src/print_injection.c
index a1d8cd8..4b5c83b 100644
--- a/src/print_injection.c
+++ b/src/print_injection.c
@@ -170,15 +170,19 @@ print_injection_details()
                 ehdr_o.dhw_addr);
     }
     else
-    if(injection_type == ETHERTYPE_ARP)
+    if(injection_type == ETHERTYPE_ARP
+	|| injection_type == ETHERTYPE_REVARP)
     {
 #ifdef DEBUG
-       fprintf(stdout, "DEBUG: ETHERTYPE_ARP\n");
+       fprintf(stdout, "DEBUG: %s\n",
+		(injection_type == ETHERTYPE_REVARP) ? "ETHERTYPE_REVARP" : "ETHERTYPE_ARP");
 #endif
 
 	arp_t = retrieve_arp_type(ahdr_o.op_type);
 
-	fprintf(stdout, "ARP header:  Type: %s(%d)\n", arp_t, ahdr_o.op_type);
+	fprintf(stdout, "%s header:  Type: %s(%d)\n",
+		(injection_type == ETHERTYPE_REVARP) ? "RARP" : "ARP",
+		arp_t, ahdr_o.op_type);
 	fprintf(stdout, "     Sender:  Protocol Address: %s  Hardware Address: %.17s\n",
 	    ahdr_o.s_paddr,
 	    ahdr_o.shw_addr); 
diff --git a/src/shape_ethernet_hdr.c b/src/shape_ethernet_hdr.c
index 1c0297c..3612201 100644
--- a/src/shape_ethernet_hdr.c
+++ b/src/shape_ethernet_hdr.c
@@ -59,7 +59,8 @@ shape_ethernet_hdr(libnet_t *pkt_d)
     snprintf(ehdr_o.shw_addr, 18, "%0X:%0X:%0X:%0X:%0X:%0X",
         us_addr[0], us_addr[1], us_addr[2], us_addr[3], us_addr[4], us_addr[5]);
 
-    if(ehdr_o.d_addr == NULL && injection_type == ETHERTYPE_ARP)
+    if(ehdr_o.d_addr == NULL
+       && (injection_type == ETHERTYPE_ARP || injection_type == ETHERTYPE_REVARP))
 	ehdr_o.d_addr = ETH_BROADCAST; 
     else
     if(ehdr_o.d_addr == NULL)
@@ -90,7 +91,7 @@ shape_ethernet_hdr(libnet_t *pkt_d)
 }
 
 libnet_t *
-shape_ethernet_hdr_auto(libnet_t *pkt_d)
+shape_ethernet_hdr_auto(libnet_t *pkt_d, u_int16_t type)
 {
     u_int8_t d_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
@@ -100,7 +101,7 @@ shape_ethernet_hdr_auto(libnet_t *pkt_d)
 
     if(libnet_autobuild_ethernet(
         d_addr,                 
-        ETHERTYPE_ARP, 
+        type,
         pkt_d) == -1)
     {
         fatal_error("Unable to auto-build ethernet header");
diff --git a/src/shape_ethernet_hdr.h b/src/shape_ethernet_hdr.h
index ac1b0cc..0e77931 100644
--- a/src/shape_ethernet_hdr.h
+++ b/src/shape_ethernet_hdr.h
@@ -28,6 +28,6 @@
 #include "utils.h"
 
 libnet_t *shape_ethernet_hdr(libnet_t *pkt_d);
-libnet_t *shape_ethernet_hdr_auto(libnet_t *pkt_d);
+libnet_t *shape_ethernet_hdr_auto(libnet_t *pkt_d, u_int16_t);
 
 #endif /* __SHAPE_ETHERNET_H */
diff --git a/src/shape_packet.c b/src/shape_packet.c
index 6417060..0f84f93 100644
--- a/src/shape_packet.c
+++ b/src/shape_packet.c
@@ -62,6 +62,7 @@ shape_packet()
             break;
 
         case ETHERTYPE_ARP:
+        case ETHERTYPE_REVARP:
             if((pkt_d = shape_arp_hdr(pkt_d)) == NULL)
                 return pkt_d;
 
@@ -74,8 +75,8 @@ shape_packet()
             return pkt_d;
     }
     else
-    if(injection_type == ETHERTYPE_ARP)
-        if((pkt_d = shape_ethernet_hdr_auto(pkt_d)) == NULL)
+    if(injection_type == ETHERTYPE_ARP || injection_type == ETHERTYPE_REVARP)
+        if((pkt_d = shape_ethernet_hdr_auto(pkt_d, injection_type)) == NULL)
             return pkt_d;
 
 #ifdef DEBUG
diff --git a/src/usage.c b/src/usage.c
index 79926f1..c01e34d 100644
--- a/src/usage.c
+++ b/src/usage.c
@@ -122,8 +122,9 @@ print_usage()
     fprintf(stdout, "\n"); 
 
 #ifndef MACOS 
-    fprintf(stdout, "ARP header options\n");
-    fprintf(stdout, "  -A op       Operation type (Default: 1 (ARP request))\n");
+    fprintf(stdout, "ARP and RARP header options\n");
+    fprintf(stdout, "  -A op       Operation type (Default: 1 (ARP request)\n");
+    fprintf(stdout, "              and 3 (Reverse ARP request))\n");
     fprintf(stdout, "  -x address  Source protocol address\n");
     fprintf(stdout, "  -X hwaddr   Source hardware address\n");
     fprintf(stdout, "  -y address  Destination protocol address\n");
-- 
1.8.1

Reply via email to