1
0
mirror of https://code.semirocket.science/wrapsix synced 2024-09-19 23:11:04 +03:00

Implemented ARP for one IPv4 address

This commit is contained in:
xHire 2009-01-08 18:40:19 +01:00
parent 2e4d31c695
commit 32e7d6459b
4 changed files with 97 additions and 11 deletions

View File

@ -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 */

View File

@ -1,4 +1,5 @@
#include <net/ethernet.h>
#include <net/if_arp.h>
#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(&eth->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);

View File

@ -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));

View File

@ -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