readFromDevice parses packets from a tun device and delivers them to the TCP and UDP stacks
(ctx context.Context, tun *water.Interface, tcpstack *tcpStack, udpstack *udpStack)
| 87 | |
| 88 | // readFromDevice parses packets from a tun device and delivers them to the TCP and UDP stacks |
| 89 | func readFromDevice(ctx context.Context, tun *water.Interface, tcpstack *tcpStack, udpstack *udpStack) error { |
| 90 | // start reading raw bytes from the tunnel device and sending them to the appropriate stack |
| 91 | buf := make([]byte, 1500) |
| 92 | for { |
| 93 | // read a packet (TODO: implement non-blocking read on the file descriptor, check for context cancellation) |
| 94 | n, err := tun.Read(buf) |
| 95 | if err != nil { |
| 96 | errorf("error reading a packet from tun: %v, ignoring", err) |
| 97 | continue |
| 98 | } |
| 99 | |
| 100 | packet := gopacket.NewPacket(buf[:n], layers.LayerTypeIPv4, gopacket.Default) |
| 101 | ipv4, ok := packet.Layer(layers.LayerTypeIPv4).(*layers.IPv4) |
| 102 | if !ok { |
| 103 | continue |
| 104 | } |
| 105 | |
| 106 | tcp, isTCP := packet.Layer(layers.LayerTypeTCP).(*layers.TCP) |
| 107 | udp, isUDP := packet.Layer(layers.LayerTypeUDP).(*layers.UDP) |
| 108 | if !isTCP && !isUDP { |
| 109 | continue |
| 110 | } |
| 111 | |
| 112 | if dumpPacketsFromSubprocess { |
| 113 | verbose(strings.Repeat("\n", 3)) |
| 114 | verbose(strings.Repeat("=", 80)) |
| 115 | verbose("From subprocess:") |
| 116 | verbose(packet.Dump()) |
| 117 | } |
| 118 | |
| 119 | if isTCP { |
| 120 | verbosef("received from subprocess: %v", summarizeTCP(ipv4, tcp, tcp.Payload)) |
| 121 | tcpstack.handlePacket(ipv4, tcp, tcp.Payload) |
| 122 | } |
| 123 | if isUDP { |
| 124 | verbosef("received from subprocess: %v", summarizeUDP(ipv4, udp, udp.Payload)) |
| 125 | udpstack.handlePacket(ipv4, udp, udp.Payload) |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | // layernames makes a one-line list of layers in a packet |
| 131 | func layernames(packet gopacket.Packet) []string { |
no test coverage detected