parse extracts IPv4 and TCP fields from raw. Returns a pkt whose slices alias raw — do not modify the returned pkt.raw unless you intend to mutate the original packet.
(raw []byte)
| 39 | // alias raw — do not modify the returned pkt.raw unless you intend to mutate |
| 40 | // the original packet. |
| 41 | func parse(raw []byte) (pkt, error) { |
| 42 | var p pkt |
| 43 | if len(raw) < 20 { |
| 44 | return p, errNotIPv4TCP |
| 45 | } |
| 46 | if raw[0]>>4 != 4 { |
| 47 | return p, errNotIPv4TCP |
| 48 | } |
| 49 | p.ipHdrLen = int(raw[0]&0x0f) * 4 |
| 50 | if p.ipHdrLen < 20 || len(raw) < p.ipHdrLen+20 { |
| 51 | return p, errNotIPv4TCP |
| 52 | } |
| 53 | if raw[9] != 6 { // IPPROTO_TCP |
| 54 | return p, errNotIPv4TCP |
| 55 | } |
| 56 | p.totalLen = int(binary.BigEndian.Uint16(raw[2:4])) |
| 57 | p.ident = binary.BigEndian.Uint16(raw[4:6]) |
| 58 | copy(p.srcIP[:], raw[12:16]) |
| 59 | copy(p.dstIP[:], raw[16:20]) |
| 60 | |
| 61 | p.tcpOff = p.ipHdrLen |
| 62 | p.tcpHdrLen = int(raw[p.tcpOff+12]>>4) * 4 |
| 63 | if p.tcpHdrLen < 20 || len(raw) < p.tcpOff+p.tcpHdrLen { |
| 64 | return p, errNotIPv4TCP |
| 65 | } |
| 66 | p.srcPort = binary.BigEndian.Uint16(raw[p.tcpOff : p.tcpOff+2]) |
| 67 | p.dstPort = binary.BigEndian.Uint16(raw[p.tcpOff+2 : p.tcpOff+4]) |
| 68 | p.seqNum = binary.BigEndian.Uint32(raw[p.tcpOff+4 : p.tcpOff+8]) |
| 69 | p.ackNum = binary.BigEndian.Uint32(raw[p.tcpOff+8 : p.tcpOff+12]) |
| 70 | p.flags = raw[p.tcpOff+13] |
| 71 | |
| 72 | // Payload runs from end-of-headers to min(totalLen, len(raw)). |
| 73 | // Clamp to len(raw) because some kernels deliver packets where |
| 74 | // totalLen < buffer size (trailing padding) or > (truncated capture). |
| 75 | payloadStart := p.tcpOff + p.tcpHdrLen |
| 76 | ipEnd := p.totalLen |
| 77 | if ipEnd > len(raw) { |
| 78 | ipEnd = len(raw) |
| 79 | } |
| 80 | if payloadStart < ipEnd { |
| 81 | p.payload = raw[payloadStart:ipEnd] |
| 82 | } |
| 83 | return p, nil |
| 84 | } |
| 85 | |
| 86 | // TCP flag bit constants (byte 13 of TCP header). |
| 87 | const ( |
no outgoing calls