Example #1
0
// With an unsafe.Pointer to the block of C memory NewUdpHdr returns a filled in UdpHdr struct.
func NewUdpHdr(p unsafe.Pointer) (*UdpHdr, unsafe.Pointer) {
	udpHead := &UdpHdr{
		cptr: (*C.struct_udphdr)(p),
	}
	udpHead.Source = uint16(C.ntohs(C.uint16_t(udpHead.cptr.source)))
	udpHead.Dest = uint16(C.ntohs(C.uint16_t(udpHead.cptr.dest)))
	udpHead.Len = uint16(C.ntohs(C.uint16_t(udpHead.cptr.len)))
	udpHead.Check = uint16(C.ntohs(C.uint16_t(udpHead.cptr.check)))
	udpHead.payload = unsafe.Pointer(uintptr(p) + 8)
	return udpHead, udpHead.payload
}
Example #2
0
// With an unsafe.Pointer to the block of C memory NewIp6Hdr returns a filled in Ip6Hdr struct.
func NewIp6Hdr(p unsafe.Pointer) (*Ip6Hdr, unsafe.Pointer) {
	ip6Hdr := &Ip6Hdr{
		cptr: (*C.struct_ip6_hdr)(p),
		// The fixed header of an IPv6 packet consists of its first 40 octets.
		payload: unsafe.Pointer(uintptr(p) + uintptr(40)),
	}
	ip6Hdr.SrcAddr = net.IP(C.GoBytes(unsafe.Pointer(&ip6Hdr.cptr.ip6_src), 16))
	ip6Hdr.DstAddr = net.IP(C.GoBytes(unsafe.Pointer(&ip6Hdr.cptr.ip6_dst), 16))
	u := (*C.struct_ip6_hdrctl)(unsafe.Pointer(&ip6Hdr.cptr.ip6_ctlun))
	ip6Hdr.NextHeader = uint8(u.ip6_un1_nxt)
	ip6Hdr.PayloadLen = uint16(C.ntohs(u.ip6_un1_plen))
	return ip6Hdr, ip6Hdr.payload
}
Example #3
0
// With an unsafe.Pointer to the block of C memory NewIpHdr returns a filled in IpHdr struct.
func NewIpHdr(p unsafe.Pointer) (*IpHdr, unsafe.Pointer) {
	iphdr := &IpHdr{
		cptr: (*C.struct_iphdr)(p),
		// Since cgo does not provide access to bit fields in a struct
		// we take the first octet and then mask the unneeded bits.
		Ihl: *(*byte)(p) & 0x0F,
		// Since cgo does not provide access to bit fields in a struct
		// we take the first octet and then shift out the unneeded bits.
		Version: *(*byte)(p) >> 4,
	}
	iphdr.SrcAddr = net.IP(C.GoBytes(unsafe.Pointer(&iphdr.cptr.saddr), 4))
	iphdr.DstAddr = net.IP(C.GoBytes(unsafe.Pointer(&iphdr.cptr.daddr), 4))
	iphdr.Protocol = uint8(iphdr.cptr.protocol)
	iphdr.TotLen = uint16(C.ntohs(C.uint16_t(iphdr.cptr.tot_len)))
	iphdr.PayloadLen = iphdr.TotLen - uint16(iphdr.Ihl*4)
	iphdr.payload = unsafe.Pointer(uintptr(p) + uintptr(iphdr.Ihl*4))
	return iphdr, iphdr.payload
}
Example #4
0
// With an unsafe.Pointer to the block of C memory NewEthHdr returns a filled in EthHdr struct.
func NewEthHdr(p unsafe.Pointer) (*EthHdr, unsafe.Pointer) {
	ethHdr := &EthHdr{
		cptr: (*C.struct_ether_header)(p),
	}
	ethHdr.SrcAddr = net.HardwareAddr(C.GoBytes(unsafe.Pointer(&ethHdr.cptr.ether_shost), C.ETH_ALEN))
	ethHdr.DstAddr = net.HardwareAddr(C.GoBytes(unsafe.Pointer(&ethHdr.cptr.ether_dhost), C.ETH_ALEN))
	ethHdr.EtherType = uint16(C.ntohs(C.uint16_t(ethHdr.cptr.ether_type)))

	// When using the Linux "any" device we have to handle cooked headers.
	// To determine if you could be in this case you can use pcap_datalink()
	// and check for DLT_LINUX_SLL.
	//TODO(gavaletz) This is an example of a decision that could be made once
	//   outside the process of decoding packets as if one is like this they
	//   will all be like this.
	if ethHdr.EtherType == 0 {
		// The "cooked" headers have an extra two bytes.
		ethHdr.payload = unsafe.Pointer(uintptr(p) + uintptr(C.ETHER_HDR_LEN) + uintptr(2))
	} else {
		ethHdr.payload = unsafe.Pointer(uintptr(p) + uintptr(C.ETHER_HDR_LEN))
	}
	return ethHdr, ethHdr.payload
}
Example #5
0
// With an unsafe.Pointer to the block of C memory NewTcpHdr returns a filled in TcpHdr struct.
func NewTcpHdr(p unsafe.Pointer) (*TcpHdr, unsafe.Pointer) {
	tcpHead := &TcpHdr{
		cptr: (*C.struct_tcphdr)(p),
		// Since cgo does not provide access to bit fields in a struct
		// we index 12 octets in and then shift out the unneeded bits.
		Doff: *(*byte)(unsafe.Pointer(uintptr(p) + uintptr(12))) >> 4,
	}
	tcpHead.Source = uint16(C.ntohs(C.uint16_t(tcpHead.cptr.source)))
	tcpHead.Dest = uint16(C.ntohs(C.uint16_t(tcpHead.cptr.dest)))
	tcpHead.Seq = uint32(C.ntohl(C.uint32_t(tcpHead.cptr.seq)))
	tcpHead.AckSeq = uint32(C.ntohl(C.uint32_t(tcpHead.cptr.ack_seq)))
	// A this time (and there are no plans to support it) cgo does not
	// provide access to bit fields in a struct so this is what we are stuck
	// with.  We index 12 octets in and then use a bit mask.
	tcpHead.Flags = uint16(C.ntohs(C.uint16_t(
		*(*uint16)(unsafe.Pointer(uintptr(p) + uintptr(12)))))) & uint16(0x01FF)
	tcpHead.Window = uint16(C.ntohs(C.uint16_t(tcpHead.cptr.window)))
	tcpHead.Check = uint16(C.ntohs(C.uint16_t(tcpHead.cptr.check)))
	tcpHead.UrgPtr = uint16(C.ntohs(C.uint16_t(tcpHead.cptr.urg_ptr)))
	tcpHead.payload = unsafe.Pointer(uintptr(p) + uintptr(tcpHead.Doff*4))
	return tcpHead, tcpHead.payload
}
Example #6
0
// Id returns the identification of the IP flow.
func (h *IpHdr) Id() uint16 {
	return uint16(C.ntohs(C.uint16_t(h.cptr.id)))
}