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