Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
AlgorithMan-de committed Aug 20, 2016
1 parent cb3517b commit f49f8a2
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 7 deletions.
2 changes: 2 additions & 0 deletions include/drivers/amd_am79c973.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ namespace myos

void SetHandler(RawDataHandler* handler);
common::uint64_t GetMACAddress();
void SetIPAddress(common::uint32_t);

This comment has been minimized.

Copy link
@amr98khaled

amr98khaled Mar 26, 2021

We will set IP address manually , but it could also be set using DHCP

common::uint32_t GetIPAddress();
};


Expand Down
56 changes: 56 additions & 0 deletions include/net/arp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

#ifndef __MYOS__NET__ARP_H
#define __MYOS__NET__ARP_H


#include <common/types.h>
#include <net/etherframe.h>


namespace myos
{
namespace net
{

struct AddressResolutionProtocolMessage
{
common::uint16_t hardwareType;
common::uint16_t protocol;
common::uint8_t hardwareAddressSize; // 6
common::uint8_t protocolAddressSize; // 4
common::uint16_t command;


common::uint64_t srcMAC : 48;
common::uint32_t srcIP;
common::uint64_t dstMAC : 48;
common::uint32_t dstIP;

} __attribute__((packed));



class AddressResolutionProtocol : public EtherFrameHandler
{

common::uint32_t IPcache[128];
common::uint64_t MACcache[128];
int numCacheEntries;

This comment has been minimized.

Copy link
@amr98khaled

amr98khaled Mar 26, 2021

When we request the MAC or IP addresses , we store them in these caches .


public:
AddressResolutionProtocol(EtherFrameProvider* backend);
~AddressResolutionProtocol();

bool OnEtherFrameReceived(common::uint8_t* etherframePayload, common::uint32_t size);

void RequestMACAddress(common::uint32_t IP_BE);
common::uint64_t GetMACFromCache(common::uint32_t IP_BE);
common::uint64_t Resolve(common::uint32_t IP_BE);
};


}
}


#endif
7 changes: 5 additions & 2 deletions include/net/etherframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ namespace myos

struct EtherFrameHeader
{
common::uint64_t dstMAC_BE;
common::uint64_t srcMAC_BE;
common::uint64_t dstMAC_BE : 48;
common::uint64_t srcMAC_BE : 48;
common::uint16_t etherType_BE;
} __attribute__ ((packed));

Expand Down Expand Up @@ -53,6 +53,9 @@ namespace myos

bool OnRawDataReceived(common::uint8_t* buffer, common::uint32_t size);
void Send(common::uint64_t dstMAC_BE, common::uint16_t etherType_BE, common::uint8_t* buffer, common::uint32_t size);

common::uint64_t GetMACAddress();
common::uint32_t GetIPAddress();
};


Expand Down
1 change: 1 addition & 0 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ objects = obj/loader.o \
obj/gui/window.o \
obj/gui/desktop.o \
obj/net/etherframe.o \
obj/net/arp.o \
obj/kernel.o


Expand Down
23 changes: 20 additions & 3 deletions src/drivers/amd_am79c973.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,13 @@ void amd_am79c973::Send(uint8_t* buffer, int size)
*dst = (uint8_t*)(sendBufferDescr[sendDescriptor].address + size -1);
src >= buffer; src--, dst--)
*dst = *src;

printf("Sending: ");
for(int i = 0; i < size; i++)
{
printfHex(buffer[i]);
printf(" ");
}

sendBufferDescr[sendDescriptor].avail = 0;
sendBufferDescr[sendDescriptor].flags2 = 0;
Expand All @@ -199,18 +206,18 @@ void amd_am79c973::Receive()
size -= 4;

uint8_t* buffer = (uint8_t*)(recvBufferDescr[currentRecvBuffer].address);

if(handler != 0)
if(handler->OnRawDataReceived(buffer, size))
Send(buffer, size);

/*
size = 64;
for(int i = 0; i < size; i++)
{
printfHex(buffer[i]);
printf(" ");
}
*/

}

recvBufferDescr[currentRecvBuffer].flags2 = 0;
Expand All @@ -227,3 +234,13 @@ uint64_t amd_am79c973::GetMACAddress()
{
return initBlock.physicalAddress;
}

void amd_am79c973::SetIPAddress(uint32_t ip)
{
initBlock.logicalAddress = ip;
}

uint32_t amd_am79c973::GetIPAddress()
{
return initBlock.logicalAddress;
}
28 changes: 26 additions & 2 deletions src/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include <drivers/amd_am79c973.h>
#include <net/etherframe.h>
#include <net/arp.h>

// #define GRAPHICSMODE

Expand Down Expand Up @@ -279,15 +280,38 @@ extern "C" void kernelMain(const void* multiboot_structure, uint32_t /*multiboot
// fourth: 0x168
*/



// IP 10.0.2.15
uint8_t ip1 = 10, ip2 = 0, ip3 = 2, ip4 = 15;
uint32_t ip_be = ((uint32_t)ip4 << 24)
| ((uint32_t)ip3 << 16)
| ((uint32_t)ip2 << 8)
| (uint32_t)ip1;

// IP 10.0.2.2

This comment has been minimized.

Copy link
@amr98khaled

amr98khaled Mar 26, 2021

gateway IP

uint8_t gip1 = 10, gip2 = 0, gip3 = 2, gip4 = 2;
uint32_t gip_be = ((uint32_t)gip4 << 24)
| ((uint32_t)gip3 << 16)
| ((uint32_t)gip2 << 8)
| (uint32_t)gip1;

amd_am79c973* eth0 = (amd_am79c973*)(drvManager.drivers[2]);

eth0->SetIPAddress(ip_be);

EtherFrameProvider etherframe(eth0);
etherframe.Send(0xFFFFFFFFFFFF, 0x0608, (uint8_t*)"FOO", 3);

AddressResolutionProtocol arp(&etherframe);

//etherframe.Send(0xFFFFFFFFFFFF, 0x0608, (uint8_t*)"FOO", 3);
//eth0->Send((uint8_t*)"Hello Network", 13);


interrupts.Activate();

printf("\n\n\n\n\n\n\n\n");
arp.Resolve(gip_be);


while(1)
{
Expand Down
99 changes: 99 additions & 0 deletions src/net/arp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@

#include <net/arp.h>
using namespace myos;
using namespace myos::common;
using namespace myos::net;
using namespace myos::drivers;


AddressResolutionProtocol::AddressResolutionProtocol(EtherFrameProvider* backend)
: EtherFrameHandler(backend, 0x806)
{
numCacheEntries = 0;
}

AddressResolutionProtocol::~AddressResolutionProtocol()
{
}

bool AddressResolutionProtocol::OnEtherFrameReceived(uint8_t* etherframePayload, uint32_t size)
{
if(size < sizeof(AddressResolutionProtocolMessage))
return false;

AddressResolutionProtocolMessage* arp = (AddressResolutionProtocolMessage*)etherframePayload;
if(arp->hardwareType == 0x0100)
{

if(arp->protocol == 0x0008
&& arp->hardwareAddressSize == 6
&& arp->protocolAddressSize == 4
&& arp->dstIP == backend->GetIPAddress())
{

switch(arp->command)
{

case 0x0100: // request
arp->command = 0x0200;
arp->dstIP = arp->srcIP;
arp->dstMAC = arp->srcMAC;
arp->srcIP = backend->GetIPAddress();
arp->srcMAC = backend->GetMACAddress();
return true;
break;

case 0x0200: // response
if(numCacheEntries < 128)
{
IPcache[numCacheEntries] = arp->srcIP;
MACcache[numCacheEntries] = arp->srcMAC;
numCacheEntries++;
}
break;
}
}

}

return false;
}

void AddressResolutionProtocol::RequestMACAddress(uint32_t IP_BE)
{

AddressResolutionProtocolMessage arp;
arp.hardwareType = 0x0100; // ethernet

This comment has been minimized.

Copy link
@amr98khaled

amr98khaled Mar 25, 2021

0x0001 is the hardware type for ethernet but we have to encode it in Big Endian so it is written 0x0100

arp.protocol = 0x0008; // ipv4

This comment has been minimized.

Copy link
@amr98khaled

amr98khaled Mar 25, 2021

0x0800 is the Network type for IPv4 but we have to encode it in Big Endian so it is written 0x0008

arp.hardwareAddressSize = 6; // mac
arp.protocolAddressSize = 4; // ipv4
arp.command = 0x0100; // request

This comment has been minimized.

Copy link
@amr98khaled

amr98khaled Mar 25, 2021

0x0001 is the ARP Request command but we have to encode it in Big Endian so it is written 0x0100


arp.srcMAC = backend->GetMACAddress();
arp.srcIP = backend->GetIPAddress();
arp.dstMAC = 0xFFFFFFFFFFFF; // broadcast
arp.dstIP = IP_BE;

this->Send(arp.dstMAC, (uint8_t*)&arp, sizeof(AddressResolutionProtocolMessage));

}

uint64_t AddressResolutionProtocol::GetMACFromCache(uint32_t IP_BE)
{
for(int i = 0; i < numCacheEntries; i++)
if(IPcache[i] == IP_BE)
return MACcache[i];
return 0xFFFFFFFFFFFF; // broadcast address
}

uint64_t AddressResolutionProtocol::Resolve(uint32_t IP_BE)
{
uint64_t result = GetMACFromCache(IP_BE);
if(result == 0xFFFFFFFFFFFF)
RequestMACAddress(IP_BE);

while(result == 0xFFFFFFFFFFFF) // possible infinite loop
result = GetMACFromCache(IP_BE);

return result;
}
10 changes: 10 additions & 0 deletions src/net/etherframe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,13 @@ void EtherFrameProvider::Send(common::uint64_t dstMAC_BE, common::uint16_t ether

backend->Send(buffer2, size + sizeof(EtherFrameHeader));
}

uint32_t EtherFrameProvider::GetIPAddress()
{
return backend->GetIPAddress();
}

uint64_t EtherFrameProvider::GetMACAddress()
{
return backend->GetMACAddress();
}

0 comments on commit f49f8a2

Please sign in to comment.