/// <summary> /// Transmit packet /// </summary> /// <param name="bytes">byte buffer</param> /// <param name="size">packet size</param> public static unsafe void Transmit(NetPacketDesc *packet) { int size = packet->end - packet->start; if (size < 0) { return; } byte *buffer = (byte *)Heap.Alloc(size); if (buffer == null) { return; } Memory.Memcpy(buffer, packet->buffer + packet->start, size); #if NETWORK_DEBUG Console.Write("[NET] Transmit packet with "); Console.WriteNum(size); Console.WriteLine(" bytes"); #endif m_dev.Transmit?.Invoke(buffer, (uint)size); Heap.Free(buffer); }
/// <summary> /// Process request /// </summary> /// <param name="ip">IP</param> /// <param name="id">ID</param> /// <param name="seq">Sequence number</param> /// <param name="data">Packet data</param> /// <param name="length">Packet length</param> private static unsafe void EchoReply(byte[] ip, ushort id, ushort seq, byte *data, int length) { NetPacketDesc *packet = NetPacket.Alloc(); ICMPHeader *hdr = (ICMPHeader *)(packet->buffer + packet->start); hdr->Type = TYPE_ECHO_REPLY; hdr->ID = id; hdr->SeqNum = seq; hdr->Code = 0; hdr->CheckSum = 0; packet->end += (short)sizeof(ICMPHeader); Memory.Memcpy(packet->buffer + packet->end, data, length); packet->end += (short)length; hdr->CheckSum = NetworkTools.Checksum((byte *)(packet->buffer + packet->start), sizeof(ICMPHeader) + length); IPV4.Send(packet, ip, 0x01); NetPacket.Free(packet); }
/// <summary> /// Send IPV4 packet /// </summary> /// <param name="packet">Packet structure</param> /// <param name="destMac">Destination mac</param> /// <param name="destIP">Destination IP</param> /// <param name="protocol">Protocol</param> public static unsafe void Send(NetPacketDesc *packet, byte[] destIP, byte protocol) { byte[] sourceIP = Util.PtrToArray(Network.Settings->IP); addHeader(packet, sourceIP, destIP, protocol); Ethernet.Send(packet, destIP, EthernetTypes.IPV4); }
/// <summary> /// Send to UDP /// </summary> /// <param name="buffer"></param> /// <param name="size"></param> public unsafe void SendByPacket(byte *buffer, uint size) { // Minimal size :O if (size < 6) { return; } UDPPacketHeader *header = (UDPPacketHeader *)buffer; // Uhhh no if (size < header->Size + sizeof(UDPPacketHeader)) { return; } NetPacketDesc *packet = NetPacket.Alloc(); Memory.Memcpy(packet->buffer + packet->start + sizeof(UDPPacketHeader), buffer, (int)header->Size); packet->end += (short)header->Size; UDP.Send(packet, Util.PtrToArray(header->IP), m_sourcePort, m_targetPort); NetPacket.Free(packet); }
/// <summary> /// Finish header and create checksum /// </summary> /// <param name="packet"></param> /// <param name="header"></param> /// <param name="sourceIp"></param> /// <param name="packetLength"></param> /// <param name="dataLength"></param> /// <returns></returns> private static unsafe bool FinishHeader(NetPacketDesc *packet, TCPHeader *header, byte[] sourceIp, int packetLength, int dataLength) { // Welp! if (packetLength % 4 != 0) { return(false); } header->Length = (byte)((packetLength / 4) << 4); ushort size = (ushort)packetLength; size += (ushort)sizeof(TCPChecksum); // Let's introduce some junk (i love that :)) TCPChecksum *checksumHeader = (TCPChecksum *)(packet->buffer + packet->start - sizeof(TCPChecksum)); Memory.Memcpy(checksumHeader->SrcIP, Network.Settings->IP, 4); Memory.Memcpy(checksumHeader->DstIP, Util.ObjectToVoidPtr(sourceIp), 4); checksumHeader->Protocol = PROTOCOL_TCP; checksumHeader->Reserved = 0; checksumHeader->Length = Byte.ReverseBytes((ushort)((ushort)packetLength + dataLength)); byte *ptr = packet->buffer + packet->start - sizeof(TCPChecksum); header->Checksum = NetworkTools.Checksum(ptr, size + dataLength); return(true); }
/// <summary> /// Send ethernet packet /// </summary> /// <param name="packet">Packet structure</param> /// <param name="destMAC">Destination MAC</param> /// <param name="protocol">Protocol</param> public static unsafe void Send(NetPacketDesc *packet, byte[] destIP, EthernetTypes protocol) { // 1 TIME PLEASE byte *srcMAC = (byte *)Heap.Alloc(6); Network.GetMac(srcMAC); // Get MAC from ARP :D byte *dstMac = (byte *)Heap.Alloc(6); bool found = Route.FindRoute(destIP, dstMac); if (!found) { Heap.Free(srcMAC); Heap.Free(dstMac); return; } addHeader(packet, Util.PtrToArray(dstMac), Util.PtrToArray(srcMAC), protocol); Network.Transmit(packet); Heap.Free(srcMAC); Heap.Free(dstMac); }
/// <summary> /// Allocates a new network packet descriptor /// </summary> /// <returns>New network packet descriptor</returns> public static unsafe NetPacketDesc *Alloc() { NetPacketDesc *desc = (NetPacketDesc *)Heap.Alloc(sizeof(NetPacketDesc)); Memory.Memclear(desc->buffer, 4096); desc->start = 256; desc->end = 256; return(desc); }
/// <summary> /// Send UDP packet /// </summary> /// <param name="packet">Packet structure</param> /// <param name="destMac">Destination MAC</param> /// <param name="destIP">Destination IP</param> /// <param name="srcPort">Source port</param> /// <param name="DestPort">Destination port</param> public static unsafe void Send(NetPacketDesc *packet, byte[] destIP, ushort srcPort, ushort DestPort) { /** * No support for packets over 1500 bytes */ if (packet->end - packet->start >= 1500) { return; } addHeader(packet, destIP, srcPort, DestPort); IPV4.Send(packet, destIP, PROTOCOL_UDP); }
/// <summary> /// Send ethernet packet /// </summary> /// <param name="packet">Packet structure</param> /// <param name="destMAC">Destination MAC</param> /// <param name="protocol">Protocol</param> public static unsafe void SendMAC(NetPacketDesc *packet, byte[] destMac, EthernetTypes protocol) { // 1 TIME PLEASE byte *srcMAC = (byte *)Heap.Alloc(6); Network.GetMac(srcMAC); addHeader(packet, destMac, Util.PtrToArray(srcMAC), protocol); Heap.Free(srcMAC); Network.Transmit(packet); }
/// <summary> /// Add header to packet /// </summary> /// <param name="packet">Packet structure</param> /// <param name="dest">Destination MAC</param> /// <param name="src">Source MAC</param> /// <param name="protocol">Protocol</param> /// <returns></returns> private static unsafe EthernetHeader *addHeader(NetPacketDesc *packet, byte[] dest, byte[] src, EthernetTypes protocol) { packet->start -= (short)sizeof(EthernetHeader); EthernetHeader *header = (EthernetHeader *)(packet->buffer + packet->start); Memory.Memcpy(header->Destination, Util.ObjectToVoidPtr(dest), 6); Memory.Memcpy(header->Source, Util.ObjectToVoidPtr(src), 6); header->Protocol = Byte.ReverseBytes((ushort)protocol); return(header); }
/// <summary> /// Add UDP header to packet /// </summary> /// <param name="packet">Packet structure</param> /// <param name="destIP">Destination IP</param> /// <param name="sourcePort">Source port</param> /// <param name="DestinationPort">Destination port</param> /// <returns>The pointer to the header</returns> private static unsafe UDPHeader *addHeader(NetPacketDesc *packet, byte[] destIP, ushort sourcePort, ushort DestinationPort) { packet->start -= (short)sizeof(UDPHeader); UDPHeader *header = (UDPHeader *)(packet->buffer + packet->start); header->SourcePort = Byte.ReverseBytes(sourcePort); header->DestinationPort = Byte.ReverseBytes(DestinationPort); header->Length = Byte.ReverseBytes((ushort)(packet->end - packet->start)); header->Checksum = 0; return(header); }
/// <summary> /// Add header to packet /// </summary> /// <param name="packet"></param> /// <param name="srcPort"></param> /// <param name="dstPort"></param> /// <param name="flags"></param> /// <param name="seqNum"></param> /// <param name="ackNum"></param> /// <param name="winSize"></param> /// <returns></returns> private static unsafe TCPHeader *addHeader(NetPacketDesc *packet, ushort srcPort, ushort dstPort, byte flags, uint seqNum, uint ackNum, ushort winSize) { packet->start -= (short)sizeof(TCPHeader); // Generate stub header TCPHeader *header = (TCPHeader *)(packet->buffer + packet->start); header->SourcePort = Byte.ReverseBytes(srcPort); header->DestPort = Byte.ReverseBytes(dstPort); header->Flags = flags; header->Urgent = 0; header->WindowSize = Byte.ReverseBytes(winSize); header->Acknowledge = ackNum; header->Sequence = seqNum; header->Checksum = 0; return(header); }
/// <summary> /// Send to UDP /// </summary> /// <param name="buffer"></param> /// <param name="size"></param> public unsafe void Send(byte *buffer, uint size) { // We can't do this if we just connect if (!m_ipSpecified) { return; } NetPacketDesc *packet = NetPacket.Alloc(); Memory.Memcpy(packet->buffer + packet->start, buffer, (int)size); packet->end += (short)size; UDP.Send(packet, m_ip, m_sourcePort, m_targetPort); NetPacket.Free(packet); }
/// <summary> /// Add DHCP header in packet /// </summary> /// <param name="packet"></param> /// <param name="xid"></param> /// <param name="clientIP"></param> /// <param name="messageType"></param> private static unsafe void addHeader(NetPacketDesc *packet, uint xid, byte[] clientIP, byte messageType) { DHCPBootstrapHeader *header = (DHCPBootstrapHeader *)(packet->buffer + packet->start); Memory.Memclear(header, sizeof(DHCPBootstrapHeader)); header->Opcode = 1; // REQUEST header->HardwareType = HARDTYPE_ETH; // Ethernet header->HardwareAddressLength = 6; // IPV4 header->Hops = 0; header->TransactionID = Byte.ReverseBytes(xid); header->SecondsElapsed = 0; // NULLLLL header->BootpFlags = 0; // NONNNN for (int i = 0; i < 4; i++) { header->ClientIP[i] = clientIP[i]; } Network.GetMac(header->ClientMac); packet->end += (short)sizeof(DHCPBootstrapHeader); /** * Default options */ byte *opt = packet->buffer + packet->end; uint *topt = (uint *)opt; *topt = Byte.ReverseBytes(MAGISCH_KOEKJE); // 4 bytes! opt += 4; // Another FOUR! /** * Set message type */ *opt++ = OPT_DHCP_MESSAGE_TYPE; // OPT_DHCP_MESSAGE_TYPE *opt++ = 1; *opt++ = messageType; packet->end += 7; }
/// <summary> /// Send UDP data /// </summary> /// <param name="destMac">Destination MAC</param> /// <param name="destIP">Destination IP</param> /// <param name="srcPort">Source port</param> /// <param name="DestPort">Destination port</param> /// <param name="data">Data pointer</param> /// <param name="size">Data size</param> public static unsafe void Send(byte[] destMac, byte[] destIP, ushort srcPort, ushort DestPort, byte[] data, int size) { /** * No support for packets over 1500 bytes */ if (size >= 1500) { return; } NetPacketDesc *packet = NetPacket.Alloc(); Memory.Memcpy(packet->buffer + packet->start, Util.ObjectToVoidPtr(data), size); addHeader(packet, destIP, srcPort, DestPort); IPV4.Send(packet, destIP, PROTOCOL_UDP); NetPacket.Free(packet); }
/// <summary> /// Send packet to TCP /// </summary> /// <param name="destIP"></param> /// <param name="seqNum"></param> /// <param name="acknumb"></param> /// <param name="srcPort"></param> /// <param name="destPort"></param> /// <param name="flags"></param> /// <param name="data"></param> /// <param name="count"></param> /// <returns></returns> private static unsafe bool SendPacket(byte[] destIP, uint seqNum, uint acknumb, ushort srcPort, ushort destPort, byte flags, byte *data, int count) { NetPacketDesc *packet = NetPacket.Alloc(); if (count > 0) { Memory.Memcpy(packet->buffer + packet->start, data, count); packet->end += (short)count; } TCPHeader *outHeader = addHeader(packet, srcPort, destPort, flags, seqNum, acknumb, 8192); FinishHeader(packet, outHeader, destIP, sizeof(TCPHeader), count); IPV4.Send(packet, destIP, PROTOCOL_TCP); NetPacket.Free(packet); return(true); }
public static unsafe void ArpSend(ushort op, byte[] hwAddr, byte[] ip) { byte *mac = (byte *)Heap.Alloc(6); Network.GetMac(mac); NetPacketDesc *packet = NetPacket.Alloc(); ARPHeader *hdr = (ARPHeader *)(packet->buffer + packet->end); hdr->HardwareType = Byte.ReverseBytes(0x01); hdr->ProtocolType = Byte.ReverseBytes(0x800); hdr->HardwareAdrLength = 6; hdr->ProtocolAdrLength = 4; hdr->Opcode = Byte.ReverseBytes(op); Memory.Memcpy(hdr->SrcIP, Network.Settings->IP, 4); Memory.Memcpy(hdr->SrcHw, mac, 6); Memory.Memcpy(hdr->DstIP, Util.ObjectToVoidPtr(ip), 4); if (op == OP_REPLY) { Memory.Memcpy(hdr->DstHw, Util.ObjectToVoidPtr(hwAddr), 6); } else { Memory.Memset(hdr->DstHw, 0, 6); } packet->end += (short)sizeof(ARPHeader); Ethernet.SendMAC(packet, hwAddr, EthernetTypes.ARP); NetPacket.Free(packet); Heap.Free(mac); }
/// <summary> /// Add IPV4 header to packet /// </summary> /// <param name="packet">Packet structure</param> /// <param name="sourceIP">Source IP</param> /// <param name="destIP">Destination IP</param> /// <param name="protocol">Protocol</param> /// <returns></returns> private static unsafe IPV4Header *addHeader(NetPacketDesc *packet, byte[] sourceIP, byte[] destIP, byte protocol) { packet->start -= (short)sizeof(IPV4Header); IPV4Header *header = (IPV4Header *)(packet->buffer + packet->start); header->Version = (4 << 4) | 5; header->ServicesField = 0; header->totalLength = Byte.ReverseBytes((ushort)(packet->end - packet->start)); header->ID = Byte.ReverseBytes(0xa836); // TODO: FIX THIS! header->FragmentOffset = 0; header->TTL = 250; header->Protocol = protocol; // The checksum calculation needs to be done with header checksum filled in as zero // then it is filled in later header->HeaderChecksum = 0; Memory.Memcpy(header->Source, Util.ObjectToVoidPtr(sourceIP), 4); Memory.Memcpy(header->Destination, Util.ObjectToVoidPtr(destIP), 4); header->HeaderChecksum = (NetworkTools.Checksum(packet->buffer + packet->start, sizeof(IPV4Header))); return(header); }
/// <summary> /// Perform a DHCP request /// </summary> /// <param name="buffer">Old packet</param> private static unsafe void request(byte *buffer, byte[] ip) { DHCPBootstrapHeader *header = (DHCPBootstrapHeader *)buffer; NetPacketDesc * packet = NetPacket.Alloc(); byte[] tmp = new byte[4]; /** * Write header to packet */ addHeader(packet, Byte.ReverseBytes(header->TransactionID), tmp, DHCP_REQUEST); /** * Write our received ip */ byte *buf = packet->buffer + packet->end; *buf++ = OPT_REQ_IP; *buf++ = 4; // IP is 4 bytes for (int i = 0; i < 4; i++) { *buf++ = header->YourClientIP[i]; } packet->end += 6; string hostname = Network.GetHostName(); int hostnameLength = hostname.Length; if (hostnameLength > 0xFF) { hostnameLength = 0xFF; } /** * Write our hostname */ buf = packet->buffer + packet->end; *buf++ = OPT_HOSTNAME; *buf++ = (byte)hostnameLength; for (int i = 0; i < hostnameLength; i++) { *buf++ = (byte)hostname[i]; } packet->end += 10; buf = packet->buffer + packet->end; *buf++ = OPT_SERVER_ID; *buf++ = 4; for (int i = 0; i < 4; i++) { *buf++ = ip[i]; } packet->end += 6; /** * Choose what we want to receive */ buf = packet->buffer + packet->end; *buf++ = OPT_PARAMETER_REQUEST; // OPT_PARAMETER_REQUEST *buf++ = 4; // Length of 4 :) *buf++ = OPT_SUBNET; // SUBNET *buf++ = OPT_ROUTER; // ROUTER *buf++ = OPT_NTP; // NTP *buf++ = OPT_DNS; // DNS *buf++ = OPT_END; // And then packet->end += 14; for (int i = 0; i < 4; i++) { tmp[i] = 0xFF; } UDP.Send(packet, tmp, 68, 67); NetPacket.Free(packet); Heap.Free(tmp); }
/// <summary> /// DHCP discover /// </summary> public static unsafe void Discover() { m_mac = new byte[6]; Network.GetMac((byte *)Util.ObjectToVoidPtr(m_mac)); byte[] tmp = new byte[4]; uint xid = (uint)Random.Rand(); /** * Get source and destination packets */ NetPacketDesc *packet = NetPacket.Alloc(); /** * Add DHCP discover header */ addHeader(packet, xid, tmp, DHCP_DISCOVER); /** * Write what we send */ byte *buf = packet->buffer + packet->end; *buf++ = OPT_CLIENT_ID; // OPT_CLIENT_ID *buf++ = 7; // Length *buf++ = 1; // Ethernet /** * Write mac address to packet */ for (int i = 0; i < 6; i++) { *buf++ = m_mac[i]; } packet->end += 9; /** * Request hostname */ string hostname = Network.GetHostName(); int hostnameLength = hostname.Length; if (hostnameLength > 0xFF) { hostnameLength = 0xFF; } /** * Write our hostname */ buf = packet->buffer + packet->end; *buf++ = OPT_HOSTNAME; *buf++ = (byte)hostnameLength; for (int i = 0; i < hostnameLength; i++) { *buf++ = (byte)hostname[i]; } packet->end += 10; /** * Specify options */ buf = packet->buffer + packet->end; *buf++ = OPT_PARAMETER_REQUEST; // OPT_PARAMETER_REQUEST *buf++ = 4; // Length of 4 :) *buf++ = OPT_SUBNET; // SUBNET *buf++ = OPT_ROUTER; // ROUTER *buf++ = OPT_NTP; // NTP *buf++ = OPT_DNS; // DNS *buf++ = OPT_END; // And then packet->end += 14; for (int i = 0; i < 4; i++) { tmp[i] = 0xFF; } UDP.Send(packet, tmp, 68, 67); NetPacket.Free(packet); }
/// <summary> /// Frees a network packet descriptor /// </summary> /// <param name="packet">The network packet descriptor</param> public static unsafe void Free(NetPacketDesc *packet) { Heap.Free(packet); }