Skip to content

Instantly share code, notes, and snippets.

@mratsim
Created May 12, 2019 15:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mratsim/dcc8aa5772357a916e0457cf3be2471d to your computer and use it in GitHub Desktop.
Save mratsim/dcc8aa5772357a916e0457cf3be2471d to your computer and use it in GitHub Desktop.
import posix
import strutils
when defined(macosx):
const
libName = "libpcap.dylib"
defaultIfName* = "en0"
else:
# where is u_int type defined for pcap.h??
const
libName = "libpcap.so"
defaultIfName* = "eth0"
const
PCAP_ERRBUF_SIZE* = 256
PCAP_NETMASK_UNKNOWN* = 0xffffffff.uint32
type
pcap_t* {.importc: "pcap_t", header: "<pcap/pcap.h>".} = object
pcap_pkthdr* {.importc: "struct pcap_pkthdr", header: "<pcap/pcap.h>",
final, pure.} = object
ts*{.importc.}: Timeval
caplen*{.importc.}: uint32
len*{.importc.}: uint32
pcap_stat* {.importc: "struct pcap_stat", header: "<pcap/pcap.h>", final, pure.} = object
when defined(macosx):
ps_recv*{.importc.}: uint32
ps_drop*{.importc.}: uint32
ps_ifdrop*{.importc.}: uint32
else:
ps_capt*{.importc.}: uint32
ps_sent*{.importc.}: uint32
ps_netdrop*{.importc.}: uint32
bpf_insn* {.importc: "struct bpf_insn", header: "<pcap/bpf.h>", final, pure.} = object
code*{.importc.}: uint16
jt*{.importc.}: cstring
jf*{.importc.}: cstring
k*{.importc.}: uint32
bpf_program* {.importc: "struct bpf_program", header: "<pcap/bpf.h>", final, pure.} = object
bf_len*{.importc.}: uint32
bf_insns*{.importc.}: bpf_insn
link_layers* = enum
LINKTYPE_NULL = 0
LINKTYPE_ETHERNET
LINKTYPE_AX25
LINKTYPE_IEEE802_5
LINKTYPE_ARCNET_BSD
LINKTYPE_SLIP
LINKTYPE_PPP
LINKTYPE_FDDI
LINKTYPE_PPP_HDLC
LINKTYPE_PPP_ETHER
LINKTYPE_ATM_RFC1483
LINKTYPE_RAW
LINKTYPE_C_HDLC
LINKTYPE_IEEE802_11
LINKTYPE_FRELAY
LINKTYPE_LOOP
LINKTYPE_LINUX_SLL
LINKTYPE_LTALK
LINKTYPE_PFLOG
LINKTYPE_IEEE802_11_PRISM
LINKTYPE_IP_OVER_FC
LINKTYPE_SUNATM
LINKTYPE_IEEE802_11_RADIOTAP
LINKTYPE_ARCNET_LINUX
LINKTYPE_APPLE_IP_OVER_IEEE1394
LINKTYPE_MTP2_WITH_PHDR
LINKTYPE_MTP2
LINKTYPE_MTP3
LINKTYPE_SCCP
LINKTYPE_DOCSIS
LINKTYPE_LINUX_IRDA = 144
LINKTYPE_IEEE802_11_AVS = 163
LINKTYPE_BACNET_MS_TP
LINKTYPE_PPP_PPPD
LINKTYPE_GPRS_LLC
LINKTYPE_GPF_T
LINKTYPE_GPF_F
LINKTYPE_LINUX_LAPD
LINKTYPE_MFR
LINKTYPE_BLUETOOTH_HCI_H4
LINKTYPE_USB_LINUX
LINKTYPE_PPI
LINKTYPE_IEEE802_15_4_WITHFCS
LINKTYPE_SITA
LINKTYPE_ERF
LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR
LINKTYPE_AX25_KISS
LINKTYPE_LAPD
LINKTYPE_PPP_WITH_DIR
LINKTYPE_C_HDLC_WITH_DIR
LINKTYPE_FRELAY_WITH_DIR
LINKTYPE_LAPB_WITH_DIR
LINKTYPE_IPMB_LINUX
LINKTYPE_IEEE802_15_4_NONASK_PHY
LINKTYPE_USB_LINUX_MMAPPED
LINKTYPE_FC_2
LINKTYPE_FC_2_WITH_FRAME_DELIMS
LINKTYPE_IPNET
LINKTYPE_CAN_SOCKETCAN
LINKTYPE_IPV4
LINKTYPE_IPV6
LINKTYPE_IEEE802_15_4_NOFCS
LINKTYPE_DBUS
LINKTYPE_DVB_CI
LINKTYPE_MUX27010
LINKTYPE_STANAG_5066_D_PDU
LINKTYPE_NFLOG
LINKTYPE_NETANALYZER
LINKTYPE_NETANALYZER_TRANSPARENT
LINKTYPE_IPOIB
LINKTYPE_MPEG_2_TS
LINKTYPE_NG40
LINKTYPE_NFC_LLCP
LINKTYPE_INFINIBAND
LINKTYPE_SCTP
LINKTYPE_USBPCAP
LINKTYPE_RTAC_SERIAL
LINKTYPE_BLUETOOTH_LE_LL
LINKTYPE_NETLINK
LINKTYPE_BLUETOOTH_LINUX_MONITOR
LINKTYPE_BLUETOOTH_BREDR_BB
LINKTYPE_BLUETOOTH_LE_LL_WITH_PHDR
LINKTYPE_PROFIBUS_DL
LINKTYPE_PKTAP
LINKTYPE_EPON
LINKTYPE_IPMI_HPM_2
LINKTYPE_ZWAVE_R1_R2
LINKTYPE_ZWAVE_R3
LINKTYPE_WATTSTOPPER_DLM
LINKTYPE_ISO_14443
LINKTYPE_RDS
LINKTYPE_USB_DARWIN
LINKTYPE_SDLC
LINKTYPE_LORATAP
LINKTYPE_VSOCK
LINKTYPE_NORDIC_BLE
LINKTYPE_DOCSIS31_XRA31
LINKTYPE_ETHERNET_MPACKET
LINKTYPE_DISPLAYPORT_AUX
LINKTYPE_LINUX_SLL2
LINKTYPE_OPENVIZSLA
LINKTYPE_EBHSCR
LINKTYPE_VPP_DISPATCH
LINKTYPE_DSA_TAG_BRCM
LINKTYPE_DSA_TAG_BRCM_PREPEND
LINKTYPE_IEEE802_15_4_TAP
LINKTYPE_DSA_TAG_DSA
LINKTYPE_DSA_TAG_EDSA
proc pcap_close*(pcap: ptr pcap_t)
{.cdecl, dynlib: libName, importc.}
proc pcap_next*(pcap: ptr pcap_t, pcappkthdr: ptr pcap_pkthdr): cstring
{.cdecl, dynlib: libName, importc.}
proc pcap_next_ex*(pcap: ptr pcap_t, pcappktthdr: ptr ptr pcap_pkthdr, c: ptr cuchar): cint
{.cdecl, dynlib: libName, importc.}
proc pcap_stats*(pcap: ptr pcap_t, pstats: ptr pcap_stat): cint
{.cdecl, dynlib: libName, importc.}
proc pcap_setfilter*(pcap: ptr pcap_t, bpfprogram: ptr bpf_program): cint
{.cdecl, dynlib: libName, importc.}
proc pcap_compile*(pcap: ptr pcap_t, fp: ptr bpf_program, str: cstring, optimize: cint, netmask: uint): cint
{.cdecl, dynlib: libName, importc.}
proc pcap_getnonblock*(pcap: ptr pcap_t, str: cstring): cint
{.cdecl, dynlib: libName, importc.}
proc pcap_sendpacket*(pcap: ptr pcap_t, buf: cstring, size: cint): cint
{.cdecl, dynlib: libName, importc.}
proc pcap_geterr*(pcap: ptr pcap_T): cstring
{.cdecl, dynlib: libName, importc.}
proc pcap_datalink*(pcap: ptr pcap_T): cint
{.cdecl, dynlib: libName, importc.}
proc pcap_set_snaplen*(pcap: ptr pcap_T, snaplen: cint): cint
{.cdecl, dynlib: libName, importc.}
proc pcap_snapshot*(pcap: ptr pcap_T): cint
{.cdecl, dynlib: libName, importc.}
proc pcap_set_promisc*(pcap: ptr pcap_T, promisc: cint): cint
{.cdecl, dynlib: libName, importc.}
proc pcap_set_rfmon*(pcap: ptr pcap_T, rfmon: cint): cint
{.cdecl, dynlib: libName, importc.}
proc pcap_can_set_rfmon*(pcap: ptr pcap_T): cint
{.cdecl, dynlib: libName, importc.}
proc pcap_set_timeout*(pcap: ptr pcap_T, to_ms: cint): cint
{.cdecl, dynlib: libName, importc.}
proc pcap_set_buffer_size*(pcap: ptr pcap_T, buffer_size: cint): cint
{.cdecl, dynlib: libName, importc.}
proc pcap_create*(source: cstring, errbuf: pointer): ptr pcap_t
{.cdecl, dynlib: libName, importc.}
proc pcap_activate*(pcap: ptr pcap_T): cint
{.cdecl, dynlib: libName, importc.}
proc checkError*(pcap: ptr pcap_T, ret: cint) =
if ret < 0:
raise newException(OSError, $pcap_geterr(pcap))
when isMainModule:
var err = newString(PCAP_ERRBUF_SIZE)
var filter: ptr bpf_program
var p = pcap_create(defaultIfName, err[0].addr)
# Produces a malloc error
# malloc: *** error for object 0x408: pointer being freed was not allocated
p.checkError p.pcap_compile(filter, "tcp port 2050", 1, PCAP_NETMASK_UNKNOWN)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment