From 32e7d6459be5e6e389b6457ba1cd53b77c376e69 Mon Sep 17 00:00:00 2001 From: xHire Date: Thu, 8 Jan 2009 18:40:19 +0100 Subject: [PATCH] Implemented ARP for one IPv4 address --- wrapper/connections.c | 2 +- wrapper/process.c | 79 +++++++++++++++++++++++++++++++++++++++---- wrapper/wrapper.c | 10 ++++-- wrapper/wrapper.h | 17 +++++++++- 4 files changed, 97 insertions(+), 11 deletions(-) diff --git a/wrapper/connections.c b/wrapper/connections.c index ffd598e..2e4fcb7 100644 --- a/wrapper/connections.c +++ b/wrapper/connections.c @@ -39,7 +39,7 @@ void send_there(struct in_addr ip4_addr, unsigned char ttl, unsigned int type, u close(sock); } -void send_ipv6(unsigned char *packet, int packet_size) +void send_raw(unsigned char *packet, int packet_size) { struct sockaddr_ll socket_address; /* target address */ struct ifreq ifr; /* interface */ diff --git a/wrapper/process.c b/wrapper/process.c index faabb49..0b24150 100644 --- a/wrapper/process.c +++ b/wrapper/process.c @@ -1,4 +1,5 @@ #include +#include #include "wrapper.h" #include "translate_ip.h" @@ -17,13 +18,17 @@ void process_packet(u_char *args, const struct pcap_pkthdr *header, const u_char switch (htons(eth->type)) { case ETHERTYPE_IP: - printf("\n IP: 4\n"); + printf("\n Proto: IPv4\n"); process_packet4(eth, payload); break; case ETHERTYPE_IPV6: - printf("\n IP: 6\n"); + printf("\n Proto: IPv6\n"); process_packet6(eth, payload); break; + case ETHERTYPE_ARP: + printf("\n Proto: ARP\n"); + process_arp(eth, payload); + break; default: printf("\n IP: unknown (%d/0x%x)\n", htons(eth->type), htons(eth->type)); break; @@ -162,7 +167,7 @@ void process_tcp4(const struct s_ethernet *eth_hdr, struct s_ip4 *ip_hdr, const memcpy(packet + SIZE_ETHERNET + SIZE_IP6, tcp, sizeof(struct s_tcp)); /* send the wrapped packet back */ - send_ipv6(packet, packet_size); + send_raw(packet, packet_size); /* free allocated memory */ free(packet); @@ -261,7 +266,7 @@ void process_udp4(const struct s_ethernet *eth_hdr, struct s_ip4 *ip_hdr, const memcpy(packet + SIZE_ETHERNET + SIZE_IP6, udp, sizeof(struct s_udp)); /* send the wrapped packet back */ - send_ipv6(packet, packet_size); + send_raw(packet, packet_size); /* free allocated memory */ free(packet); @@ -377,12 +382,74 @@ void process_icmp4(const struct s_ethernet *eth_hdr, struct s_ip4 *ip_hdr, const memcpy(packet + SIZE_ETHERNET + SIZE_IP6, icmp, sizeof(struct s_icmp)); /* send the wrapped packet back */ - send_ipv6(packet, packet_size); + send_raw(packet, packet_size); /* free allocated memory */ free(packet); } +void process_arp(const struct s_ethernet *eth_hdr, const unsigned char *arp_packet) +{ + struct s_arp *arp; /* ARP request packet */ + struct s_arp *arpr; /* ARP reply packet */ + struct s_ethernet *eth; + unsigned char *packet; + unsigned short packet_size; + + arp = (struct s_arp *) arp_packet; + + /* process only requests */ + if (htons(arp->opcode) != ARPOP_REQUEST) { + printf("==> Not ARP request <==\n"); + return; + } + + /* DEBUG: print source and destination IP addresses */ + printf(" IP From: %s\n", inet_ntoa(arp->ip_src)); + printf(" IP To: %s\n", inet_ntoa(arp->ip_dest)); + printf(" MAC From: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", arp->mac_src.a, arp->mac_src.b, arp->mac_src.c, arp->mac_src.d, arp->mac_src.e, arp->mac_src.f); + printf(" MAC To: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", arp->mac_dest.a, arp->mac_dest.b, arp->mac_dest.c, arp->mac_dest.d, arp->mac_dest.e, arp->mac_dest.f); + + /* check if this packet is ours */ + if (memcmp(&ip4addr_wrapsix, &arp->ip_dest, 4)) { + printf("==> This packet is not ours! <==\n"); + return; + } + + /* compute the packet size */ + packet_size = SIZE_ETHERNET + sizeof(struct s_arp); + + /* allocate enough memory */ + if ((packet = (unsigned char *) malloc(packet_size)) == NULL) { + fprintf(stderr, "Fatal Error! Lack of free memory!\n"); + exit(EXIT_FAILURE); + } + memset(packet, 0x0, packet_size); + + /* define ethernet header and ARP offsets */ + eth = (struct s_ethernet *) packet; + arpr = (struct s_arp *) (packet + SIZE_ETHERNET); + + /* assemble the ethernet header */ + eth->dest = eth_hdr->src; + memcpy(ð->src, mac, sizeof(struct s_mac_addr)); + eth->type = htons(ETHERTYPE_ARP); + + /* assemble the ARP reply part */ + arpr->hw = htons(ARPHRD_ETHER); + arpr->proto = htons(ETHERTYPE_IP); + arpr->hw_len = 0x06; + arpr->proto_len = 0x04; + arpr->opcode = htons(ARPOP_REPLY); + arpr->mac_src = eth->src; + arpr->mac_dest = eth->dest; + arpr->ip_src = ip4addr_wrapsix; + arpr->ip_dest = arp->ip_src; + + /* send ARP reply */ + send_raw(packet, packet_size); +} + /*** IPv6 ***/ void process_packet6(const struct s_ethernet *eth, const unsigned char *packet) { @@ -816,7 +883,7 @@ void process_ndp(const struct s_ethernet *eth_hdr, struct s_ip6 *ip_hdr, unsigne icmp->checksum = checksum_ipv6(ip->ip6_src, ip->ip6_dst, htons(ip->ip6_plen), ip->ip6_nxt, (unsigned char *) icmp); /* send the packet */ - send_ipv6(packet, packet_size); + send_raw(packet, packet_size); /* free allocated memory */ free(packet); diff --git a/wrapper/wrapper.c b/wrapper/wrapper.c index 7406f7b..0612834 100644 --- a/wrapper/wrapper.c +++ b/wrapper/wrapper.c @@ -2,9 +2,10 @@ #include "storage.h" struct s_mac_addr *mac; /* MAC address of the device */ -char *dev; /* capture device name */ -int dev_index; /* capture device index */ -struct in_addr *dev_ip; /* IP address associated with the device */ +char *dev; /* capture device name */ +int dev_index; /* capture device index */ +struct in_addr *dev_ip; /* IP address associated with the device */ +struct in_addr ip4addr_wrapsix; /* IPv4 address for WrapSix */ /* storage trees */ jsw_rbtree_t *stg_conn_tcp; @@ -69,6 +70,9 @@ int main(int argc, char **argv) /* get index of the device */ dev_index = get_dev_index(dev); + /* set the WrapSix IPv4 address */ + inet_aton("10.0.0.111", &ip4addr_wrapsix); + /* compile the filter expression */ if (pcap_compile(handle, &fp, filter_exp, 0, 0) == -1) { fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle)); diff --git a/wrapper/wrapper.h b/wrapper/wrapper.h index cdeafb2..3629655 100644 --- a/wrapper/wrapper.h +++ b/wrapper/wrapper.h @@ -40,6 +40,19 @@ struct s_ethernet { unsigned short type; /* 16 b; IP/ARP/RARP/... */ }; +/* ARP structure */ +struct s_arp { + unsigned short hw; /* 16 b; hardware type [0x0001] */ + unsigned short proto; /* 16 b; protocol type [0x0800] */ + unsigned char hw_len; /* 8 b; length of hardware address in bytes [0x06] */ + unsigned char proto_len; /* 8 b; length of protocol address in bytes [0x04] */ + unsigned short opcode; /* 16 b; operation code: [0x0001] or [0x0002] */ + struct s_mac_addr mac_src; /* 48 b; sender hardware address */ + struct in_addr ip_src; /* 32 b; sender protocol address */ + struct s_mac_addr mac_dest; /* 48 b; target hardware address */ + struct in_addr ip_dest; /* 32 b; target protocol address */ +}__attribute__((__packed__)); + /* IPv4 header structure */ struct s_ip4 { unsigned char ver_ihl; @@ -171,6 +184,7 @@ void process_packet4(const struct s_ethernet *eth, const unsigned char *packet); void process_tcp4(const struct s_ethernet *eth_hdr, struct s_ip4 *ip_hdr, const unsigned char *payload, unsigned short data_size); void process_udp4(const struct s_ethernet *eth_hdr, struct s_ip4 *ip_hdr, const unsigned char *payload, unsigned short data_size); void process_icmp4(const struct s_ethernet *eth_hdr, struct s_ip4 *ip_hdr, const unsigned char *payload, unsigned short data_size); +void process_arp(const struct s_ethernet *eth_hdr, const unsigned char *arp_packet); void process_packet6(const struct s_ethernet *eth, const unsigned char *packet); void process_tcp6(const struct s_ethernet *eth, struct s_ip6 *ip, const unsigned char *payload); @@ -179,7 +193,7 @@ void process_icmp6(const struct s_ethernet *eth, struct s_ip6 *ip, const unsigne void process_ndp(const struct s_ethernet *eth_hdr, struct s_ip6 *ip_hdr, unsigned char *icmp_data); void send_there(struct in_addr ip4_addr, unsigned char ttl, unsigned int type, unsigned char *payload, unsigned int paylen); -void send_ipv6(unsigned char *packet, int packet_size); +void send_raw(unsigned char *packet, int packet_size); unsigned short checksum(const void *_buf, int len); unsigned short checksum_ipv4(struct in_addr ip_src, struct in_addr ip_dest, unsigned short length, unsigned char proto, unsigned char *data); @@ -191,5 +205,6 @@ extern char *dev; /* capture device name */ extern int dev_index; /* capture device index */ extern struct in_addr *dev_ip; /* IP address associated with the device */ extern struct in6_addr ip6addr_wrapsix; /* IPv6 prefix of WrapSix addresses */ +extern struct in_addr ip4addr_wrapsix; /* IPv4 address for WrapSix */ #endif