public
Last active

  • Download Gist
pcap_findalldevs.lsp
Common Lisp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
#!/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
Common Lisp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
;; 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

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

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

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.