//Create and bind to queue specified by queueId func NewNFQueue(queueId uint16, maxPacketsInQueue uint32, packetSize uint32) (*NFQueue, error) { var nfq = NFQueue{} var err error var ret C.int if nfq.h, err = C.nfq_open(); err != nil { return nil, fmt.Errorf("Error opening NFQueue handle: %v\n", err) } if ret, err = C.nfq_unbind_pf(nfq.h, AF_INET); err != nil || ret < 0 { return nil, fmt.Errorf("Error unbinding existing NFQ handler from AF_INET protocol family: %v\n", err) } if ret, err := C.nfq_bind_pf(nfq.h, AF_INET); err != nil || ret < 0 { return nil, fmt.Errorf("Error binding to AF_INET protocol family: %v\n", err) } nfq.packets = make(chan NFPacket) if nfq.qh, err = C.CreateQueue(nfq.h, C.u_int16_t(queueId), unsafe.Pointer(&nfq.packets)); err != nil || nfq.qh == nil { C.nfq_close(nfq.h) return nil, fmt.Errorf("Error binding to queue: %v\n", err) } if ret, err = C.nfq_set_queue_maxlen(nfq.qh, C.u_int32_t(maxPacketsInQueue)); err != nil || ret < 0 { C.nfq_destroy_queue(nfq.qh) C.nfq_close(nfq.h) return nil, fmt.Errorf("Unable to set max packets in queue: %v\n", err) } if C.nfq_set_mode(nfq.qh, C.u_int8_t(2), C.uint(packetSize)) < 0 { C.nfq_destroy_queue(nfq.qh) C.nfq_close(nfq.h) return nil, fmt.Errorf("Unable to set packets copy mode: %v\n", err) } if nfq.fd, err = C.nfq_fd(nfq.h); err != nil { C.nfq_destroy_queue(nfq.qh) C.nfq_close(nfq.h) return nil, fmt.Errorf("Unable to get queue file-descriptor. %v", err) } go nfq.run() return &nfq, nil }
func (this *nfQueue) init() { var err error if this.h, err = C.nfq_open(); err != nil || this.h == nil { panic(err) } //if this.qh, err = C.nfq_create_queue(this.h, qid, C.get_cb(), unsafe.Pointer(nfq)); err != nil || this.qh == nil { this.pktch = make(chan *Packet, 1) if C.nfq_unbind_pf(this.h, C.AF_INET) < 0 { this.Destroy() panic("nfq_unbind_pf(AF_INET) failed, are you running root?.") } if C.nfq_unbind_pf(this.h, C.AF_INET6) < 0 { this.Destroy() panic("nfq_unbind_pf(AF_INET6) failed.") } if C.nfq_bind_pf(this.h, C.AF_INET) < 0 { this.Destroy() panic("nfq_bind_pf(AF_INET) failed.") } if C.nfq_bind_pf(this.h, C.AF_INET6) < 0 { this.Destroy() panic("nfq_bind_pf(AF_INET6) failed.") } if this.qh, err = C.create_queue(this.h, C.uint16_t(this.qid), unsafe.Pointer(this)); err != nil || this.qh == nil { C.nfq_close(this.h) panic(err) } this.fd = int(C.nfq_fd(this.h)) if C.nfq_set_mode(this.qh, C.NFQNL_COPY_PACKET, 0xffff) < 0 { this.Destroy() panic("nfq_set_mode(NFQNL_COPY_PACKET) failed.") } if C.nfq_set_queue_maxlen(this.qh, 1024*8) < 0 { this.Destroy() panic("nfq_set_queue_maxlen(1024 * 8) failed.") } }
func (this *nfQueue) Destroy() { this.lk.Lock() defer this.lk.Unlock() if this.fd != 0 && this.Valid() { syscall.Close(this.fd) } if this.qh != nil { C.nfq_destroy_queue(this.qh) this.qh = nil } if this.h != nil { C.nfq_close(this.h) this.h = nil } if this.pktch != nil { close(this.pktch) } }
//Unbind and close the queue func (nfq *NFQueue) Close() { C.nfq_destroy_queue(nfq.qh) C.nfq_close(nfq.h) }