Add hex2pcap
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
package inet
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"pcap-web-tools/internal/pcap"
|
||||
)
|
||||
|
||||
const (
|
||||
etherTypeIPv4 = 0x0800
|
||||
etherTypeIPv6 = 0x86dd
|
||||
etherTypeVLAN = 0x8100
|
||||
etherTypeQinQ = 0x88a8
|
||||
)
|
||||
|
||||
// FindIP returns the offset of the IP header within a link-layer frame of the
|
||||
// given pcap link type, by parsing the link-layer header.
|
||||
func FindIP(frame []byte, linkType uint32) (int, error) {
|
||||
switch linkType {
|
||||
case pcap.LinkTypeRaw:
|
||||
return 0, nil
|
||||
|
||||
case pcap.LinkTypeEthernet:
|
||||
off := 12
|
||||
for {
|
||||
if off+2 > len(frame) {
|
||||
return 0, fmt.Errorf("Ethernet header truncated")
|
||||
}
|
||||
et := binary.BigEndian.Uint16(frame[off:])
|
||||
if et == etherTypeVLAN || et == etherTypeQinQ {
|
||||
off += 4
|
||||
continue
|
||||
}
|
||||
return etherIP(et, off+2)
|
||||
}
|
||||
|
||||
case pcap.LinkTypeLinuxSLL:
|
||||
if len(frame) < 16 {
|
||||
return 0, fmt.Errorf("Linux cooked (SLL) header truncated")
|
||||
}
|
||||
return etherIP(binary.BigEndian.Uint16(frame[14:]), 16)
|
||||
|
||||
case pcap.LinkTypeLinuxSLL2:
|
||||
if len(frame) < 20 {
|
||||
return 0, fmt.Errorf("Linux cooked v2 (SLL2) header truncated")
|
||||
}
|
||||
return etherIP(binary.BigEndian.Uint16(frame[0:]), 20)
|
||||
}
|
||||
return 0, fmt.Errorf("cannot locate the IP header for link type %s", pcap.LinkTypeName(linkType))
|
||||
}
|
||||
|
||||
func etherIP(etherType uint16, off int) (int, error) {
|
||||
if etherType != etherTypeIPv4 && etherType != etherTypeIPv6 {
|
||||
return 0, fmt.Errorf("link-layer payload is not IP (EtherType 0x%04x)", etherType)
|
||||
}
|
||||
return off, nil
|
||||
}
|
||||
Reference in New Issue
Block a user