Small updates to Network Stack

Added DNS, not finished. Lots of cleaning up to do when converting Shrine code
Formatting alterations to Net files, beginning restructuring and updating Docs & Tests
This commit is contained in:
TomAwezome 2020-07-31 13:49:37 -04:00
parent 9e53a92859
commit 31d3760e34
28 changed files with 628 additions and 241 deletions

Binary file not shown.

View file

@ -46,7 +46,6 @@ U0 ARPCacheInit()
arp_globals.local_ipv4 = 0;
}
I64 ARPSend(U16 operation,
U8 *dest_mac_address,
U8 *send_mac_address,
@ -68,13 +67,11 @@ I64 ARPSend(U16 operation,
header = ethernet_frame;
header->hardware_type = EndianU16(HTYPE_ETHERNET);
header->protocol_type = EndianU16(ETHERTYPE_IPV4);
header->hardware_addr_len = MAC_ADDRESS_LENGTH;
header->protocol_addr_len = IP_ADDRESS_LENGTH;
header->operation = EndianU16(operation);
header->hardware_type = EndianU16(HTYPE_ETHERNET);
header->protocol_type = EndianU16(ETHERTYPE_IPV4);
header->hardware_addr_len = MAC_ADDRESS_LENGTH;
header->protocol_addr_len = IP_ADDRESS_LENGTH;
header->operation = EndianU16(operation);
MemCopy(header->sender_hardware_addr, send_mac_address, MAC_ADDRESS_LENGTH);
header->sender_protocol_addr = send_ip;
@ -86,9 +83,6 @@ I64 ARPSend(U16 operation,
return 0;
}
CARPHash *ARPCacheFindByIP(U32 ip_address)
{
U8 *ip_string = MStrPrint("%d", ip_address);
@ -103,11 +97,19 @@ CARPHash *ARPCacheFindByIP(U32 ip_address)
CARPHash *ARPCachePut(U32 ip_address, U8 *mac_address)
{
CARPHash *entry = ARPCacheFindByIP(ip_address);
Free(entry);
//Free(entry); // something seems wrong about this...
if (!entry)
{
entry = CAlloc(sizeof(CARPHash));
entry->str = MStrPrint("%d", ip_address);
MemCopy(entry->mac_address, mac_address, 6);
HashAdd(entry, arp_cache);
}
else
ZenithWarn("ARP Cache Put attempted but entry was already found in Cache. TODO: overwrite?\n");
entry = CAlloc(sizeof(CARPHash));
entry->str = MStrPrint("%d", ip_address);
MemCopy(entry->mac_address, mac_address, 6);
return entry;
}
@ -123,8 +125,6 @@ U0 ARPSetIPV4Address(U32 ip_address)
arp_globals.local_ipv4);
}
//ARP Handler? Takes an eth_frame CEthFrame* ?
//Seems like a weird way to do this,
//and then it goes into a a RegisterL3Protocol
@ -164,7 +164,6 @@ I64 ARPHandler(CEthernetFrame *ethernet_frame)
ZenithErr("ARP Handler caught wrong frame hardware type.");
return -1; // External use of ARPHandler must account for -1 error codes
}
if (EndianU16(header->protocol_type) != ETHERTYPE_IPV4)
{
ZenithErr("ARP Handler caught wrong frame protocol type.");
@ -181,8 +180,6 @@ I64 ARPHandler(CEthernetFrame *ethernet_frame)
return -1; // External use of ARPHandler must account for -1 error codes
}
switch (operation)
{
case ARP_REQUEST:
@ -200,43 +197,4 @@ I64 ARPHandler(CEthernetFrame *ethernet_frame)
}
}
ARPCacheInit;

476
src/Home/Net/DNS.CC Executable file
View file

@ -0,0 +1,476 @@
#include "UDP";
// https://www2.cs.duke.edu/courses/fall16/compsci356/DNS/DNS-primer.pdf
// https://en.wikipedia.org/wiki/Domain_Name_System
// DNS Cache is a HashTable, similar to ARP Cache
#define DNS_HASHTABLE_SIZE 2048 // 1024 might be fine, test it
#define HTT_DNS 0x00100 // identical to HTT_DICT_WORD
#define DNS_FLAG_RD 0x0100
#define DNS_OP_QUERY 0
#define DNS_TYPE_A 1
#define DNS_CLASS_IN 1
#define DNS_TIMEOUT 5000
class CDNSHash:CHash
{ // store U8 *hostname as CHash->str U8 *
CAddressInfo info;
// Shrine has 'TODO: honor TTL' ...
// Duke: 'TTL: the number of seconds the results can be cached'
// perhaps have a separate task for removing cached results ?
};
class CDNSDomainName
{
U8 **labels;
I64 num_labels;
};
class CDNSQuestion
{
CDNSQuestion *next;
CDNSDomainName q_name;
U16 q_type;
U16 q_class;
};
class CDNSHeader
{
U16 id;
U16 flags;
U16 q_count; // number of entries in question section
U16 a_count; // number of resource records in answer section
U16 ns_count; // number of name server resource records in authority records section
U16 ar_count; // number of resource records in additional records section
};
class CDNSRR
{ // RR: Resource Record
CDNSRR *next;
CDNSDomainName name; // name of the node this record is for
U16 type; // RR type, e.g. 44=SSHFP, 15=MX, 49=DHCID ...
U16 rr_class; // class code
U32 ttl; // count in seconds that RR stays valid (max = 2^31 - 1)
U16 rd_length; // length of r_data member
U8 *r_data; // additional RR-specific data
};
class CDNSGlobals
{
U16 addr_family;
CIPAddressStorage dns_ip;
} dns_globals;
CHashTable *dns_cache = NULL;
U0 DNSCacheInit()
{
dns_cache = HashTableNew(DNS_HASHTABLE_SIZE);
MemSet(&dns_globals.dns_ip, 0, sizeof(CIPAddressStorage));
dns_globals.addr_family = 0;
}
CDNSHash *DNSCacheFind(U8 *hostname)
{
CDNSHash *entry = HashFind(hostname, dns_cache, HTT_DNS);
if (entry == NULL)
ZenithErr("Could not find a hostname in the DNS Cache.\n");
return entry;
}
CDNSHash *DNSCachePut(U8 *hostname, CAddressInfo *info)
{
CDNSHash *entry = DNSCacheFind(hostname);
if (!entry)
{
entry = CAlloc(sizeof(CDNSHash));
entry->str = StrNew(hostname);
AddressInfoCopy(&entry->info, info);
HashAdd(entry, dns_cache);
}
else
ZenithWarn("DNS Cache Put attempted but entry was already found in Cache. TODO: overwrite?");
return entry;
}
I64 DNSCalculateQuestionSize(CDNSQuestion *q)
{ // ??
I64 i, size = 0;
for (i = 0; i < q->q_name.num_labels; i++)
{
size += 1 + StrLen(q->q_name.labels[i]);
}
return size + 1 + 4;
}
U0 DNSSerializeQuestion(U8 *buffer, CDNSQuestion *q)
{ // ??
I64 i;
U8 *label;
for (i = 0; i < q->q_name.num_labels; i++)
{
label = q->q_name.labels[i];
*(buffer++) = StrLen(label);
while (*label)
*(buffer++) = *(label++);
}
*(buffer++) = 0;
*(buffer++) = q->q_type >> 8;
*(buffer++) = q->q_type & 0xFF;
*(buffer++) = q->q_class >> 8;
*(buffer++) = q->q_class & 0xFF;
}
I64 DNSSendQuestion(U16 id, U16 local_port, CDNSQuestion *q)
{
CIPV4Address* ipv4_addr;
U8 *frame;
U16 flags;
CDNSHeader *header;
I64 de_index;
switch (dns_globals.addr_family)
{
case AF_UNSPEC: // 0, global dns ip not set
return -1;
case AF_INET6:
ZenithErr("IPV6 not supported yet in DNS.\n");
throw('DNS');
case AF_INET:
ipv4_addr = &dns_globals.dns_ip;
if (!*ipv4_addr)
return -1;
}
// UDPPacketAllocate currently only accepts IPV4 ...
de_index = UDPPacketAllocate(&frame,
IPV4GetAddress(),
local_port,
*ipv4_addr,
53,
sizeof(CDNSHeader) + DNSCalculateQuestionSize(q));
if (de_index < 0)
return de_index;
flags = (DNS_OP_QUERY << 11) | DNS_FLAG_RD;
header = frame;
header->id = EndianU16(id);
header->flags = EndianU16(flags);
header->q_count = EndianU16(1);
header->a_count = 0;
header->ns_count = 0;
header->ar_count = 0;
DNSSerializeQuestion(frame + sizeof(CDNSHeader), q);
UDPPacketFinish(de_index);
return 0;
}
I64 DNSParseDomainName(U8 *packet_data, I64 packet_length, U8 **data_inout, I64 *length_inout, CDNSDomainName *name_out)
{ // these methods look not-so-good, ngl.
U8 *data = *data_inout;
U8 *name_buf;
I64 length = *length_inout;
I64 label_len;
Bool jump_taken = FALSE;
if (length < 1)
{
ZenithErr("DNS parsed domain name, hit length of 0 or less\n");
return -1;
}
name_out->labels = CAlloc(16 * sizeof(U8 *));
name_out->num_labels = 0;
name_buf = CAlloc(256); // ?..
name_out->labels[0] = name_buf;
while (length)
{
label_len = *(data++);
length--;
if (label_len == 0)
break;
else if (label_len >= 192)
{
label_len &= 0x3F; // ...
if (!jump_taken)
{
*data_inout = data + 1;
*length_inout = length - 1;
jump_taken = TRUE;
ZenithLog("UDP parsed domain name, jump taken\n");
}
data = packet_data + ((label_len << 8) | *data);
length = packet_data + packet_length - data;
}
else
{
if (length < label_len)
return -1; // ?
MemCopy(name_buf, data, label_len);
data += label_len;
length -= label_len;
name_buf[label_len] = 0;
name_out->labels[name_out->num_labels++] = name_buf;
name_buf += label_len + 1;
}
}
if (!jump_taken)
{
*data_inout = data;
*length_inout = length;
}
return 0;
}
I64 DNSParseQuestion(U8 *packet_data, I64 packet_length, U8 **data_inout, I64 *length_inout, CDNSQuestion *q_out)
{
U8 *data;
I64 length;
I64 error = DNSParseDomainName(packet_data, packet_length, data_inout, length_inout, &q_out->q_name);
if (error < 0)
return error;
data = *data_inout;
length = *length_inout;
if (length < 4)
return -1;
q_out->next = NULL;
q_out->q_type = (data[1] << 8) | data[0];
q_out->q_class = (data[3] << 8) | data[2];
*data_inout = data + 4;
*length_inout = length - 4;
return 0;
}
I64 DNSParseRR(U8 *packet_data, I64 packet_length, U8 **data_inout, I64 *length_inout, CDNSRR *rr_out)
{
U8 *data;
I64 length;
I64 record_length;
I64 error = DNSParseDomainName(packet_data, packet_length, data_inout, length_inout, &rr_out->name);
if (error < 0)
return error;
data = *data_inout;
length = *length_inout;
if (length < 10)
return -1;
rr_out->next = NULL;
MemCopy(&rr_out->type, data, 10); // ???
record_length = 10 + EndianU16(rr_out->rd_length);
if (length < record_length)
return -1;
rr_out->r_data = data + 10; // ??
*data_inout = data + record_length;
*length_inout = length - record_length;
return 0;
}
I64 DNSParseResponse(U16 id, U8 *data, I64 len, CDNSHeader **header_out, CDNSQuestion **questions_out, CDNSRR **answers_out)
{
CDNSHeader *header;
CDNSQuestion *question;
CDNSRR *answer;
I64 i;
U8 *packet_data = data;
I64 packet_length = length;
if (length < sizeof(CDNSHeader))
{
ZenithErr("DNS Response Parsed, length too short.\n");
return -1;
}
header = data;
data += sizeof(CDNSHeader);
if (id != 0 && EndianU16(header->id) != id)
{
ZenithErr("DNS Response Parsed, header id mismatch.\n");
return -1;
}
for (i = 0; i < EndianU16(header->q_count); i++)
{
question = CAlloc(sizeof(CDNSQuestion));
if (DNSParseQuestion(packet_data, packet_length, &data, &length, question) < 0)
return -1;
question->next = *questions_out;
*questions_out = question;
}
for (i = 0; i < EndianU16(header->a_count); i++)
{
answer = CAlloc(sizeof(CDNSRR));
if (DNSParseRR(packet_data, packet_length, &data, &length, answer) < 0)
return -1;
answer->next = *answers_out;
*answers_out = answer;
}
*header_out = header;
return 0;
}
U0 DNSBuildQuestion(CDNSQuestion *q, U8 *name)
{
U8 *copy = StrNew(name);
U8 *dot;
q->next = NULL;
q->q_name.labels = CAlloc(16 * sizeof(U8 *));
q->q_name.labels[0] = 0;
q->q_name.num_labels = 0;
q->q_type = DNS_TYPE_A;
q->q_class = DNS_CLASS_IN;
while (*copy)
{
q->q_name.labels[q->q_name.num_labels++] = copy;
dot = StrFirstOcc(copy, ".");
if (dot)
{
*dot = 0;
copy = dot + 1;
}
else
break;
}
}
// these Free methods bother me a bit...
U0 DNSFreeQuestion(CDNSQuestion *q)
{
Free(q->q_name.labels[0]);
}
U0 DNSFreeRR(CDNSRR *r)
{
Free(rr->name.labels[0]);
}
U0 DNSFreeQuestionChain(CDNSQuestion *questions)
{
CDNSQuestion *next;
while (questions)
{
next = questions->next;
DNSFreeQuestion(questions);
Free(questions);
questions = next;
}
}
U0 DNSFreeRRChain(CDNSRR *rrs)
{ // Shrine sets rrs->next to a CDNSQuestion when it would be a CDNSRR ... assuming it's wrong and fixing it here..
CDNSRR *next;
while (rrs)
{
next = rrs->next;
DNSFreeRR(rrs);
Free(rrs);
rrs = next;
}
}
/*
I64 DNSRunQuery(CUDPSocket *udp_socket, U8 *name, U16 port, CAddressInfo **result_out)
{ // IPV4-UDP-based
I64 retries = 0;
I64 timeout = DNS_TIMEOUT;
U16 local_port = RandU16;
U16 id = RandU16;
I64 error = 0;
U8 *buffer;
I64 count;
Bool have;
CDNSQuestion q;
CDNSHeader *header;
CDNSQuestion *questions;
CDNSRR *answers;
CDNSRR *a;
CSocketAddressIPV4 ipv4_addr;
CSocketAddressIPV4 ipv4_addr_in; // ?
CAddressInfo *res;
//setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO_MS, &timeout, sizeof(timeout))
udp_socket->receive_timeout_ms = timeout;
}
*/
/*
I64 DNSRunQuery(socket?, U8 *name, U16 port, CAddressInfo **result_out)
I64 DNSGetAddressInfo(U8 *node, U8 *service, CAddressInfo *hints, CAddressInfo **result)
U0 DNSSetResolverIPV4(U32 ip) // funny enough he explicitly labeled IPV4.........
U0 Host(U8 *hostname)
U0 DNSInit()
*/
DNSCacheInit;

View file

@ -36,6 +36,7 @@ NetQueue
Ethernet
EthernetInitGlobals
EthernetFrameParse (has a fixme)
@ -46,10 +47,17 @@ ARP
ARPCachePut
ARPHandler
ARPSetIPV4Address
ARPHandler
Sockets (just finite state modifiers.)
AddressInfoCopy
IPV4AddressParse
PresentationToNetwork
NetworkToPresentation
SocketStateErr
Socket
SocketAccept
SocketClose
SocketBind
@ -61,6 +69,7 @@ Sockets (just finite state modifiers.)
SocketSendTo
IPV4
InitIPV4Globals (should change this to IPV4InitGlobals ...)
IPV4Checksum
GetMACAddressForIP
IPV4PacketAllocate
@ -78,14 +87,37 @@ TCP
UDP
UDPTreeNodeInit
UDPTreeNodeAdd
UDPTreeNodeParamAdd
UDPTreeNodeParamInit
UDPTreeNodeFind
UDPTreeNodePop
UDPTreeNodeSinglePop
UDPTreeNodeQueueInit
UDPTreeNodeQueueSocketFind
UDPTreeNodeQueueIPV4Find
UDPTreeNodeQueueSocketSinglePop
UDPGlobalsInit
UDPPacketAllocate
UDPPacketFinish
UDPParsePacket
UDPSocket
UDPSocketBind
UDPSocketClose
UDPSocketReceiveFrom
UDPSocketSendTo
DNS
DNSCacheInit
DNSCacheFind
DNSCachePut
NetHandlerTask
NetHandlerTask
HandleNetQueueEntry (4 million context swaps per second!)
HandleNetQueueEntry (TODO: investigate 4 million context swaps per second)
IPV4Handler
NetConfig

Binary file not shown.

View file

@ -4,6 +4,8 @@ Departures from Shrine:
ARP Cache is Hashtable. Keys are U32 ip addresses to "%d" string.
DNS Cache is Hashtable. Keys are U8 *hostname.
NetFIFO is NetQueue. If problems arise, maybe set a #define max
for the length of the Queue.
@ -16,9 +18,9 @@ Departures from Shrine:
Stack progress: (# done, ~ WIP, . N/A)
# PCNet-II Driver
. Other Network Card Drivers? See $LK,"Roadmap",A="FF:C:/Home/Roadmap.DD,most common ethernet cards"$.
# NetQueue
- no NetHandler currently
# Ethernet
- double check.
@ -34,6 +36,9 @@ Stack progress: (# done, ~ WIP, . N/A)
socket state. Protocols will
need to detect socket states
and respond appropriately.
- had to go back and alter low level
logic recently, keep eyes on verifying
socket logic sanity.
# IPV4 (Internet Protocol version 4)
@ -44,11 +49,12 @@ Stack progress: (# done, ~ WIP, . N/A)
. TCP (Transmission Control Protocol)
. UDP (User Datagram Protocol)
~ UDP (User Datagram Protocol)
- needs more testing. could use a UDPRep func to render bound tree.
. DNS (Domain Name System)
~ DNS (Domain Name System)
. NetHandlerTask
~ NetHandlerTask
- thinking maybe for this, instead of using this whole
handler function pointer nonsense, it can be done
more seamlessly with a switch(ethertype). Shrine

Binary file not shown.

View file

@ -44,7 +44,7 @@ U0 EthernetFrameParse(CEthernetFrame *frame_out, U8 *frame, U16 length)
frame_out->data = frame + ETHERNET_DATA_OFFSET;
frame_out->length = length - ETHERNET_MAC_HEADER_LENGTH + 4; //TODO: He has a comment literally just saying "??".
frame_out->length = length - ETHERNET_MAC_HEADER_LENGTH + 4; // He has a comment literally just saying "??".
}
EthernetInitGlobals;

View file

@ -5,8 +5,8 @@
class CICMPHeader // Shrine's use of id and seq indicate this header is for Address Mask Reply/Request
{
U8 type;
U8 code;
U8 type;
U8 code;
U16 checksum;
U16 identifier;
@ -38,16 +38,12 @@ I64 ICMPSendReply(U32 destination_ip_address,
header = frame;
header->type = ICMP_TYPE_ECHO_REPLY;
header->code = 0; // why is 0 okay?
header->checksum = EndianU16(EndianU16(request_checksum) + 0x0800);// TODO: this is awful. Shrine says hack alert.
header->identifier = identifier;
header->sequence_number = sequence_number;
header->type = ICMP_TYPE_ECHO_REPLY;
header->code = 0; // why is 0 okay?
header->checksum = EndianU16(EndianU16(request_checksum) + 0x0800);
header->identifier = identifier;
header->sequence_number = sequence_number;
// TODO: header checksum is awful. Shrine says hack alert.
MemCopy(frame + sizeof(CICMPHeader), payload, length);

View file

@ -11,39 +11,32 @@
#define IP_PROTOCOL_TCP 0x06
#define IP_PROTOCOL_UDP 0x11
class CIPV4Packet
{
CEthernetFrame *ethernet_frame;
CEthernetFrame *ethernet_frame;
U32 source_ip_address;
U32 destination_ip_address;
U32 source_ip_address;
U32 destination_ip_address;
U8 protocol;
U8 protocol;
U8 padding[7];
U8 padding[7];
U8 *data;
I64 length;
U8 *data;
I64 length;
};
class CIPV4Header
{ // note: U4's in some U8s.
U8 version_ihl; // Version for IPV4 is 4. IHL=Internet Header Length
U8 dscp_ecn; // DSCP=Differentiated Services Code Point. ECN=Explicit Congestion Notification
U8 version_ihl; // Version for IPV4 is 4. IHL=Internet Header Length
U8 dscp_ecn; // DSCP=Differentiated Services Code Point. ECN=Explicit Congestion Notification
U16 total_length; // min 20B max 65535
U16 identification;
U16 flags_fragment_offset; // flags first(?) 3 bits. fragment offset min 0 max 65528
// flag: bit 0: reserved must be 0. bit 1: don't fragment. bit 2: more fragments
// flag: bit 0: reserved must be 0. bit 1: don't fragment. bit 2: more fragments
U8 time_to_live; // specified in seconds, wikipedia says nowadays serves as a hop count
U8 protocol;
U8 time_to_live; // specified in seconds, wikipedia says nowadays serves as a hop count
U8 protocol;
U16 header_checksum;
@ -69,9 +62,8 @@ U0 InitIPV4Globals()
ipv4_globals.ipv4_subnet_mask = 0;
}
// For now, trusting Shrine's implement
// of this. Shrine links back to
// of checksum. Shrine links back to
// http://stackoverflow.com/q/26774761/2524350
U16 IPV4Checksum(U8* header, I64 length)
@ -99,8 +91,6 @@ U16 IPV4Checksum(U8* header, I64 length)
}
I64 GetMACAddressForIP(U32 ip_address, U8 **mac_out)
{
CARPHash *entry;
@ -116,7 +106,6 @@ I64 GetMACAddressForIP(U32 ip_address, U8 **mac_out)
return 0;
}
*/
if (ip_address == 0)
{
ZenithLog("Get MAC for IP failed. Address = 0\n");
@ -129,11 +118,10 @@ I64 GetMACAddressForIP(U32 ip_address, U8 **mac_out)
return 0;
}
// "outside this subnet; needs routing"
if ((ip_address & ipv4_globals.ipv4_subnet_mask) != (ipv4_globals.local_ip & ipv4_globals.ipv4_subnet_mask))
{
// Shrine recurses here... and says FIXME infinite loop if mis-configured...
// TODO: Shrine recurses here... and says FIXME infinite loop if mis-configured...
}
else // "local network"
{
@ -182,16 +170,13 @@ I64 IPV4PacketAllocate(U8 **frame_out,
{
U8 *ethernet_frame;
U8 *destination_mac_address;
I64 error;
I64 de_index;
I64 internet_header_length;
CIPV4Header *header;
error = GetMACAddressForIP(destination_ip_address, &destination_mac_address);
if (error < 0)
{
ZenithLog("IPV4 Packet Allocate failed to get MAC for destination.\n");
@ -211,10 +196,8 @@ I64 IPV4PacketAllocate(U8 **frame_out,
internet_header_length = 5;// ... why. need a #define
header = ethernet_frame;
header->version_ihl = internet_header_length | (4 << 4);// whaaat the fuck is this? #define!
header->dscp_ecn = 0; // a clear define of what this actually means would be good
header->total_length = EndianU16(internet_header_length * 4 + length); //...why?
@ -278,32 +261,4 @@ U0 IPV4ParsePacket(CIPV4Packet *packet_out, CEthernetFrame *ethernet_frame)
}
// IPV4 handler moved to NetHandlerTask file.
InitIPV4Globals;

View file

@ -2,28 +2,29 @@
(in our case, Queues) for pending and
empty frames. If logical to implement,
perhaps Zenith NetQueue code should
do something similar to that idea. */
do something similar to that idea.
/* Each Ethernet Frame will be represented
Each Ethernet Frame will be represented
as an entry in a CQueue. */
class CNetQueueEntry:CQueue
{
I64 length; //todo: change to packet_length?
U8 frame[ETHERNET_FRAME_SIZE];
U8 frame[ETHERNET_FRAME_SIZE];
};
/* global variable, holds pointer of Ethernet Queue.
This acts as the Head of the Queue, Entries act
as the Tail of the Queue.
Upon QueueInit, ->next and ->last are set to
itself, the Head. */
CQueue *net_queue; // no QueueRemove the Head! only Entries!
/* Net Handler Task is set idle and active depending
on if entries in Net Queue. See NetHandlerTask.CC */
CTask *net_handler_task = NULL;
on if entries in Net Queue. See $LK,"NetHandlerTask",A="FF:C:/Home/Net/NetHandlerTask.CC,net_handler_task"$ */
CTask *net_handler_task = NULL;
U0 NetQueueInit()
{
@ -31,7 +32,6 @@ U0 NetQueueInit()
QueueInit(net_queue);
}
CNetQueueEntry *NetQueuePull()
{/* Returns a pointer to a CNetQueueEntry,
or NULL pointer if Net Queue is empty. */
@ -50,8 +50,6 @@ CNetQueueEntry *NetQueuePull()
return entry;
}
U0 NetQueuePushCopy(U8 *data, I64 length)
{/* Pushes a copy of the packet data and length
into the Net Queue. The NetQueueEntry is inserted
@ -72,27 +70,4 @@ U0 NetQueuePushCopy(U8 *data, I64 length)
}
NetQueueInit;
NetQueueInit;

View file

@ -81,7 +81,8 @@
class CPCNet
{
CPCIDev *pci;
U8 mac_address[6]; // MAC address is first 6 bytes of PCNet EEPROM (page # ? )
U8 mac_address[6]; // MAC address is first 6 bytes of PCNet EEPROM (page # ? )
I64 current_rx_de_index; // Current Receive DE being processed. Gets incremented, wrapped to 0 at max of PCNET_RX_BUFF_COUNT.
I64 current_tx_de_index; // Current Transmit DE being processed. Gets incremented, wrapped to 0 at max of PCNET_TX_BUFF_COUNT.
@ -102,6 +103,7 @@ class CPCNetDescriptorEntry
but have different registers and functions.
The RX and TX DE buffers of the CPCNet class
are allocated to a certain amount of these DEs. */
U32 buffer_addr;
U32 status1;
U32 status2;

View file

@ -45,14 +45,14 @@
#define IP_PARSE_STATE_NUM 0
#define IP_PARSE_STATE_DOT 1
/*
class CSocketAddress
{
U16 family; // 'address family, AF_xxx'
U8 data[14]; // '14 bytes of protocol address'
};
*/
class CIPV4Address
{
U32 address; // 'in Network Byte order' ... Big Endian
@ -70,24 +70,19 @@ class CIPAddressStorage
class CSocketAddressIPV4
{
I16 family; // 'AF_INET'
U16 port; // 'in Network Byte order' ... Big Endian
CIPV4Address address;
U8 zeroes[8]; // 'same size as socket address'
I16 family; // 'AF_INET'
U16 port; // 'in Network Byte order' ... Big Endian
CIPV4Address address;
U8 zeroes[8]; // 'same size as socket address'
};
class CSocketAddressIPV6
{
U16 family; // 'AF_INET6'
U16 port; // 'in Network Byte order'... Big Endian
U32 flow_info;
CIPV6Address address;
U32 scope_id;
U16 family; // 'AF_INET6'
U16 port; // 'in Network Byte order'... Big Endian
U32 flow_info;
CIPV6Address address;
U32 scope_id;
};
class CSocketAddressStorage
@ -95,25 +90,20 @@ class CSocketAddressStorage
hold both IPV4 and IPV6 structures.' */
U16 family;
U8 padding[26];
U8 padding[26];
};
class CAddressInfo
{
I32 flags;
I32 family;
I32 socket_type;
I32 protocol;
I64 address_length;
CSocketAddress *address;
U8 *canonical_name;
CAddressInfo *next;
I32 flags;
I32 family;
I32 socket_type;
I32 protocol;
I64 address_length;
CSocketAddressStorage *address;
U8 *canonical_name;
CAddressInfo *next;
};
class CSocket
@ -124,6 +114,22 @@ class CSocket
U16 domain;
};
U0 AddressInfoCopy(CAddressInfo *out, CAddressInfo *in)
{ // assumes *out already exists
MemCopy(out, in, sizeof(CAddressInfo));
if (in->address)
{
out->address = CAlloc(in->address_length);
MemCopy(out->address, in->address, in->address_length);
}
if (in->canonical_name)
{
out->canonical_name = StrNew(in->canonical_name);
}
}
Bool IPV4AddressParse(U8 *string, U32 *destination)
{
// U8* lexable_string;
@ -339,9 +345,6 @@ U0 SocketStateErr(U8 *request, U8 state)
ZenithErr("Socket attempted %s while in %s state.\n", request, state_string);
}
U0 SocketAccept(CSocket *socket)
{
switch (socket->state)

View file

View file

View file

@ -8,48 +8,40 @@ class CUDPHeader
{
U16 source_port;
U16 destination_port;
U16 length;
U16 checksum;
};
class CUDPSocket
{
CSocket *socket;
I64 receive_timeout_ms;
I64 receive_max_timeout;
U8 *receive_buffer;
I64 receive_len;
CSocketAddressStorage receive_address; // based on ->family, cast or assign to a var as IPV4/IPV6 CSocketAddress
U16 bound_to; // represents the currently bound port
CSocket *socket;
I64 receive_timeout_ms;
I64 receive_max_timeout;
U8 *receive_buffer;
I64 receive_len;
CSocketAddressStorage receive_address; // based on ->family, cast or assign to a var as IPV4/IPV6 CSocketAddress
U16 bound_to; // represents the currently bound port
};
/***************************************************
UDP Bound Socket Tree Classes & Functions
////////////////////////////////////////////////////
// UDP Bound Socket Tree Classes & Functions
***************************************************/
class CUDPTreeQueue
{ // next, last for CQueue implementation.
CUDPTreeQueue *next;
CUDPTreeQueue *last;
CUDPSocket *socket;
CUDPTreeQueue *next;
CUDPTreeQueue *last;
CUDPSocket *socket;
};
class CUDPTreeNode
{
I64 port;
CUDPTreeNode *left;
CUDPTreeNode *right;
CUDPTreeQueue *queue;
I64 port;
CUDPTreeNode *left;
CUDPTreeNode *right;
CUDPTreeQueue *queue;
};
CUDPTreeNode *UDPTreeNodeInit()
@ -316,16 +308,8 @@ CUDPTreeQueue *UDPTreeNodeQueueSinglePop(U32 address, CUDPTreeNode *node)
return temp_queue; // if not found, NULL.
}
*/
// end UDP Bound Socket functions & classes
////////////////////////////////////////////////////
/***************************************************/
class CUDPGlobals
{
@ -788,4 +772,4 @@ I64 UDPHandler(CIPV4Packet *packet)
// ZenithErr and return fail vals if socket FSM improperly used.
// Careful with Free()'s.
UDPGlobalsInit;
UDPGlobalsInit;