Skip to content

Commit

Permalink
Parse ARP Packet
Browse files Browse the repository at this point in the history
  • Loading branch information
moratorium08 committed Jul 21, 2018
1 parent f4c9292 commit d5180cf
Showing 1 changed file with 178 additions and 9 deletions.
187 changes: 178 additions & 9 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include "desc.h"
#include "init.h"
#include "mem.h"
Expand All @@ -26,14 +27,136 @@ typedef enum {

typedef unsigned long long mac_addr;

typedef enum {
ARPHTYPE_ETHERNET,
ARPHTYPE_UNKNOWN
} ARPHType;

typedef enum {
ARPPTYPE_IPv4,
ARPPTYPE_UNKNOWN
} ARPPType;

typedef enum {
ARPOPERATION_REQUEST = 1,
ARPOPERATION_REPLY = 2,
ARPOPERATION_UNKNOWN = 3
} ARPOperation;

typedef struct {
ARPHType hardware_type;
ARPPType protocol_type;
ARPOperation operation;

// 多分ここは場合によって大きさが異なる?
union {
struct {
int sender_ip_addr;
int recver_ip_addr;
};
};
union {
struct {
mac_addr sender_mac_addr;
mac_addr recver_mac_addr;
};
};

} ARP;

typedef struct {
mac_addr recver_mac;
mac_addr sender_mac;
EthernetType type;
char *data;
union {
ARP *arp;
char *data;
};
} Ethernet;

void parse_packet(Ethernet *e, unsigned char *raw) {

ARP * parse_arp(unsigned char *raw) {
ARP *arp = (ARP *)malloc(sizeof(ARP));
memset(arp, 0, sizeof(ARP));

int tmp;
tmp = raw[0] * 0x100 + raw[1];
switch (tmp) {
case 1:
arp->hardware_type = ARPHTYPE_ETHERNET;
break;
default:
arp->hardware_type = ARPHTYPE_UNKNOWN;
}

tmp = raw[2] * 0x100 + raw[3];
if (tmp >= 0x800) {
arp->protocol_type = ARPPTYPE_IPv4;
} else {
arp->protocol_type = ARPPTYPE_UNKNOWN;
}

tmp = raw[6] * 0x100 + raw[7];
switch (tmp) {
case 1:
arp->operation = ARPOPERATION_REQUEST;
break;
case 2:
arp->operation = ARPOPERATION_REPLY;
break;
default:
arp->operation = ARPOPERATION_UNKNOWN;
}

int hardware_size = raw[4];
int protocol_size = raw[5];

unsigned long long addr;
switch (arp->hardware_type) {
case ARPHTYPE_ETHERNET:
addr = 0;
for (int i = 0; i < 6; i++) {
addr = addr * 0x100 + raw[8 + i];
}
arp->sender_mac_addr = addr;

addr = 0;
for (int i = 0; i < 6; i++) {
addr = addr * 0x100 + raw[8 + i + hardware_size + protocol_size];
}
arp->recver_mac_addr = addr;
break;
default:
// nop
break;
}

switch (arp->protocol_type) {
case ARPPTYPE_IPv4:
addr = 0;
for (int i = 0; i < 4; i++) {
addr = addr * 0x100 + raw[8 + i + hardware_size];
}
arp->sender_ip_addr= addr;

addr = 0;
for (int i = 0; i < 4; i++) {
addr = addr * 0x100 + raw[8 + i + protocol_size +
2 * hardware_size];
}
arp->recver_ip_addr = addr;
break;
default:
//nop
break;
}

return arp;
}

Ethernet * parse_packet(unsigned char *raw) {
Ethernet *e = (Ethernet *)malloc(sizeof(Ethernet));
memset(e, 0, sizeof(Ethernet));
mac_addr recv = 0;
for (int i = 0; i < 6; i++) {
recv = recv * 0x100 + (unsigned int)raw[i];
Expand Down Expand Up @@ -61,7 +184,53 @@ void parse_packet(Ethernet *e, unsigned char *raw) {
e->recver_mac = recv;
e->sender_mac = sender;
e->type = t;
e->data = raw + 14;
switch (e->type) {
case ETYPE_ARP:
e->arp = parse_arp(raw + 14);
break;
default:
e->data = raw + 14;
}
return e;
}

void print_arp_packet(ARP *arp) {
printf("Hardware Type: ");
switch (arp->hardware_type) {
case ARPHTYPE_ETHERNET:
printf("Ethernet\n");
break;
default:
printf("Unknown\n");
}

printf("Protocol Type: ");
switch (arp->protocol_type) {
case ARPPTYPE_IPv4:
printf("IPv4\n");
break;
default:
printf("Unknown\n");
}

printf("Operation: ");
switch (arp->operation) {
case ARPOPERATION_REQUEST:
printf("Request\n");
break;
case ARPOPERATION_REPLY:
printf("Reply\n");
break;
default:
printf("Unknown\n");
}

// TBD
printf("Sender Hardware Addr: %llx\n", arp->sender_mac_addr);
printf("Sender Protocol Addr: %x\n", arp->sender_ip_addr);

printf("Receiver Hardware Addr: %llx\n", arp->recver_mac_addr);
printf("Receiver Protocol Addr: %x\n", arp->recver_ip_addr);
}

void print_packet(Ethernet *e) {
Expand All @@ -72,10 +241,11 @@ void print_packet(Ethernet *e) {
printf("Type: IPv4\n");
break;
case ETYPE_ARP:
printf("Type: Arp\n");
printf("Type: ARP\n");
print_arp_packet(e->arp);
break;
case ETYPE_RARP:
printf("Type: RArp\n");
printf("Type: RARP\n");
break;
default:
printf("Type: Unknown\n");
Expand Down Expand Up @@ -225,10 +395,9 @@ int main(int argc, char const *argv[]) {
print_log("waiting read buffer");
for (int i = 0; i < 1000; i++) {
unsigned char *bufr = read_a_packet();
Ethernet e;
parse_packet(&e, bufr);
if (e.type == ETYPE_ARP) {
print_packet(&e);
Ethernet *e = parse_packet(bufr);
if (e->type == ETYPE_ARP) {
print_packet(e);
dump_data(bufr);
}
}
Expand Down

0 comments on commit d5180cf

Please sign in to comment.