complete DHCP. ARP for the DHCP server. feed in proper DNS settings.

This commit is contained in:
Arisotura
2019-02-23 18:50:58 +01:00
parent 93d51b0cbc
commit c135670b9c

View File

@ -74,6 +74,7 @@ int NumAdapters = 0;
void* PCapLib = NULL; void* PCapLib = NULL;
pcap_t* PCapAdapter = NULL; pcap_t* PCapAdapter = NULL;
AdapterData* PCapAdapterData;
u8 PCapPacketBuffer[2048]; u8 PCapPacketBuffer[2048];
int PCapPacketLen; int PCapPacketLen;
@ -249,13 +250,14 @@ bool Init()
#endif // __WIN32__ #endif // __WIN32__
// open pcap device // open pcap device
dev = (pcap_if_t*)Adapters[0].Internal; PCapAdapterData = &Adapters[0];
for (int i = 0; i < NumAdapters; i++) for (int i = 0; i < NumAdapters; i++)
{ {
if (!strncmp(Adapters[i].DeviceName, Config::LANDevice, 128)) if (!strncmp(Adapters[i].DeviceName, Config::LANDevice, 128))
dev = (pcap_if_t*)Adapters[i].Internal; PCapAdapterData = &Adapters[i];
} }
dev = (pcap_if_t*)PCapAdapterData->Internal;
PCapAdapter = pcap_open_live(dev->name, 2048, PCAP_OPENFLAG_PROMISCUOUS, 1, errbuf); PCapAdapter = pcap_open_live(dev->name, 2048, PCAP_OPENFLAG_PROMISCUOUS, 1, errbuf);
if (!PCapAdapter) if (!PCapAdapter)
{ {
@ -336,7 +338,8 @@ zarp=transid;
printf("DHCP: frame type %d, transid %08X\n", type, transid); printf("DHCP: frame type %d, transid %08X\n", type, transid);
if (type == 1) // discover if (type == 1 || // discover
type == 3) // request
{ {
u8 resp[512]; u8 resp[512];
u8* out = &resp[0]; u8* out = &resp[0];
@ -359,7 +362,14 @@ zarp=transid;
*out++ = 0x11; // protocol (UDP) *out++ = 0x11; // protocol (UDP)
*(u16*)out = 0; out += 2; // checksum *(u16*)out = 0; out += 2; // checksum
*(u32*)out = htonl(serverip); out += 4; // source IP *(u32*)out = htonl(serverip); out += 4; // source IP
*(u32*)out = htonl(0xFFFFFFFF); out += 4; // destination IP if (type == 1)
{
*(u32*)out = htonl(0xFFFFFFFF); out += 4; // destination IP
}
else if (type == 3)
{
*(u32*)out = htonl(clientip); out += 4; // destination IP
}
// UDP // UDP
u8* udpheader = out; u8* udpheader = out;
@ -388,7 +398,7 @@ zarp=transid;
// DHCP options // DHCP options
*out++ = 53; *out++ = 1; *out++ = 53; *out++ = 1;
*out++ = 2; // DHCP type: offer *out++ = (type==1) ? 2 : 5; // DHCP type: offer/ack
*out++ = 1; *out++ = 4; *out++ = 1; *out++ = 4;
*(u32*)out = htonl(0xFFFFFF00); out += 4; // subnet mask *(u32*)out = htonl(0xFFFFFF00); out += 4; // subnet mask
*out++ = 3; *out++ = 4; *out++ = 3; *out++ = 4;
@ -397,8 +407,22 @@ zarp=transid;
*(u32*)out = htonl(442030); out += 4; // lease time *(u32*)out = htonl(442030); out += 4; // lease time
*out++ = 54; *out++ = 4; *out++ = 54; *out++ = 4;
*(u32*)out = htonl(serverip); out += 4; // DHCP server *(u32*)out = htonl(serverip); out += 4; // DHCP server
*out++ = 6; *out++ = 4;
*(u32*)out = htonl(0x08080808); out += 4; // DNS (TODO!!) u8 numdns = 0;
for (int i = 0; i < 8; i++)
{
if (*(u32*)&PCapAdapterData->DNS[i][0] != 0)
numdns++;
}
*out++ = 6; *out++ = 4*numdns;
for (int i = 0; i < 8; i++)
{
u32 dnsip = *(u32*)&PCapAdapterData->DNS[i][0];
if (dnsip != 0)
{
*(u32*)out = htonl(dnsip); out += 4;
}
}
*out++ = 0xFF; *out++ = 0xFF;
memset(out, 0, 20); out += 20; memset(out, 0, 20); out += 20;
@ -454,22 +478,87 @@ zarp=transid;
return false; return false;
} }
bool HandleARPFrame(u8* data, int len)
{
const u32 serverip = 0x0A404001;
const u32 clientip = 0x0A404010;
u16 protocol = ntohs(*(u16*)&data[0x10]);
if (protocol != 0x0800) return false;
u16 op = ntohs(*(u16*)&data[0x14]);
u32 targetip = ntohl(*(u32*)&data[0x26]);
if (op == 1 && targetip == serverip)
{
// opcode 1=req 2=reply
// sender MAC
// sender IP
// target MAC
// target IP
u8 resp[64];
u8* out = &resp[0];
// ethernet
memcpy(out, &data[6], 6); out += 6;
*out++ = 0x00; *out++ = 0xAB; *out++ = 0x33;
*out++ = 0x28; *out++ = 0x99; *out++ = 0x44;
*(u16*)out = htons(0x0806); out += 2;
// ARP
*(u16*)out = htons(0x0001); out += 2; // hardware type
*(u16*)out = htons(0x0800); out += 2; // protocol
*out++ = 6; // MAC address size
*out++ = 4; // IP address size
*(u16*)out = htons(0x0002); out += 2; // opcode
*out++ = 0x00; *out++ = 0xAB; *out++ = 0x33;
*out++ = 0x28; *out++ = 0x99; *out++ = 0x44;
*(u32*)out = htonl(targetip); out += 4;
memcpy(out, &data[0x16], 6+4); out += 6+4;
u32 framelen = (u32)(out - &resp[0]);
// TODO: if there is already a packet queued, this will overwrite it
// that being said, this will only happen during DHCP setup, so probably
// not a big deal
PCapPacketLen = framelen;
memcpy(PCapPacketBuffer, resp, PCapPacketLen);
PCapRXNum = 1;
// also broadcast them to the network
pcap_sendpacket(PCapAdapter, data, len);
pcap_sendpacket(PCapAdapter, resp, framelen);
return true;
}
return false;
}
bool HandlePacket(u8* data, int len) bool HandlePacket(u8* data, int len)
{ {
if (ntohs(*(u16*)&data[0xC]) != 0x0800) // IPv4 u16 ethertype = ntohs(*(u16*)&data[0xC]);
return false;
u8 protocol = data[0x17]; if (ethertype == 0x0800) // IPv4
if (protocol == 0x11) // UDP
{ {
u16 srcport = ntohs(*(u16*)&data[0x22]); u8 protocol = data[0x17];
u16 dstport = ntohs(*(u16*)&data[0x24]); if (protocol == 0x11) // UDP
if (srcport == 68 && dstport == 67) // DHCP
{ {
printf("LANMAGIC: DHCP packet\n"); u16 srcport = ntohs(*(u16*)&data[0x22]);
return HandleDHCPFrame(data, len); u16 dstport = ntohs(*(u16*)&data[0x24]);
if (srcport == 68 && dstport == 67) // DHCP
{
printf("LANMAGIC: DHCP packet\n");
return HandleDHCPFrame(data, len);
}
} }
} }
else if (ethertype == 0x0806) // ARP
{
return HandleARPFrame(data, len);
}
return false; return false;
} }