decode.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. package pcap
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "net"
  6. "reflect"
  7. "strings"
  8. )
  9. const (
  10. TYPE_IP = 0x0800
  11. TYPE_ARP = 0x0806
  12. TYPE_IP6 = 0x86DD
  13. TYPE_VLAN = 0x8100
  14. IP_ICMP = 1
  15. IP_INIP = 4
  16. IP_TCP = 6
  17. IP_UDP = 17
  18. )
  19. const (
  20. ERRBUF_SIZE = 256
  21. // According to pcap-linktype(7).
  22. LINKTYPE_NULL = 0
  23. LINKTYPE_ETHERNET = 1
  24. LINKTYPE_TOKEN_RING = 6
  25. LINKTYPE_ARCNET = 7
  26. LINKTYPE_SLIP = 8
  27. LINKTYPE_PPP = 9
  28. LINKTYPE_FDDI = 10
  29. LINKTYPE_ATM_RFC1483 = 100
  30. LINKTYPE_RAW = 101
  31. LINKTYPE_PPP_HDLC = 50
  32. LINKTYPE_PPP_ETHER = 51
  33. LINKTYPE_C_HDLC = 104
  34. LINKTYPE_IEEE802_11 = 105
  35. LINKTYPE_FRELAY = 107
  36. LINKTYPE_LOOP = 108
  37. LINKTYPE_LINUX_SLL = 113
  38. LINKTYPE_LTALK = 104
  39. LINKTYPE_PFLOG = 117
  40. LINKTYPE_PRISM_HEADER = 119
  41. LINKTYPE_IP_OVER_FC = 122
  42. LINKTYPE_SUNATM = 123
  43. LINKTYPE_IEEE802_11_RADIO = 127
  44. LINKTYPE_ARCNET_LINUX = 129
  45. LINKTYPE_LINUX_IRDA = 144
  46. LINKTYPE_LINUX_LAPD = 177
  47. )
  48. type addrHdr interface {
  49. SrcAddr() string
  50. DestAddr() string
  51. Len() int
  52. }
  53. type addrStringer interface {
  54. String(addr addrHdr) string
  55. }
  56. func decodemac(pkt []byte) uint64 {
  57. mac := uint64(0)
  58. for i := uint(0); i < 6; i++ {
  59. mac = (mac << 8) + uint64(pkt[i])
  60. }
  61. return mac
  62. }
  63. // Decode decodes the headers of a Packet.
  64. func (p *Packet) Decode() {
  65. if len(p.Data) <= 14 {
  66. return
  67. }
  68. p.Type = int(binary.BigEndian.Uint16(p.Data[12:14]))
  69. p.DestMac = decodemac(p.Data[0:6])
  70. p.SrcMac = decodemac(p.Data[6:12])
  71. if len(p.Data) >= 15 {
  72. p.Payload = p.Data[14:]
  73. }
  74. switch p.Type {
  75. case TYPE_IP:
  76. p.decodeIp()
  77. case TYPE_IP6:
  78. p.decodeIp6()
  79. case TYPE_ARP:
  80. p.decodeArp()
  81. case TYPE_VLAN:
  82. p.decodeVlan()
  83. }
  84. }
  85. func (p *Packet) headerString(headers []interface{}) string {
  86. // If there's just one header, return that.
  87. if len(headers) == 1 {
  88. if hdr, ok := headers[0].(fmt.Stringer); ok {
  89. return hdr.String()
  90. }
  91. }
  92. // If there are two headers (IPv4/IPv6 -> TCP/UDP/IP..)
  93. if len(headers) == 2 {
  94. // Commonly the first header is an address.
  95. if addr, ok := p.Headers[0].(addrHdr); ok {
  96. if hdr, ok := p.Headers[1].(addrStringer); ok {
  97. return fmt.Sprintf("%s %s", p.Time, hdr.String(addr))
  98. }
  99. }
  100. }
  101. // For IP in IP, we do a recursive call.
  102. if len(headers) >= 2 {
  103. if addr, ok := headers[0].(addrHdr); ok {
  104. if _, ok := headers[1].(addrHdr); ok {
  105. return fmt.Sprintf("%s > %s IP in IP: ",
  106. addr.SrcAddr(), addr.DestAddr(), p.headerString(headers[1:]))
  107. }
  108. }
  109. }
  110. var typeNames []string
  111. for _, hdr := range headers {
  112. typeNames = append(typeNames, reflect.TypeOf(hdr).String())
  113. }
  114. return fmt.Sprintf("unknown [%s]", strings.Join(typeNames, ","))
  115. }
  116. // String prints a one-line representation of the packet header.
  117. // The output is suitable for use in a tcpdump program.
  118. func (p *Packet) String() string {
  119. // If there are no headers, print "unsupported protocol".
  120. if len(p.Headers) == 0 {
  121. return fmt.Sprintf("%s unsupported protocol %d", p.Time, int(p.Type))
  122. }
  123. return fmt.Sprintf("%s %s", p.Time, p.headerString(p.Headers))
  124. }
  125. // Arphdr is a ARP packet header.
  126. type Arphdr struct {
  127. Addrtype uint16
  128. Protocol uint16
  129. HwAddressSize uint8
  130. ProtAddressSize uint8
  131. Operation uint16
  132. SourceHwAddress []byte
  133. SourceProtAddress []byte
  134. DestHwAddress []byte
  135. DestProtAddress []byte
  136. }
  137. func (arp *Arphdr) String() (s string) {
  138. switch arp.Operation {
  139. case 1:
  140. s = "ARP request"
  141. case 2:
  142. s = "ARP Reply"
  143. }
  144. if arp.Addrtype == LINKTYPE_ETHERNET && arp.Protocol == TYPE_IP {
  145. s = fmt.Sprintf("%012x (%s) > %012x (%s)",
  146. decodemac(arp.SourceHwAddress), arp.SourceProtAddress,
  147. decodemac(arp.DestHwAddress), arp.DestProtAddress)
  148. } else {
  149. s = fmt.Sprintf("addrtype = %d protocol = %d", arp.Addrtype, arp.Protocol)
  150. }
  151. return
  152. }
  153. func (p *Packet) decodeArp() {
  154. if len(p.Payload) < 8 {
  155. return
  156. }
  157. pkt := p.Payload
  158. arp := new(Arphdr)
  159. arp.Addrtype = binary.BigEndian.Uint16(pkt[0:2])
  160. arp.Protocol = binary.BigEndian.Uint16(pkt[2:4])
  161. arp.HwAddressSize = pkt[4]
  162. arp.ProtAddressSize = pkt[5]
  163. arp.Operation = binary.BigEndian.Uint16(pkt[6:8])
  164. if len(pkt) < int(8+2*arp.HwAddressSize+2*arp.ProtAddressSize) {
  165. return
  166. }
  167. arp.SourceHwAddress = pkt[8 : 8+arp.HwAddressSize]
  168. arp.SourceProtAddress = pkt[8+arp.HwAddressSize : 8+arp.HwAddressSize+arp.ProtAddressSize]
  169. arp.DestHwAddress = pkt[8+arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+arp.ProtAddressSize]
  170. arp.DestProtAddress = pkt[8+2*arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+2*arp.ProtAddressSize]
  171. p.Headers = append(p.Headers, arp)
  172. if len(pkt) >= int(8+2*arp.HwAddressSize+2*arp.ProtAddressSize) {
  173. p.Payload = p.Payload[8+2*arp.HwAddressSize+2*arp.ProtAddressSize:]
  174. }
  175. }
  176. // IPadr is the header of an IP packet.
  177. type Iphdr struct {
  178. Version uint8
  179. Ihl uint8
  180. Tos uint8
  181. Length uint16
  182. Id uint16
  183. Flags uint8
  184. FragOffset uint16
  185. Ttl uint8
  186. Protocol uint8
  187. Checksum uint16
  188. SrcIp []byte
  189. DestIp []byte
  190. }
  191. func (p *Packet) decodeIp() {
  192. if len(p.Payload) < 20 {
  193. return
  194. }
  195. pkt := p.Payload
  196. ip := new(Iphdr)
  197. ip.Version = uint8(pkt[0]) >> 4
  198. ip.Ihl = uint8(pkt[0]) & 0x0F
  199. ip.Tos = pkt[1]
  200. ip.Length = binary.BigEndian.Uint16(pkt[2:4])
  201. ip.Id = binary.BigEndian.Uint16(pkt[4:6])
  202. flagsfrags := binary.BigEndian.Uint16(pkt[6:8])
  203. ip.Flags = uint8(flagsfrags >> 13)
  204. ip.FragOffset = flagsfrags & 0x1FFF
  205. ip.Ttl = pkt[8]
  206. ip.Protocol = pkt[9]
  207. ip.Checksum = binary.BigEndian.Uint16(pkt[10:12])
  208. ip.SrcIp = pkt[12:16]
  209. ip.DestIp = pkt[16:20]
  210. pEnd := int(ip.Length)
  211. if pEnd > len(pkt) {
  212. pEnd = len(pkt)
  213. }
  214. if len(pkt) >= pEnd && int(ip.Ihl*4) < pEnd {
  215. p.Payload = pkt[ip.Ihl*4 : pEnd]
  216. } else {
  217. p.Payload = []byte{}
  218. }
  219. p.Headers = append(p.Headers, ip)
  220. p.IP = ip
  221. switch ip.Protocol {
  222. case IP_TCP:
  223. p.decodeTcp()
  224. case IP_UDP:
  225. p.decodeUdp()
  226. case IP_ICMP:
  227. p.decodeIcmp()
  228. case IP_INIP:
  229. p.decodeIp()
  230. }
  231. }
  232. func (ip *Iphdr) SrcAddr() string { return net.IP(ip.SrcIp).String() }
  233. func (ip *Iphdr) DestAddr() string { return net.IP(ip.DestIp).String() }
  234. func (ip *Iphdr) Len() int { return int(ip.Length) }
  235. type Vlanhdr struct {
  236. Priority byte
  237. DropEligible bool
  238. VlanIdentifier int
  239. Type int // Not actually part of the vlan header, but the type of the actual packet
  240. }
  241. func (v *Vlanhdr) String() {
  242. fmt.Sprintf("VLAN Priority:%d Drop:%v Tag:%d", v.Priority, v.DropEligible, v.VlanIdentifier)
  243. }
  244. func (p *Packet) decodeVlan() {
  245. pkt := p.Payload
  246. vlan := new(Vlanhdr)
  247. if len(pkt) < 4 {
  248. return
  249. }
  250. vlan.Priority = (pkt[2] & 0xE0) >> 13
  251. vlan.DropEligible = pkt[2]&0x10 != 0
  252. vlan.VlanIdentifier = int(binary.BigEndian.Uint16(pkt[:2])) & 0x0FFF
  253. vlan.Type = int(binary.BigEndian.Uint16(p.Payload[2:4]))
  254. p.Headers = append(p.Headers, vlan)
  255. if len(pkt) >= 5 {
  256. p.Payload = p.Payload[4:]
  257. }
  258. switch vlan.Type {
  259. case TYPE_IP:
  260. p.decodeIp()
  261. case TYPE_IP6:
  262. p.decodeIp6()
  263. case TYPE_ARP:
  264. p.decodeArp()
  265. }
  266. }
  267. type Tcphdr struct {
  268. SrcPort uint16
  269. DestPort uint16
  270. Seq uint32
  271. Ack uint32
  272. DataOffset uint8
  273. Flags uint16
  274. Window uint16
  275. Checksum uint16
  276. Urgent uint16
  277. Data []byte
  278. }
  279. const (
  280. TCP_FIN = 1 << iota
  281. TCP_SYN
  282. TCP_RST
  283. TCP_PSH
  284. TCP_ACK
  285. TCP_URG
  286. TCP_ECE
  287. TCP_CWR
  288. TCP_NS
  289. )
  290. func (p *Packet) decodeTcp() {
  291. if len(p.Payload) < 20 {
  292. return
  293. }
  294. pkt := p.Payload
  295. tcp := new(Tcphdr)
  296. tcp.SrcPort = binary.BigEndian.Uint16(pkt[0:2])
  297. tcp.DestPort = binary.BigEndian.Uint16(pkt[2:4])
  298. tcp.Seq = binary.BigEndian.Uint32(pkt[4:8])
  299. tcp.Ack = binary.BigEndian.Uint32(pkt[8:12])
  300. tcp.DataOffset = (pkt[12] & 0xF0) >> 4
  301. tcp.Flags = binary.BigEndian.Uint16(pkt[12:14]) & 0x1FF
  302. tcp.Window = binary.BigEndian.Uint16(pkt[14:16])
  303. tcp.Checksum = binary.BigEndian.Uint16(pkt[16:18])
  304. tcp.Urgent = binary.BigEndian.Uint16(pkt[18:20])
  305. if len(pkt) >= int(tcp.DataOffset*4) {
  306. p.Payload = pkt[tcp.DataOffset*4:]
  307. }
  308. p.Headers = append(p.Headers, tcp)
  309. p.TCP = tcp
  310. }
  311. func (tcp *Tcphdr) String(hdr addrHdr) string {
  312. return fmt.Sprintf("TCP %s:%d > %s:%d %s SEQ=%d ACK=%d LEN=%d",
  313. hdr.SrcAddr(), int(tcp.SrcPort), hdr.DestAddr(), int(tcp.DestPort),
  314. tcp.FlagsString(), int64(tcp.Seq), int64(tcp.Ack), hdr.Len())
  315. }
  316. func (tcp *Tcphdr) FlagsString() string {
  317. var sflags []string
  318. if 0 != (tcp.Flags & TCP_SYN) {
  319. sflags = append(sflags, "syn")
  320. }
  321. if 0 != (tcp.Flags & TCP_FIN) {
  322. sflags = append(sflags, "fin")
  323. }
  324. if 0 != (tcp.Flags & TCP_ACK) {
  325. sflags = append(sflags, "ack")
  326. }
  327. if 0 != (tcp.Flags & TCP_PSH) {
  328. sflags = append(sflags, "psh")
  329. }
  330. if 0 != (tcp.Flags & TCP_RST) {
  331. sflags = append(sflags, "rst")
  332. }
  333. if 0 != (tcp.Flags & TCP_URG) {
  334. sflags = append(sflags, "urg")
  335. }
  336. if 0 != (tcp.Flags & TCP_NS) {
  337. sflags = append(sflags, "ns")
  338. }
  339. if 0 != (tcp.Flags & TCP_CWR) {
  340. sflags = append(sflags, "cwr")
  341. }
  342. if 0 != (tcp.Flags & TCP_ECE) {
  343. sflags = append(sflags, "ece")
  344. }
  345. return fmt.Sprintf("[%s]", strings.Join(sflags, " "))
  346. }
  347. type Udphdr struct {
  348. SrcPort uint16
  349. DestPort uint16
  350. Length uint16
  351. Checksum uint16
  352. }
  353. func (p *Packet) decodeUdp() {
  354. if len(p.Payload) < 8 {
  355. return
  356. }
  357. pkt := p.Payload
  358. udp := new(Udphdr)
  359. udp.SrcPort = binary.BigEndian.Uint16(pkt[0:2])
  360. udp.DestPort = binary.BigEndian.Uint16(pkt[2:4])
  361. udp.Length = binary.BigEndian.Uint16(pkt[4:6])
  362. udp.Checksum = binary.BigEndian.Uint16(pkt[6:8])
  363. p.Headers = append(p.Headers, udp)
  364. p.UDP = udp
  365. if len(p.Payload) >= 8 {
  366. p.Payload = pkt[8:]
  367. }
  368. }
  369. func (udp *Udphdr) String(hdr addrHdr) string {
  370. return fmt.Sprintf("UDP %s:%d > %s:%d LEN=%d CHKSUM=%d",
  371. hdr.SrcAddr(), int(udp.SrcPort), hdr.DestAddr(), int(udp.DestPort),
  372. int(udp.Length), int(udp.Checksum))
  373. }
  374. type Icmphdr struct {
  375. Type uint8
  376. Code uint8
  377. Checksum uint16
  378. Id uint16
  379. Seq uint16
  380. Data []byte
  381. }
  382. func (p *Packet) decodeIcmp() *Icmphdr {
  383. if len(p.Payload) < 8 {
  384. return nil
  385. }
  386. pkt := p.Payload
  387. icmp := new(Icmphdr)
  388. icmp.Type = pkt[0]
  389. icmp.Code = pkt[1]
  390. icmp.Checksum = binary.BigEndian.Uint16(pkt[2:4])
  391. icmp.Id = binary.BigEndian.Uint16(pkt[4:6])
  392. icmp.Seq = binary.BigEndian.Uint16(pkt[6:8])
  393. p.Payload = pkt[8:]
  394. p.Headers = append(p.Headers, icmp)
  395. return icmp
  396. }
  397. func (icmp *Icmphdr) String(hdr addrHdr) string {
  398. return fmt.Sprintf("ICMP %s > %s Type = %d Code = %d ",
  399. hdr.SrcAddr(), hdr.DestAddr(), icmp.Type, icmp.Code)
  400. }
  401. func (icmp *Icmphdr) TypeString() (result string) {
  402. switch icmp.Type {
  403. case 0:
  404. result = fmt.Sprintf("Echo reply seq=%d", icmp.Seq)
  405. case 3:
  406. switch icmp.Code {
  407. case 0:
  408. result = "Network unreachable"
  409. case 1:
  410. result = "Host unreachable"
  411. case 2:
  412. result = "Protocol unreachable"
  413. case 3:
  414. result = "Port unreachable"
  415. default:
  416. result = "Destination unreachable"
  417. }
  418. case 8:
  419. result = fmt.Sprintf("Echo request seq=%d", icmp.Seq)
  420. case 30:
  421. result = "Traceroute"
  422. }
  423. return
  424. }
  425. type Ip6hdr struct {
  426. // http://www.networksorcery.com/enp/protocol/ipv6.htm
  427. Version uint8 // 4 bits
  428. TrafficClass uint8 // 8 bits
  429. FlowLabel uint32 // 20 bits
  430. Length uint16 // 16 bits
  431. NextHeader uint8 // 8 bits, same as Protocol in Iphdr
  432. HopLimit uint8 // 8 bits
  433. SrcIp []byte // 16 bytes
  434. DestIp []byte // 16 bytes
  435. }
  436. func (p *Packet) decodeIp6() {
  437. if len(p.Payload) < 40 {
  438. return
  439. }
  440. pkt := p.Payload
  441. ip6 := new(Ip6hdr)
  442. ip6.Version = uint8(pkt[0]) >> 4
  443. ip6.TrafficClass = uint8((binary.BigEndian.Uint16(pkt[0:2]) >> 4) & 0x00FF)
  444. ip6.FlowLabel = binary.BigEndian.Uint32(pkt[0:4]) & 0x000FFFFF
  445. ip6.Length = binary.BigEndian.Uint16(pkt[4:6])
  446. ip6.NextHeader = pkt[6]
  447. ip6.HopLimit = pkt[7]
  448. ip6.SrcIp = pkt[8:24]
  449. ip6.DestIp = pkt[24:40]
  450. if len(p.Payload) >= 40 {
  451. p.Payload = pkt[40:]
  452. }
  453. p.Headers = append(p.Headers, ip6)
  454. switch ip6.NextHeader {
  455. case IP_TCP:
  456. p.decodeTcp()
  457. case IP_UDP:
  458. p.decodeUdp()
  459. case IP_ICMP:
  460. p.decodeIcmp()
  461. case IP_INIP:
  462. p.decodeIp()
  463. }
  464. }
  465. func (ip6 *Ip6hdr) SrcAddr() string { return net.IP(ip6.SrcIp).String() }
  466. func (ip6 *Ip6hdr) DestAddr() string { return net.IP(ip6.DestIp).String() }
  467. func (ip6 *Ip6hdr) Len() int { return int(ip6.Length) }