async void SendTask() { while (true) { if (sendbuf.Count > 0) { var payload = sendbuf.Dequeue(); GREHeader outhead = new GREHeader { flags_ver = 0, protocol = payload.Type }; //TODO: callback to print packet now? maybe another task? switch (payload.Type) { case 0x86dd: var v6outHeader = IPv6Header.FromBytes(payload.Data, 0); Console.WriteLine($"Type: {v6outHeader.nextHeader} Payload: {v6outHeader.payloadLen} From: {v6outHeader.source} To: {v6outHeader.dest}"); break; case 0x0800: var v4outHeader = IPv4Header.FromBytes(payload.Data, 0); Console.WriteLine($"Type: {v4outHeader.protocol} Size: {v4outHeader.totalLen} From: {v4outHeader.source} To: {v4outHeader.dest}"); break; case 0x88B5: // code for private experimentation Console.WriteLine($"FCP"); break; default: Console.WriteLine($"GRE Invalid Type: 0x{payload.Type:x4} {payload.Data.Length} bytes"); break; } var packet = new List <ArraySegment <byte> > { new ArraySegment <byte>(outhead.ToBytes()), new ArraySegment <byte>(payload.Data) }; await Task.Factory.FromAsync( (callback, state) => gresock.BeginSend(packet, SocketFlags.None, callback, state) , gresock.EndSend, null); } else { //TODO: better way to wait for new packets? await Task.Delay(1); } } }
void ReceivedBytes(byte[] rcvbuf) { // convert to signals and OnRecieve() switch (rcvbuf[0] >> 4) { case 4: var v4Header = IPv4Header.FromBytes(rcvbuf, 0); if (v4Header.protocol != 47) { break; // only GRE... this should be handled by socket, but just to be sure... } if (v4Header.headLen != 5) { break; // don't currently handle any options } var GRE4Header = GREHeader.FromBytes(rcvbuf, (v4Header.headLen * 4)); if (GRE4Header.flags_ver != 0) { break; // don't support any GRE flags, version is always 0 } // convert inner to json for clusterio and submit... for now we only have v6 inner switch (GRE4Header.protocol) { case 0x86dd: var v6inHeader = IPv6Header.FromBytes(rcvbuf, ((v4Header.headLen + 1) * 4)); Console.WriteLine($"Type: {v6inHeader.nextHeader} Payload: {v6inHeader.payloadLen} From: {v6inHeader.source} To: {v6inHeader.dest}"); if (v6inHeader.payloadLen + 40 <= ((Feathernet_0_16.Count - 2) * 4)) { if (v6inHeader.nextHeader == 44) { Console.WriteLine("Fragmented packet dropped"); } else { var circpacket = packet_to_circuit(rcvbuf, ((v4Header.headLen + 1) * 4), v6inHeader.totalLen).Unpack(); circpacket.origin = this; OnReceive?.Invoke(circpacket); } } else { Console.WriteLine("Too large"); } break; default: break; } break; case 6: var v6Header = IPv6Header.FromBytes(rcvbuf, 0); var GRE6Header = GREHeader.FromBytes(rcvbuf, 40); break; default: break; } }