<commit_before>package pcap

/*
#cgo LDFLAGS: -lpcap
struct pcap { int dummy; };
#include <stdlib.h>
#include <pcap.h>
*/
import "C"
import (
	"unsafe"
	"os"
	"net"
	"syscall"
)

type Pcap struct {
	cptr *C.pcap_t
}

type Stat struct {
	PacketsReceived  uint32
	PacketsDropped   uint32
	PacketsIfDropped uint32
}

type Interface struct {
	Name        string
	Description string
	Addresses   []IFAddress
	// TODO: add more elements
}

type IFAddress struct {
	IP      net.IP
	Netmask net.IPMask
	// TODO: add broadcast + PtP dst ?
}

func Openlive(device string, snaplen int32, promisc bool, timeout_ms int32) (handle *Pcap, err string) {
	var buf *C.char
	buf = (*C.char)(C.calloc(ERRBUF_SIZE, 1))
	h := new(Pcap)
	var pro int32
	if promisc {
		pro = 1
	} else {
		pro = 0
	}
	h.cptr = C.pcap_open_live(C.CString(device), C.int(snaplen), C.int(pro), C.int(timeout_ms), buf)
	if nil == h.cptr {
		handle = nil
		err = C.GoString(buf)
	} else {
		handle = h
	}
	C.free(unsafe.Pointer(buf))
	return
}

func Openoffline(file string) (handle *Pcap, err string) {
	var buf *C.char
	buf = (*C.char)(C.calloc(ERRBUF_SIZE, 1))
	h := new(Pcap)
	h.cptr = C.pcap_open_offline(C.CString(file), buf)
	if nil == h.cptr {
		handle = nil
		err = C.GoString(buf)
	} else {
		handle = h
	}
	C.free(unsafe.Pointer(buf))
	return
}

func (p *Pcap) Next() (pkt *Packet) {
	rv, _ := p.NextEx()

	return rv
}

func (p *Pcap) NextEx() (pkt *Packet, result int32) {
	var pkthdr_ptr *_Ctype_struct_pcap_pkthdr
	var pkthdr _Ctype_struct_pcap_pkthdr

	var buf_ptr *_Ctypedef_u_char
	var buf unsafe.Pointer
	result = int32(C.pcap_next_ex(p.cptr, &pkthdr_ptr, &buf_ptr))

	buf = unsafe.Pointer(buf_ptr)
	pkthdr = *pkthdr_ptr

	if nil == buf {
		pkt = nil
		return
	}
	pkt = new(Packet)
	pkt.Time.Sec = int32(pkthdr.ts.tv_sec)
	pkt.Time.Usec = int32(pkthdr.ts.tv_usec)
	pkt.Caplen = uint32(pkthdr.caplen)
	pkt.Len = uint32(pkthdr.len)
	pkt.Data = make([]byte, pkthdr.caplen)

	for i := uint32(0); i < pkt.Caplen; i++ {
		pkt.Data[i] = *(*byte)(unsafe.Pointer(uintptr(buf) + uintptr(i)))
	}

	return
}

func (p *Pcap) Geterror() string {
	return C.GoString(C.pcap_geterr(p.cptr))
}

func (p *Pcap) Getstats() (stat *Stat, err string) {
	var cstats _Ctype_struct_pcap_stat
	if -1 == C.pcap_stats(p.cptr, &cstats) {
		return nil, p.Geterror()
	}

	stats := new(Stat)

	stats.PacketsReceived = uint32(cstats.ps_recv)
	stats.PacketsDropped = uint32(cstats.ps_drop)
	stats.PacketsIfDropped = uint32(cstats.ps_ifdrop)

	return stats, ""
}

func (p *Pcap) Setfilter(expr string) (err string) {
	var bpf _Ctype_struct_bpf_program

	if -1 == C.pcap_compile(p.cptr, &bpf, C.CString(expr), 1, 0) {
		return p.Geterror()
	}

	if -1 == C.pcap_setfilter(p.cptr, &bpf) {
		C.pcap_freecode(&bpf)
		return p.Geterror()
	}

	C.pcap_freecode(&bpf)
	return ""
}

func Version() string {
	return C.GoString(C.pcap_lib_version())
}

func (p *Pcap) Datalink() int {
	return int(C.pcap_datalink(p.cptr))
}

func (p *Pcap) Setdatalink(dlt int) string {
	if -1 == C.pcap_set_datalink(p.cptr, C.int(dlt)) {
		return p.Geterror()
	}
	return ""
}

func DatalinkValueToName(dlt int) string {
	name := C.pcap_datalink_val_to_name(C.int(dlt))
	if nil != name {
		return C.GoString(name)<commit_msg>free C strings.<commit_after>package pcap

/*
#cgo LDFLAGS: -lpcap
struct pcap { int dummy; };
#include <stdlib.h>
#include <pcap.h>
*/
import "C"
import (
	"unsafe"
	"os"
	"net"
	"syscall"
)

type Pcap struct {
	cptr *C.pcap_t
}

type Stat struct {
	PacketsReceived  uint32
	PacketsDropped   uint32
	PacketsIfDropped uint32
}

type Interface struct {
	Name        string
	Description string
	Addresses   []IFAddress
	// TODO: add more elements
}

type IFAddress struct {
	IP      net.IP
	Netmask net.IPMask
	// TODO: add broadcast + PtP dst ?
}

func Openlive(device string, snaplen int32, promisc bool, timeout_ms int32) (handle *Pcap, err string) {
	var buf *C.char
	buf = (*C.char)(C.calloc(ERRBUF_SIZE, 1))
	h := new(Pcap)
	var pro int32
	if promisc {
		pro = 1
	} else {
		pro = 0
	}

	dev := C.CString(device)
	defer C.free(unsafe.Pointer(dev))

	h.cptr = C.pcap_open_live(dev, C.int(snaplen), C.int(pro), C.int(timeout_ms), buf)
	if nil == h.cptr {
		handle = nil
		err = C.GoString(buf)
	} else {
		handle = h
	}
	C.free(unsafe.Pointer(buf))
	return
}

func Openoffline(file string) (handle *Pcap, err string) {
	var buf *C.char
	buf = (*C.char)(C.calloc(ERRBUF_SIZE, 1))
	h := new(Pcap)

	cf := C.CString(file)
	defer C.free(unsafe.Pointer(cf))

	h.cptr = C.pcap_open_offline(cf, buf)
	if nil == h.cptr {
		handle = nil
		err = C.GoString(buf)
	} else {
		handle = h
	}
	C.free(unsafe.Pointer(buf))
	return
}

func (p *Pcap) Next() (pkt *Packet) {
	rv, _ := p.NextEx()

	return rv
}

func (p *Pcap) NextEx() (pkt *Packet, result int32) {
	var pkthdr_ptr *_Ctype_struct_pcap_pkthdr
	var pkthdr _Ctype_struct_pcap_pkthdr

	var buf_ptr *_Ctypedef_u_char
	var buf unsafe.Pointer
	result = int32(C.pcap_next_ex(p.cptr, &pkthdr_ptr, &buf_ptr))

	buf = unsafe.Pointer(buf_ptr)
	pkthdr = *pkthdr_ptr

	if nil == buf {
		pkt = nil
		return
	}
	pkt = new(Packet)
	pkt.Time.Sec = int32(pkthdr.ts.tv_sec)
	pkt.Time.Usec = int32(pkthdr.ts.tv_usec)
	pkt.Caplen = uint32(pkthdr.caplen)
	pkt.Len = uint32(pkthdr.len)
	pkt.Data = make([]byte, pkthdr.caplen)

	for i := uint32(0); i < pkt.Caplen; i++ {
		pkt.Data[i] = *(*byte)(unsafe.Pointer(uintptr(buf) + uintptr(i)))
	}

	return
}

func (p *Pcap) Geterror() string {
	return C.GoString(C.pcap_geterr(p.cptr))
}

func (p *Pcap) Getstats() (stat *Stat, err string) {
	var cstats _Ctype_struct_pcap_stat
	if -1 == C.pcap_stats(p.cptr, &cstats) {
		return nil, p.Geterror()
	}

	stats := new(Stat)

	stats.PacketsReceived = uint32(cstats.ps_recv)
	stats.PacketsDropped = uint32(cstats.ps_drop)
	stats.PacketsIfDropped = uint32(cstats.ps_ifdrop)

	return stats, ""
}

func (p *Pcap) Setfilter(expr string) (err string) {
	var bpf _Ctype_struct_bpf_program

	cexpr := C.CString(expr)
	defer C.free(unsafe.Pointer(cexpr))

	if -1 == C.pcap_compile(p.cptr, &bpf, cexpr, 1, 0) {
		return p.Geterror()
	}

	if -1 == C.pcap_setfilter(p.cptr, &bpf) {
		C.pcap_freecode(&bpf)
		return p.Geterror()
	}

	C.pcap_freecode(&bpf)
	return ""
}

func Version() string {
	return C.GoString(C.pcap_lib_version())
}

func (p *Pcap) Datalink() int {
	return int(C.pcap_datalink(p.cptr))
}

func (p *Pcap) Setdatalink(dlt int) string {
	if -1 == C.pcap_set_datalink(p.cptr, C.int(dlt)) {
		return p.Geterror()
	}
	return ""
}

func DatalinkValueToName(dlt int) string {
	name := C.pcap_datalink_val_to_name(C.int(dlt))
	if nil != name {
		return C.GoString(name)
{'fraction_non_alphanumeric': 0.14890400604686319, 'fraction_numerical': 0.013000755857898715, 'mean_word_length': 3.843338213762811, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5717439', 'n_tokens_mistral': 3045, 'n_tokens_neox': 2937, 'n_words': 621}