mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2024-12-26 15:26:43 +00:00
Merge pull request #67 from Zeal-Operating-System/network-loopback
Network loopback
This commit is contained in:
commit
d2ee56f425
9 changed files with 103 additions and 33 deletions
|
@ -563,6 +563,11 @@ I64 PCNetTransmitPacketAllocate(U8 **packet_buffer_out, I64 length)
|
||||||
return de_index;
|
return de_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
U8 *EthernetMACGet()
|
||||||
|
{
|
||||||
|
return pcnet.mac_address;
|
||||||
|
}
|
||||||
|
|
||||||
U0 PCNetTransmitPacketFinish(I64 de_index)
|
U0 PCNetTransmitPacketFinish(I64 de_index)
|
||||||
{/* Release ownership of the packet to the PCNet card
|
{/* Release ownership of the packet to the PCNet card
|
||||||
by setting the OWN bit to 1. */
|
by setting the OWN bit to 1. */
|
||||||
|
@ -574,11 +579,23 @@ U0 PCNetTransmitPacketFinish(I64 de_index)
|
||||||
de_index, PCIBt(&entry->status1, PCNET_DESCRIPTORf_OWN));
|
de_index, PCIBt(&entry->status1, PCNET_DESCRIPTORf_OWN));
|
||||||
}
|
}
|
||||||
|
|
||||||
U0 EthernetFrameFinish(I64 de_index)
|
U0 NetDriverTransmitPacketFinish(I64 de_index)
|
||||||
{//Alias for driver Finish TX function.
|
{//Alias for driver-specific Finish TX function.
|
||||||
PCNetTransmitPacketFinish(de_index);
|
PCNetTransmitPacketFinish(de_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
I64 NetDriverPacketBufferGet(I64 de_index)
|
||||||
|
{
|
||||||
|
return pcnet.tx_buffer_addr_phys + de_index * ETHERNET_FRAME_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
I64 NetDriverPacketLengthGet(I64 de_index)
|
||||||
|
{
|
||||||
|
CPCNetDescriptorEntry *entry = &pcnet.tx_de_buffer[de_index * sizeof(CPCNetDescriptorEntry)];
|
||||||
|
|
||||||
|
return U16_MAX - (entry->status1 & 0xFFFF) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
I64 PCNetPacketReceive(U8 **packet_buffer_out, U16 *packet_length_out)
|
I64 PCNetPacketReceive(U8 **packet_buffer_out, U16 *packet_length_out)
|
||||||
{/* Receives the packet at the current RX DE index. Parameters
|
{/* Receives the packet at the current RX DE index. Parameters
|
||||||
are both pointers, since we modify the value at the packet_buffer_out,
|
are both pointers, since we modify the value at the packet_buffer_out,
|
||||||
|
@ -809,11 +826,6 @@ I64 EthernetFrameAllocate(U8 **packet_buffer_out,
|
||||||
return de_index;
|
return de_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
U8 *EthernetMACGet()
|
|
||||||
{
|
|
||||||
return pcnet.mac_address;
|
|
||||||
}
|
|
||||||
|
|
||||||
U0 NetStop()
|
U0 NetStop()
|
||||||
{ // Halt network activity by setting STOP bit on Status CSR.
|
{ // Halt network activity by setting STOP bit on Status CSR.
|
||||||
U32 csr = PCNetCSRRead(PCNET_CSR_CTRLSTATUS);
|
U32 csr = PCNetCSRRead(PCNET_CSR_CTRLSTATUS);
|
||||||
|
|
|
@ -167,15 +167,15 @@ I64 EthernetFrameAllocate(U8 **buffer_out, U8 *src_addr, U8 *dst_addr,
|
||||||
|
|
||||||
I64 index;
|
I64 index;
|
||||||
|
|
||||||
if (!MemCompare(dst_addr, &VirtioNet.mac, 6)) {
|
// if (!MemCompare(dst_addr, &VirtioNet.mac, 6)) {
|
||||||
frame = loopback_frame;
|
// frame = loopback_frame;
|
||||||
loopback_length = length;
|
// loopback_length = length;
|
||||||
index = I64_MAX;
|
// index = I64_MAX;
|
||||||
} else {
|
// } else {
|
||||||
index = @virtio_net_alloc_tx_packet(&frame, 14 + length/*, flags*/);
|
index = @virtio_net_alloc_tx_packet(&frame, 14 + length/*, flags*/);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return index;
|
return index;
|
||||||
}
|
// }
|
||||||
|
|
||||||
MemCopy(frame + 0, dst_addr, 6);
|
MemCopy(frame + 0, dst_addr, 6);
|
||||||
MemCopy(frame + 6, src_addr, 6);
|
MemCopy(frame + 6, src_addr, 6);
|
||||||
|
@ -186,15 +186,26 @@ I64 EthernetFrameAllocate(U8 **buffer_out, U8 *src_addr, U8 *dst_addr,
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
I64 EthernetFrameFinish(I64 index) {
|
//I64 EthernetFrameFinish(I64 index) {
|
||||||
if (index == I64_MAX && loopback_frame && loopback_length) {
|
I64 NetDriverTransmitPacketFinish(I64 index) {
|
||||||
NetQueuePush(loopback_frame, loopback_length);
|
// if (index == I64_MAX && loopback_frame && loopback_length) {
|
||||||
loopback_length = 0;
|
// NetQueuePush(loopback_frame, loopback_length);
|
||||||
return 0;
|
// loopback_length = 0;
|
||||||
}
|
// return 0;
|
||||||
|
// }
|
||||||
return @virtio_net_finish_tx_packet(index);
|
return @virtio_net_finish_tx_packet(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
I64 NetDriverPacketBufferGet(I64 de_index)
|
||||||
|
{
|
||||||
|
return tx_buffers + de_index * ETHERNET_FRAME_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
I64 NetDriverPacketLengthGet(I64 de_index)
|
||||||
|
{ // TODO: ... de_index in Alec's VirtIO-Net driver don't match up to any way to get packet length...
|
||||||
|
return ETHERNET_FRAME_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
U8 *EthernetMACGet() { return &VirtioNet.mac; }
|
U8 *EthernetMACGet() { return &VirtioNet.mac; }
|
||||||
|
|
||||||
I64 @virtio_net_init() {
|
I64 @virtio_net_init() {
|
||||||
|
|
|
@ -24,8 +24,8 @@ U0 ChatMessageTask(I64)
|
||||||
while (message = StrGet("> ",, SGF_SHIFT_ESC_EXIT))
|
while (message = StrGet("> ",, SGF_SHIFT_ESC_EXIT))
|
||||||
{
|
{
|
||||||
DocBottom(chat_display_task->put_doc);
|
DocBottom(chat_display_task->put_doc);
|
||||||
DocPrint(chat_display_task->put_doc,
|
// DocPrint(chat_display_task->put_doc,
|
||||||
"$$BG,BLUE$$$$BLACK$$<local>$$FG$$$$BG$$ %s\n", message);
|
// "$$BG,BLUE$$$$BLACK$$<local>$$FG$$$$BG$$ %s\n", message);
|
||||||
|
|
||||||
TCPSocketSendString(tcp, message);
|
TCPSocketSendString(tcp, message);
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ U0 ChatServerBroadcast(CTCPSocket *tcp_socket, I64 length)
|
||||||
{
|
{
|
||||||
dest_socket = conn->socket;
|
dest_socket = conn->socket;
|
||||||
|
|
||||||
if (dest_socket != tcp_socket)
|
// if (dest_socket != tcp_socket)
|
||||||
{
|
{
|
||||||
addr.address = EndianU32(dest_socket->destination_address(CSocketAddressIPV4).address.address);
|
addr.address = EndianU32(dest_socket->destination_address(CSocketAddressIPV4).address.address);
|
||||||
|
|
||||||
|
@ -51,7 +51,10 @@ U0 ChatServerBroadcast(CTCPSocket *tcp_socket, I64 length)
|
||||||
ip_string = NetworkToPresentation(AF_INET, &addr);
|
ip_string = NetworkToPresentation(AF_INET, &addr);
|
||||||
// TODO: is NetworkToPresentation backwards? or, do socket addrs store BE or LE ?
|
// TODO: is NetworkToPresentation backwards? or, do socket addrs store BE or LE ?
|
||||||
|
|
||||||
message_prefix = MStrPrint("$$BG,PURPLE$$$$BLACK$$<%s>$$FG$$$$BG$$ %%0%dts", ip_string, length);
|
if (dest_socket == tcp_socket)
|
||||||
|
message_prefix = MStrPrint("$$BG,PURPLE$$$$BLACK$$<%s (you)>$$FG$$$$BG$$ %%0%dts", ip_string, length);
|
||||||
|
else
|
||||||
|
message_prefix = MStrPrint("$$BG,PURPLE$$$$BLACK$$<%s>$$FG$$$$BG$$ %%0%dts", ip_string, length);
|
||||||
|
|
||||||
message = MStrPrint(message_prefix, buffer);
|
message = MStrPrint(message_prefix, buffer);
|
||||||
|
|
||||||
|
|
|
@ -127,9 +127,11 @@ CARPHash *ARPCachePut(U32 ip_address, U8 *mac_address)
|
||||||
}
|
}
|
||||||
|
|
||||||
U0 ARPLocalIPV4Set(U32 ip_address)
|
U0 ARPLocalIPV4Set(U32 ip_address)
|
||||||
{ // takes in little endian IP, stores into globals as Big Endian
|
{ // takes in little endian IP, stores into arp_globals as Big Endian and into ARP cache as Little Endian
|
||||||
arp_globals.local_ipv4 = EndianU32(ip_address);
|
arp_globals.local_ipv4 = EndianU32(ip_address);
|
||||||
|
|
||||||
|
ARPCachePut(ip_address, EthernetMACGet);
|
||||||
|
|
||||||
ARPSend(ARP_REPLY,
|
ARPSend(ARP_REPLY,
|
||||||
ethernet_globals.ethernet_broadcast,
|
ethernet_globals.ethernet_broadcast,
|
||||||
EthernetMACGet,
|
EthernetMACGet,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
class CEthernetFrame
|
class CEthernetFrame
|
||||||
{
|
{
|
||||||
U8 source_address[6];
|
U8 source_address[MAC_ADDRESS_LENGTH];
|
||||||
U8 padding[2];
|
U8 padding[2];
|
||||||
U8 destination_address[6];
|
U8 destination_address[MAC_ADDRESS_LENGTH];
|
||||||
U16 ethertype;
|
U16 ethertype;
|
||||||
|
|
||||||
U8 *data;
|
U8 *data;
|
||||||
|
@ -12,15 +12,15 @@ class CEthernetFrame
|
||||||
|
|
||||||
class CEthernetGlobals
|
class CEthernetGlobals
|
||||||
{
|
{
|
||||||
U8 ethernet_null[6];
|
U8 ethernet_null[MAC_ADDRESS_LENGTH];
|
||||||
U8 ethernet_broadcast[6];
|
U8 ethernet_broadcast[MAC_ADDRESS_LENGTH];
|
||||||
|
|
||||||
} ethernet_globals;
|
} ethernet_globals;
|
||||||
|
|
||||||
U0 EthernetGlobalsInit()
|
U0 EthernetGlobalsInit()
|
||||||
{
|
{
|
||||||
I64 i;
|
I64 i;
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < MAC_ADDRESS_LENGTH; i++)
|
||||||
{
|
{
|
||||||
ethernet_globals.ethernet_null[i] = 0;
|
ethernet_globals.ethernet_null[i] = 0;
|
||||||
ethernet_globals.ethernet_broadcast[i] = 0xFF;
|
ethernet_globals.ethernet_broadcast[i] = 0xFF;
|
||||||
|
@ -52,4 +52,19 @@ U0 EthernetFrameParse(CEthernetFrame *frame_out, U8 *frame, U16 length)
|
||||||
frame_out->length = length - ETHERNET_MAC_HEADER_LENGTH - 4; // He has a comment literally just saying "??". + or - 4?
|
frame_out->length = length - ETHERNET_MAC_HEADER_LENGTH - 4; // He has a comment literally just saying "??". + or - 4?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
U0 EthernetFrameFinish(I64 de_index)
|
||||||
|
{//Alias for generic driver Finish TX function.
|
||||||
|
U8 *data = NetDriverPacketBufferGet(de_index);
|
||||||
|
I64 length = NetDriverPacketLengthGet(de_index);
|
||||||
|
U8 *mac = EthernetMACGet();
|
||||||
|
Bool is_loopback = !MemCompare(mac, data, MAC_ADDRESS_LENGTH); // check the TX packet MAC against local MAC
|
||||||
|
|
||||||
|
// software loopback the TX packet to RX NetQueue if it's loopback
|
||||||
|
if (is_loopback)
|
||||||
|
NetQueueLazyPush(data, length);
|
||||||
|
|
||||||
|
NetDriverTransmitPacketFinish(de_index);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
EthernetGlobalsInit;
|
EthernetGlobalsInit;
|
|
@ -68,5 +68,32 @@ U0 NetQueuePush(U8 *data, I64 length)
|
||||||
MPInt(I_NETHANDLER, INT_DEST_CPU);
|
MPInt(I_NETHANDLER, INT_DEST_CPU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
U0 NetQueueLazyPull()
|
||||||
|
{
|
||||||
|
PUSHFD
|
||||||
|
CLI
|
||||||
|
|
||||||
|
if (net_queue->next != net_queue)
|
||||||
|
{
|
||||||
|
NetLog("NETQUEUE LAZY PULL: Generating NetHandler interrupt.");
|
||||||
|
MPInt(I_NETHANDLER, INT_DEST_CPU);
|
||||||
|
}
|
||||||
|
|
||||||
|
POPFD
|
||||||
|
}
|
||||||
|
|
||||||
|
U0 NetQueueLazyPush(U8 *data, I64 length)
|
||||||
|
{ // Push into NetQueue, don't trigger interrupt in this func.
|
||||||
|
// Trigger interrupt by Spawn-ing another Task to check queue.
|
||||||
|
|
||||||
|
CNetQueueEntry *entry = CAlloc(sizeof(CNetQueueEntry));
|
||||||
|
|
||||||
|
entry->packet_length = length;
|
||||||
|
MemCopy(entry->frame, data, length);
|
||||||
|
QueueInsert(entry, net_queue->last);
|
||||||
|
|
||||||
|
Spawn(&NetQueueLazyPull,, "NetQueueLazyPull");
|
||||||
|
}
|
||||||
|
|
||||||
NetQueueInit;
|
NetQueueInit;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ U8 *rev_bits_table; //Table with U8 bits reversed
|
||||||
CDate local_time_offset;
|
CDate local_time_offset;
|
||||||
F64 *pow10_I64,
|
F64 *pow10_I64,
|
||||||
sys_os_version = 2.03;
|
sys_os_version = 2.03;
|
||||||
U64 sys_os_version_sub = 107;
|
U64 sys_os_version_sub = 108;
|
||||||
U8 *sys_os_version_str;
|
U8 *sys_os_version_str;
|
||||||
U8 *sys_os_version_full;
|
U8 *sys_os_version_full;
|
||||||
U8 *sys_os_version_nice;
|
U8 *sys_os_version_nice;
|
||||||
|
|
|
@ -15,7 +15,7 @@ U0 LoadDocDefines()
|
||||||
//$LK,"DD_BOOT_HIGH_LOC_DVD",A="FF:::/System/Boot/BootDVD.ZC,DD_BOOT_HIGH_LOC_DVD"$
|
//$LK,"DD_BOOT_HIGH_LOC_DVD",A="FF:::/System/Boot/BootDVD.ZC,DD_BOOT_HIGH_LOC_DVD"$
|
||||||
|
|
||||||
$TR,"LineRep"$
|
$TR,"LineRep"$
|
||||||
$ID,2$DefinePrint("DD_ZEALOS_LOC","98,756");
|
$ID,2$DefinePrint("DD_ZEALOS_LOC","99,737");
|
||||||
$ID,-2$
|
$ID,-2$
|
||||||
DefinePrint("DD_MP_VECT", "%08X", MP_VECT_ADDR);
|
DefinePrint("DD_MP_VECT", "%08X", MP_VECT_ADDR);
|
||||||
DefinePrint("DD_MP_VECT_END", "%08X", MP_VECT_ADDR + COREAP_16BIT_INIT_END - COREAP_16BIT_INIT - 1);
|
DefinePrint("DD_MP_VECT_END", "%08X", MP_VECT_ADDR + COREAP_16BIT_INIT_END - COREAP_16BIT_INIT - 1);
|
||||||
|
|
Loading…
Reference in a new issue