Create a gist now

Instantly share code, notes, and snippets.

#!/usr/bin/newlisp
;; ネットワークデバイスを表示する (= `tcpdump -D`)
;; Usage: newlisp pcap_findalldevs.lsp
;; ** rootユーザ権限が必要
(load "pcapdef.lsp")
(define NULL 0)
(setf stdin 0 stdout 1 stderr 2)
(define (fprintf fp) (write fp (apply format $args)))
(define (printf ) (write stdout (apply format $args)))
(setf alldevs (pcap_if))
(setf errbuf (dup "\000" PCAP_ERRBUF_SIZE))
;; or (if (= -1 (pcap_findalldevs_ex PCAP_SRC_IF_STRING NULL alldevs errbuf)) ...)
(pcap_findalldevs (alldevs 1) errbuf)
(unless (empty? errbuf)
(fprintf stderr "Error in pcap_findalldevs: %s\n" errbuf)
(exit 1))
(setf i 0)
(setf dev (:next alldevs)) ; *alldevs->next
(while (!= dev (pcap_if))
(if (empty? (:description dev))
(printf "%d.%s\n" (++ i) (:name dev))
(printf "%d.%s (%s)\n" (++ i) (:name dev) (:description dev)))
(setf dev (:next dev)))
(when (= i 0)
(fprintf stderr "No interfaces found! Make sure WinPcap is installed.\n")
(exit 0))
(pcap_freealldevs (alldevs 1))
(exit)
;; pcapdef.lsp
(define libpcap
(case ostype
("Win32" "wpcap.dll")
(true "libpcap.so"))) ; "libpcap.so.0" (CentOS 5)
#include <pcap.h>
(define PCAP_VERSION_MAJOR 2)
(define PCAP_VERSION_MINOR 4)
(define PCAP_ERRBUF_SIZE 256)
(when (= ostype "Win32")
(import libpcap "pcap_findalldevs_ex"))
;; int pcap_findalldevs(pcap_if_t **alldevsp, char **errbuf)
(import libpcap "pcap_findalldevs")
;; char *pcap_lookupdev(char *errbuf)
(import libpcap "pcap_lookupdev")
;; void pcap_freealldevs(pcap_if_t *alldevs)
(import libpcap "pcap_freealldevs")
#include <remote-ext.h>
(define PCAP_SRC_FILE_STRING "file://")
(define PCAP_SRC_IF_STRING "rpcap://")
;; struct pcap_if {
;; struct pcap_if *next;
;; char *name;
;; char *description;
;; struct pcap_addr *address;
;; bpf_u_int32 flags;
;; };
(new Class 'pcap_if)
(if (= 256 (& (sys-info 9) 256)) ; 64-bit?
(define pcap_if:struct "Lu Lu Lu Lu Lu")
(define pcap_if:struct "lu lu lu lu lu"))
(define (pcap_if:pcap_if (x nil))
(if (integer? x)
;; (pcap_if *) ポインタからオブジェクトを作成する
(cons (context) (pack pcap_if:struct (unpack pcap_if:struct x)))
;; 初期値はすべて null
(cons (context) (pack pcap_if:struct '(0 0 0 0 0 0)))))
(define (pcap_if:_unpack (idx nil))
(let (lst (unpack pcap_if:struct (self 1)))
(if (integer? idx) (lst idx) lst)))
(define (pcap_if:next)
(let (ptr (:_unpack (self) 0))
(if (= ptr 0) (pcap_if) (pcap_if ptr))))
(define (pcap_if:name)
(let (ptr (:_unpack (self) 1)) (if (!= ptr 0) (get-string ptr) "")))
(define (pcap_if:description)
(let (ptr (:_unpack (self) 2)) (if (!= ptr 0) (get-string ptr) "")))
(define (pcap_if:address) (:_unpack (self) 3))
(define (pcap_if:flags) (:_unpack (self) 4))
(context MAIN)
;; eof
@kosh04
Owner
kosh04 commented Sep 30, 2010

newLISPのテンプレートベースなオブジェクト指向プログラミング(FOOP)を
Cライブラリの構造体に利用してみるテスト。

名前による直感的な参照ができることと、名前空間の節約になるかも。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment