Commit 4f1c3dad authored by Martin Vítek's avatar Martin Vítek

Parsing IP header, fixes

parent d208d8ef
......@@ -60,14 +60,14 @@ void Debug::reg(const char* name, const uint16_t value)
uart.send_new_line();
}
void Debug::frame(const ethernet_frame& frame)
void Debug::frame(const ethernet_frame* frame)
{
uart.send("[FRAME] \n\r");
uart.send("\tDEST: ");
for (uint8_t i = 0; i < 6; i++)
{
uart.send_hex8(frame.dest_address[i]);
uart.send_hex8(frame->dest_address[i]);
uart.send(' ');
}
uart.send_new_line();
......@@ -75,13 +75,13 @@ void Debug::frame(const ethernet_frame& frame)
uart.send("\tSRC: ");
for (uint8_t i = 0; i < 6; i++)
{
uart.send_hex8(frame.src_address[i]);
uart.send_hex8(frame->src_address[i]);
uart.send(' ');
}
uart.send_new_line();
uart.send("\tType: ");
switch (__htons(frame.type_length))
switch (__htons(frame->type_length))
{
case IPV4: uart.send("IPv4");
break;
......@@ -94,19 +94,19 @@ void Debug::frame(const ethernet_frame& frame)
default: uart.send("Unknown");
}
uart.send(" (0x");uart.send_hex16(__htons(frame.type_length));uart.send(')');
uart.send(" (0x");uart.send_hex16(__htons(frame->type_length));uart.send(')');
uart.send_new_line();
uart.send("\tPayload: ");
for (uint16_t i = 0; i < frame.payload.length; i++)
for (uint16_t i = 0; i < frame->payload.length; i++)
{
uart.send_hex8(frame.payload.data[i]);
uart.send_hex8(frame->payload.data[i]);
uart.send(' ');
}
uart.send_new_line();
uart.send("\tCRC: ");
uart.send_hex32(frame.crc);
uart.send_hex32(frame->crc);
uart.send_new_line();
uart.send_new_line();
......@@ -134,6 +134,66 @@ void Debug::frame_type(const ethernet_frame* frame)
uart.send_new_line();
}
void Debug::ip_packet(const IP_packet* packet)
{
uart.send("[IPpacket]\n\r");
uart.send("\t\tVersion: ");
uart.send_dec(packet->version);
uart.send_new_line();
uart.send("\t\tHeader length: ");
uart.send_dec(packet->ihl);
uart.send_new_line();
uart.send("\t\tType: ");
uart.send_dec(packet->tos);
uart.send_new_line();
uart.send("\t\tTotal length: ");
uart.send_dec(__ntohs(packet->tl));
uart.send_new_line();
uart.send("\t\tTTL: ");
uart.send_dec(packet->ttl);
uart.send_new_line();
uart.send("\t\tProtocol: ");
switch (packet->protocol)
{
case ICMP: uart.send("ICMP");
break;
case TCP: uart.send("TCP");
break;
case UDP: uart.send("UDP");
break;
default: uart.send("Unknown");
break;
}
uart.send_new_line();
uart.send("\t\tSRC IP: ");
uint8_t* p = (uint8_t*) &(packet->src_address);
for (int8_t i=0; i<4; i++)
{
uart.send_dec(p[i]);
uart.send('.');
}
uart.send_new_line();
uart.send("\t\tDST IP: ");
p = (uint8_t*) &(packet->dst_address);
for (int8_t i=0; i<4; i++)
{
uart.send_dec(p[i]);
uart.send('.');
}
uart.send_new_line();
}
void Debug::tx_status(const ENC28J60_namespace::tx_status_vector& status, bool simple/*= true*/)
{
debug.info("TX status vector: ");
......
......@@ -3,6 +3,7 @@
#include "USART.h"
#include "ethernet_frame.h"
#include "ENC28J60.h"
#include "IP_protocol.h"
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
......@@ -43,8 +44,9 @@ class Debug
void error(const char* s);
void reg(const char* name, const uint8_t value);
void reg(const char* name, const uint16_t value);
void frame(const ethernet_frame& frame);
void frame(const ethernet_frame* frame);
void frame_type(const ethernet_frame* frame);
void ip_packet(const IP_packet* packet);
void tx_status(const ENC28J60_namespace::tx_status_vector& status, bool simple=true);
void rx_status(const ENC28J60_namespace::rx_status_vector& status, bool simple=true);
void adc();
......
......@@ -79,20 +79,20 @@ namespace ENC28J60_namespace
write_control_register(MAIPGL, 0x12); //Non-Back-to-Back Inter-Packet Gap
write_control_register(MAIPGH, 0x0C); //Non-Back-to-Back Inter-Packet Gap
//MAC is stored byte-backward
write_control_register(MAADR1, mac[5]);
write_control_register(MAADR2, mac[4]);
write_control_register(MAADR3, mac[3]);
write_control_register(MAADR4, mac[2]);
write_control_register(MAADR5, mac[1]);
write_control_register(MAADR6, mac[0]);
//MAC is stored byte-backward (not here?)
write_control_register(MAADR1, mac[0]);
write_control_register(MAADR2, mac[1]);
write_control_register(MAADR3, mac[2]);
write_control_register(MAADR4, mac[3]);
write_control_register(MAADR5, mac[4]);
write_control_register(MAADR6, mac[5]);
//Set-up PHY, left/green -> LEDA, right/orange -> LEDB
bit_field_set_in_PHY_register(PHCON2, HDLDIS_bm); //Fix for errata issue 9???
bit_field_clear_in_PHY_register(PHCON1, PDPXMD_bm); //Force half-duplex
//write_PHY_register(PHLCON, (1<<13) | (1<<12) | LACFG2_bm | LBCFG2_bm | LBCFG1_bm | LBCFG0_bm | STRCH_bm); //LEDA (green) link status, LEDB (orange) rx & tx activity
write_PHY_register(PHLCON, (1<<13) | (1<<12) | LACFG2_bm | LACFG1_bm | LACFG0_bm | LBCFG2_bm | LBCFG1_bm | LBCFG0_bm | STRCH_bm); //Both LEDs indicates rx/tx activity
write_PHY_register(PHIE, PLNKIE_bm | PGEIE_bm); //Enable interrupt from PHY
write_PHY_register(PHLCON, (1<<13) | (1<<12) | LACFG2_bm | LACFG1_bm | LACFG0_bm | LBCFG2_bm | LBCFG1_bm | LBCFG0_bm | STRCH_bm); //Both LEDs indicates rx/tx activity
write_PHY_register(PHIE, PLNKIE_bm | PGEIE_bm); //Enable interrupt from PHY
//Enable interrupts - global enable, RX packet, link change, TX packet
bit_field_set_in_register(EIE, INTIE_bm | PKTIE_bm | LINKIE_bm | TXIE_bm);
......
#include "IP_protocol.h"
#include <cstdint>
#include "ethernet_frame.h"
#include "USART.h"
#include "Debug.h"
IP_protocol::IP_protocol()
{
}
void IP_protocol::decode(const ethernet_payload& payload)
{
IP_packet* packet = (IP_packet*) payload.data;
debug.ip_packet(packet);
}
#pragma once
#include <cstdint>
#include "ethernet_frame.h"
enum IP_protocols
{
ICMP = 0x01,
IGMP = 0x02,
GGP = 0x03,
IP_in_IP = 0x04,
TCP = 0x06,
EGP = 0x08,
UDP = 0x11,
ESP = 0x32,
AH = 0x33
};
#pragma pack(push, 1)
struct IP_packet
{
uint8_t ihl :4; //Internet Header Length
uint8_t version :4; //4 for IPv4
uint8_t tos :8; //Type of service
uint16_t tl :16; //Total Length
uint16_t identification :16; //Identification for fragmented messages
//uint8_t flags :3;
//uint16_t fragment_offset :13;
uint16_t flags_fragment_offset :16;
/*
union
{
uint8_t value :3;
struct
{
uint8_t reserved :1;
uint8_t df:1;
uint8_t mf:1;
} bit;
} flags;
*/
uint8_t ttl :8;
uint8_t protocol :8;
uint16_t checksum :16;
uint32_t src_address ;
uint32_t dst_address ;
};
#pragma pack(pop)
class IP_protocol
{
public:
IP_protocol();
void decode(const ethernet_payload& payload);
};
......@@ -8,6 +8,7 @@
#include "ethernet_frame.h"
#include "NetworkTypes.h"
#include "ARP.h"
#include "IP_protocol.h"
#include "ENC28J60.h"
#include "Debug.h"
#include "NixieClock.h"
......@@ -23,6 +24,7 @@ NixieStack::NixieStack(ENC28J60& eth): eth(eth),
gateway(0),
link_is_up(false),
arp(mac, ip),
ipv4(),
rx_buffer(),
tx_buffer()
{
......@@ -126,26 +128,30 @@ void NixieStack::packet_handler()
if (rx_buffer.check())
{
ethernet_frame* frame = rx_buffer.read();
//debug.frame(frame);
switch (__htons(frame->type_length))
{
case IPV4:
break;
{
ipv4.decode(frame->payload);
}
break;
case ARP:
{
ethernet_frame* tx_frame = tx_buffer.write();
if (arp.decode(frame->payload, tx_frame->payload))
{
//Send ARP reply
memcpy(tx_frame->dest_address, frame->src_address, 6);
memcpy(tx_frame->src_address, mac, 6);
{
ethernet_frame* tx_frame = tx_buffer.write();
if (arp.decode(frame->payload, tx_frame->payload))
{
//Send ARP reply
memcpy(tx_frame->dest_address, frame->src_address, 6);
memcpy(tx_frame->src_address, mac, 6);
tx_frame->type_length = __htons(ARP);
tx_frame->type_length = __htons(ARP);
tx_buffer.write_advance();
}
}
tx_buffer.write_advance();
}
}
break;
default:
......
......@@ -7,6 +7,7 @@
#include "ethernet_frame.h"
#include "NetworkTypes.h"
#include "ARP.h"
#include "IP_protocol.h"
#include "ENC28J60.h"
using namespace ENC28J60_namespace;
......@@ -26,6 +27,7 @@ class NixieStack
bool link_is_up;
ARP_protocol arp;
IP_protocol ipv4;
public:
CircularBuffer<ethernet_frame, 5> rx_buffer;
......
......@@ -31,6 +31,7 @@
#include "ethernet_frame.h"
#include "NetworkTypes.h"
#include "NixieStack.h"
#include "IP_protocol.h"
using namespace ENC28J60_namespace;
......@@ -44,6 +45,12 @@ static const ethernet_frame packet = {
0
};
static const char packet_ip_icmp[] = {
0x45, 0x00, 0x00, 0x3c, 0x2d, 0x69, 0x00, 0x00,
0x80, 0x01, 0x8a, 0x04, 0xc0, 0xa8, 0x01, 0x01,
0xc0, 0xa8, 0x01, 0x02
};
int main(void)
{
//Initialize the SAM system
......@@ -95,7 +102,8 @@ int main(void)
//Set-up IPv4 address
stack.set_IP({192, 168, 1, 2});
//stack.set_IP({10, 20, 70, 145});
//Set-up gateway address
stack.set_gateway({192, 168, 1, 1});
......
......@@ -256,6 +256,12 @@
<Compile Include="GPIO.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="IP_protocol.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="IP_protocol.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="irq.cpp">
<SubType>compile</SubType>
</Compile>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment