ethinject and plumbing for transmitting raw network packets.
This commit is contained in:
parent
289412b585
commit
9251a3b7cc
@ -162,6 +162,7 @@ CopyTree('build/include/machine', 'sys/' + env['ARCH'] + '/include', env)
|
|||||||
SConscript('sys/SConscript', variant_dir='build/sys')
|
SConscript('sys/SConscript', variant_dir='build/sys')
|
||||||
SConscript('lib/libc/SConscript', variant_dir='build/lib/libc')
|
SConscript('lib/libc/SConscript', variant_dir='build/lib/libc')
|
||||||
SConscript('bin/ethdump/SConscript', variant_dir='build/bin/ethdump')
|
SConscript('bin/ethdump/SConscript', variant_dir='build/bin/ethdump')
|
||||||
|
SConscript('bin/ethinject/SConscript', variant_dir='build/bin/ethinject')
|
||||||
SConscript('bin/shell/SConscript', variant_dir='build/bin/shell')
|
SConscript('bin/shell/SConscript', variant_dir='build/bin/shell')
|
||||||
SConscript('sbin/ifconfig/SConscript', variant_dir='build/sbin/ifconfig')
|
SConscript('sbin/ifconfig/SConscript', variant_dir='build/sbin/ifconfig')
|
||||||
SConscript('sbin/init/SConscript', variant_dir='build/sbin/init')
|
SConscript('sbin/init/SConscript', variant_dir='build/sbin/init')
|
||||||
@ -185,6 +186,7 @@ if env["BOOTDISK"] == "1":
|
|||||||
bootdisk = env.BuildImage('#build/bootdisk.img', '#release/bootdisk.manifest')
|
bootdisk = env.BuildImage('#build/bootdisk.img', '#release/bootdisk.manifest')
|
||||||
Depends(bootdisk, "#build/tools/newfs_o2fs/newfs_o2fs")
|
Depends(bootdisk, "#build/tools/newfs_o2fs/newfs_o2fs")
|
||||||
Depends(bootdisk, "#build/bin/ethdump/ethdump")
|
Depends(bootdisk, "#build/bin/ethdump/ethdump")
|
||||||
|
Depends(bootdisk, "#build/bin/ethinject/ethinject")
|
||||||
Depends(bootdisk, "#build/bin/shell/shell")
|
Depends(bootdisk, "#build/bin/shell/shell")
|
||||||
Depends(bootdisk, "#build/sbin/ifconfig/ifconfig")
|
Depends(bootdisk, "#build/sbin/ifconfig/ifconfig")
|
||||||
Depends(bootdisk, "#build/sbin/init/init")
|
Depends(bootdisk, "#build/sbin/init/init")
|
||||||
|
@ -67,7 +67,7 @@ main(int argc, const char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Listening to nic%d\n", nic.nicNo);
|
printf("Listening to nic%d\n", (int)nic.nicNo);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
readPacket(&nic);
|
readPacket(&nic);
|
||||||
|
21
bin/ethinject/SConscript
Normal file
21
bin/ethinject/SConscript
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import sys
|
||||||
|
|
||||||
|
Import('env')
|
||||||
|
|
||||||
|
ethinject_env = env.Clone()
|
||||||
|
|
||||||
|
src = [ ]
|
||||||
|
|
||||||
|
src_common = [
|
||||||
|
"ethinject.c"
|
||||||
|
]
|
||||||
|
|
||||||
|
src.append(src_common)
|
||||||
|
|
||||||
|
ethinject_env.Append(LINKFLAGS = ['-nostdlib'])
|
||||||
|
ethinject_env.Append(CPPFLAGS = ['-nostdinc'])
|
||||||
|
ethinject_env.Append(CPPPATH = ['#build/include'])
|
||||||
|
ethinject_env.Append(LIBPATH = ['#build/lib/libc'], LIBS = ['c'])
|
||||||
|
|
||||||
|
ethinject_env.Program("ethinject", src)
|
||||||
|
|
73
bin/ethinject/ethinject.c
Normal file
73
bin/ethinject/ethinject.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <syscall.h>
|
||||||
|
#include <sys/nic.h>
|
||||||
|
|
||||||
|
#include <net/ethernet.h>
|
||||||
|
|
||||||
|
static int nicNo = 1;
|
||||||
|
static char buf[4096];
|
||||||
|
static MBuf mbuf;
|
||||||
|
|
||||||
|
void
|
||||||
|
writePacket(NIC *nic)
|
||||||
|
{
|
||||||
|
uint64_t status;
|
||||||
|
|
||||||
|
mbuf.vaddr = (uint64_t)&buf;
|
||||||
|
mbuf.maddr = 0;
|
||||||
|
mbuf.len = 64;
|
||||||
|
mbuf.type = MBUF_TYPE_NULL;
|
||||||
|
mbuf.flags = 0;
|
||||||
|
mbuf.status = MBUF_STATUS_NULL;
|
||||||
|
|
||||||
|
status = OSNICSend(nicNo, &mbuf);
|
||||||
|
if (status != 0) {
|
||||||
|
printf("OSNICSend failed!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbuf.status == MBUF_STATUS_FAILED) {
|
||||||
|
printf("Failed to write packet!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, const char *argv[])
|
||||||
|
{
|
||||||
|
uint64_t status;
|
||||||
|
NIC nic;
|
||||||
|
|
||||||
|
printf("Ethernet Dump Tool\n");
|
||||||
|
|
||||||
|
status = OSNICStat(nicNo, &nic);
|
||||||
|
if (status == ENOENT) {
|
||||||
|
printf("nic%d not present\n", nicNo);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Injecting packet on nic%d\n", (int)nic.nicNo);
|
||||||
|
|
||||||
|
struct ether_header *hdr = (struct ether_header *)&buf;
|
||||||
|
hdr->ether_dhost[0] = 0xFF;
|
||||||
|
hdr->ether_dhost[1] = 0xFF;
|
||||||
|
hdr->ether_dhost[2] = 0xFF;
|
||||||
|
hdr->ether_dhost[3] = 0xFF;
|
||||||
|
hdr->ether_dhost[4] = 0xFF;
|
||||||
|
hdr->ether_dhost[5] = 0xFF;
|
||||||
|
|
||||||
|
hdr->ether_shost[0] = 0x00;
|
||||||
|
hdr->ether_shost[1] = 0x11;
|
||||||
|
hdr->ether_shost[2] = 0x22;
|
||||||
|
hdr->ether_shost[3] = 0x33;
|
||||||
|
hdr->ether_shost[4] = 0x44;
|
||||||
|
hdr->ether_shost[5] = 0x55;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
writePacket(&nic);
|
||||||
|
sleep(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -22,6 +22,7 @@ struct ether_addr {
|
|||||||
|
|
||||||
#define ETHERTYPE_IP 0x0800 /* IP */
|
#define ETHERTYPE_IP 0x0800 /* IP */
|
||||||
#define ETHERTYPE_ARP 0x0806 /* ARP */
|
#define ETHERTYPE_ARP 0x0806 /* ARP */
|
||||||
|
#define ETHERTYPE_REVARP 0x8036 /* Reverse ARP */
|
||||||
#define ETHERTYPE_IPV6 0x86DD /* IPv6 */
|
#define ETHERTYPE_IPV6 0x86DD /* IPv6 */
|
||||||
|
|
||||||
#endif /* __NET_ETHERNET_H__ */
|
#endif /* __NET_ETHERNET_H__ */
|
||||||
|
@ -39,6 +39,8 @@ int puts(const char *str);
|
|||||||
|
|
||||||
int printf(const char *fmt, ...);
|
int printf(const char *fmt, ...);
|
||||||
int fprintf(FILE *stream, const char *fmt, ...);
|
int fprintf(FILE *stream, const char *fmt, ...);
|
||||||
|
int sprintf(char *str, const char *fmt, ...);
|
||||||
|
int snprintf(char *str, size_t size, const char *fmt, ...);
|
||||||
|
|
||||||
#endif /* __STDIO_H__ */
|
#endif /* __STDIO_H__ */
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ DIR /
|
|||||||
END
|
END
|
||||||
DIR bin
|
DIR bin
|
||||||
FILE ethdump build/bin/ethdump/ethdump
|
FILE ethdump build/bin/ethdump/ethdump
|
||||||
|
FILE ethinject build/bin/ethinject/ethinject
|
||||||
FILE shell build/bin/shell/shell
|
FILE shell build/bin/shell/shell
|
||||||
END
|
END
|
||||||
DIR sbin
|
DIR sbin
|
||||||
|
@ -58,6 +58,7 @@ void E1000_Configure(PCIDevice dev);
|
|||||||
#define E1000_REG_TDH 0x3810
|
#define E1000_REG_TDH 0x3810
|
||||||
#define E1000_REG_TDT 0x3818
|
#define E1000_REG_TDT 0x3818
|
||||||
#define E1000_REG_TIDV 0x3820
|
#define E1000_REG_TIDV 0x3820
|
||||||
|
#define E1000_REG_TADV 0x382C
|
||||||
|
|
||||||
#define E1000_REG_MTABASE 0x5200
|
#define E1000_REG_MTABASE 0x5200
|
||||||
|
|
||||||
@ -111,6 +112,11 @@ typedef struct PACKED E1000TXDesc {
|
|||||||
volatile uint16_t special;
|
volatile uint16_t special;
|
||||||
} E1000TXDesc;
|
} E1000TXDesc;
|
||||||
|
|
||||||
|
#define TDESC_CMD_RS (1 << 3) /* Report Status */
|
||||||
|
#define TDESC_CMD_IC (1 << 2) /* Insert Checksum */
|
||||||
|
#define TDESC_CMD_IFCS (1 << 1) /* Insert Ethernet FCS/CRC */
|
||||||
|
#define TDESC_CMD_EOP (1 << 0) /* End-of-Packet */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Driver Configuration and Structures
|
* Driver Configuration and Structures
|
||||||
*/
|
*/
|
||||||
@ -220,6 +226,7 @@ void
|
|||||||
E1000_TXPoll(E1000Dev *dev)
|
E1000_TXPoll(E1000Dev *dev)
|
||||||
{
|
{
|
||||||
// Free memory
|
// Free memory
|
||||||
|
kprintf("TXPOLL\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -323,7 +330,7 @@ retry:
|
|||||||
|
|
||||||
//Debug_PrintHex(data, len, 0, len);
|
//Debug_PrintHex(data, len, 0, len);
|
||||||
// Use CB instead
|
// Use CB instead
|
||||||
memcpy(mbuf->vaddr, data, len);
|
memcpy((void *)mbuf->vaddr, data, len);
|
||||||
|
|
||||||
dev->rxDesc[dev->rxTail].status = 0;
|
dev->rxDesc[dev->rxTail].status = 0;
|
||||||
dev->rxDesc[dev->rxTail].errors = 0;
|
dev->rxDesc[dev->rxTail].errors = 0;
|
||||||
@ -353,6 +360,18 @@ retry:
|
|||||||
int
|
int
|
||||||
E1000_Enqueue(NIC *nic, MBuf *mbuf, NICCB cb, void *arg)
|
E1000_Enqueue(NIC *nic, MBuf *mbuf, NICCB cb, void *arg)
|
||||||
{
|
{
|
||||||
|
E1000Dev *dev = (E1000Dev *)nic;
|
||||||
|
void *data = (void *)DMPA2VA(dev->txDesc[dev->txTail].addr);
|
||||||
|
|
||||||
|
// Copy data
|
||||||
|
memcpy(data, (void *)mbuf->vaddr, mbuf->len);
|
||||||
|
dev->txDesc[dev->txTail].len = mbuf->len;
|
||||||
|
|
||||||
|
dev->txDesc[dev->txTail].cmd = TDESC_CMD_EOP | TDESC_CMD_IFCS | TDESC_CMD_RS;
|
||||||
|
MMIO_Write32(dev, E1000_REG_TDT, dev->txTail);
|
||||||
|
dev->txTail = (dev->txTail + 1) % E1000_TX_QLEN;
|
||||||
|
|
||||||
|
// Wait for transmit to complete
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -392,7 +411,7 @@ E1000_TXInit(E1000Dev *dev)
|
|||||||
|
|
||||||
dev->txDesc = (E1000TXDesc *)E1000RXDesc_Alloc();
|
dev->txDesc = (E1000TXDesc *)E1000RXDesc_Alloc();
|
||||||
for (i = 0; i < E1000_TX_QLEN; i++) {
|
for (i = 0; i < E1000_TX_QLEN; i++) {
|
||||||
dev->txDesc[i].addr = 0;
|
dev->txDesc[i].addr = VA2PA((uintptr_t)PAlloc_AllocPage()); // LOOKUP IN PMAP
|
||||||
dev->txDesc[i].cmd = 0;
|
dev->txDesc[i].cmd = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,6 +425,10 @@ E1000_TXInit(E1000Dev *dev)
|
|||||||
MMIO_Write32(dev, E1000_REG_TDT, 0);
|
MMIO_Write32(dev, E1000_REG_TDT, 0);
|
||||||
dev->txTail = 0;
|
dev->txTail = 0;
|
||||||
|
|
||||||
|
// Interrupt Delay Timers
|
||||||
|
MMIO_Write32(dev, E1000_REG_TIDV, 1);
|
||||||
|
MMIO_Write32(dev, E1000_REG_TADV, 1);
|
||||||
|
|
||||||
MMIO_Write32(dev, E1000_REG_TCTL, TCTL_EN | TCTL_PSP);
|
MMIO_Write32(dev, E1000_REG_TCTL, TCTL_EN | TCTL_PSP);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,6 +438,9 @@ E1000_Configure(PCIDevice dev)
|
|||||||
E1000Dev *ethDev = (E1000Dev *)PAlloc_AllocPage();
|
E1000Dev *ethDev = (E1000Dev *)PAlloc_AllocPage();
|
||||||
PCI_Configure(&dev);
|
PCI_Configure(&dev);
|
||||||
|
|
||||||
|
// Ensure that the NIC structure is the first thing inside E1000Dev
|
||||||
|
ASSERT((void *)ethDev == (void *)ðDev->nic);
|
||||||
|
|
||||||
if (!runOnce) {
|
if (!runOnce) {
|
||||||
runOnce = true;
|
runOnce = true;
|
||||||
|
|
||||||
|
@ -410,9 +410,13 @@ Syscall_ThreadSleep(uint64_t time)
|
|||||||
|
|
||||||
// If the sleep time is zero just yield
|
// If the sleep time is zero just yield
|
||||||
if (time != 0) {
|
if (time != 0) {
|
||||||
|
Thread_Retain(cur);
|
||||||
cur->timerEvt = KTimer_Create(time, ThreadWakeupHelper, cur);
|
cur->timerEvt = KTimer_Create(time, ThreadWakeupHelper, cur);
|
||||||
if (cur->timerEvt == NULL)
|
if (cur->timerEvt == NULL) {
|
||||||
|
Thread_Release(cur);
|
||||||
|
Thread_Release(cur);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
Sched_SetWaiting(cur);
|
Sched_SetWaiting(cur);
|
||||||
}
|
}
|
||||||
@ -472,7 +476,25 @@ Syscall_NICStat(uint64_t nicNo, uint64_t user_stat)
|
|||||||
uint64_t
|
uint64_t
|
||||||
Syscall_NICSend(uint64_t nicNo, uint64_t user_mbuf)
|
Syscall_NICSend(uint64_t nicNo, uint64_t user_mbuf)
|
||||||
{
|
{
|
||||||
return SYSCALL_PACK(ENOSYS, 0);
|
int status;
|
||||||
|
NIC *nic;
|
||||||
|
MBuf mbuf;
|
||||||
|
|
||||||
|
status = CopyIn(user_mbuf, &mbuf, sizeof(mbuf));
|
||||||
|
if (status != 0) {
|
||||||
|
return SYSCALL_PACK(status, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
nic = NIC_GetByID(nicNo);
|
||||||
|
if (nic == NULL) {
|
||||||
|
return SYSCALL_PACK(ENOENT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pin Memory
|
||||||
|
(nic->tx)(nic, &mbuf, NULL, NULL);
|
||||||
|
// Unpin Memory
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
|
Loading…
Reference in New Issue
Block a user