packet capture
Common Lisp
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
README
constant.lisp
eth-protocol.lisp
function.lisp
package.lisp
snif.asd
snif.lisp
type.lisp
util.lisp

README

============
=== 概要 ===
・パケットスニフィングの実装
・SBCLおよびLinux環境に依存


==================
=== バージョン ===
・0.0.1


===========
=== API ===
# (snif:make-channel interface-name &key (protocol :all)) => channel
 特定にインターフェースに対するイーサネット用入出力チャネルを作成する
 - interface-name: 対象のインターフェースの名前
 - protocol: 入出力対象となるのプロトコル

# (snif:list-all-protocols) => (list (protocol description) ...)
 利用可能なプロトコル一覧を返す

# (snif:close channel) => t
 チャネルを閉じる

# (snif:promisc-mode interface-name) => (or t nil)
 指定されたインターフェースがプロミスキャスモードになっているかどうかを判断する

# (snif:set-promisc-mode interface-name enable) => t
 指定されたインターフェースのプロミスキャスモードを設定する
 - interface-name: 対象インターフェース
 - enable: tならプロミスキャスモードをオンに、nilならオフに設定する

# (snif:with-channel ((channel-var interface-name &key (protocol :all) promisc) &body body) 
 引数に従ってチャネルを作成し、本体を実行する
 本体を抜ける際には、必ずチェネルが閉じられる
 - channel-var: 作成されたチャネルが束縛される変数
 - interface-name: チャネルの入出力の対象となるインターフェースの名前
 - protocol: 入出力対象となるプロトコル
 - promisc: tならインターフェースのプロミスキャスモードをオンに、nilならオフに設定して、本体を実行する

# (snif:sniffing interface-name &key (protocol :all) promisc (columns 16))
 指定されたインターフェースに対してスニフィングを行う
 スニフィング結果(経過)は標準出力に出力される

# (snif:read-frame channel &key dont-wait) => (values octets source destination protocol)
 チャネルからイーサネットフレームを読み込む
 - dont-wait: この値がtの場合、読み込み処理はブロッキングされない
        即座に読み込み可能なデータない場合は、返り値として(values nil nil nil nil)が返される
 - octets: 読み込んだイーサネットフレーム。ヘッダを含む。(simple-array (unsigned-byte 8))型
 - source: 送信元のハードウェアアドレス。文字列形式。
 - destination: 送信先のハードウェアアドレス。文字列形式。
 - protocol: 使用されたプロトコル
 - columns: 一行に表示されるバイト数

# (snif:listen channel) => (or t nil)
 チャネルからブロッキングせずにデータが読み込み可能かどうかを判定する

# (snif:flush channel) => discarded-octets-size
 チャネルに溜まっている全てのデータを読み捨てる
 - discarded-octets-size: 読み捨てたデータのバイト数

# (snif:write-frame octets channel) => write-octets-size
 チャネルにデータを出力する
 - octets: 出力するバイト列
 - channel: 対象チャネル
 - write-octets-size: 実際に出力されたバイト数


==============
=== 使用例 ===
;;; スニフィング
(snif:suffing "eth0" :promisc t)
;  送信元HWADDR         送信先HWADDR      プロトコル
;# 00:24:d7:71:22:7c -> 00:1d:93:00:4e:8f [IP]
;[000] 00 1d 93 00 4e 8f 00 24 d7 71 22 7c 08 00 45 00 ....N..$.q"|..E.
;[010] 00 34 92 84 40 00 40 06 5b 15 c0 a8 64 65 ad c7 .4..@.@.[...de..
;[020] 7a 55 a3 d3 00 50 5d cf 5e 47 7f 8d 4a 80 80 10 zU...P].^G..J...
;[030] 0c 07 57 9b 00 00 01 01 08 0a 00 3a be 4e 53 09 ..W........:.NS.
;[040] 8a 16                                           ..
;
;# 00:1d:93:00:4e:8f -> 00:24:d7:71:22:7c [IP]
;[000] 00 24 d7 71 22 7c 00 1d 93 00 4e 8f 08 00 45 00 .$.q"|....N...E.
;[010] 00 a7 00 00 40 00 40 11 ef 91 c0 a8 64 fe c0 a8 ....@.@.....d...
;[020] 64 65 00 35 9f 99 00 93 6c 8a da 05 81 80 00 01 de.5....l.......
;[030] 00 02 00 01 00 00 02 69 64 09 77 69 6b 69 70 65 .......id.wikipe
;[040] 64 69 61 03 6f 72 67 00 00 1c 00 01 c0 0c 00 05 dia.org.........
;[050] 00 01 00 00 09 11 00 11 04 74 65 78 74 09 77 69 .........text.wi
;[060] 6b 69 6d 65 64 69 61 c0 19 c0 2e 00 05 00 01 00 kimedia.........
;[070] 00 00 65 00 0d 04 74 65 78 74 05 70 6d 74 70 61 ..e...text.pmtpa
;[080] c0 33 c0 33 00 06 00 01 00 00 27 0d 00 27 03 6e .3.3......'..'.n
;[090] 73 30 c0 33 0a 68 6f 73 74 6d 61 73 74 65 72 c0 s0.3.hostmaster.
;[0a0] 33 77 de 0c 37 00 00 a8 c0 00 00 1c 20 00 12 75 3w..7....... ..u
;[0b0] 00 00 00 02 58                                  ....X


;;; プロトコルをARPに限定したスニフィング
(snif:sniffing "eth0" :protocol :arp)
;# 00:1d:93:00:4e:8f -> 00:24:d7:71:22:7c [ARP]
;[000] 00 24 d7 71 22 7c 00 1d 93 00 4e 8f 08 06 00 01 .$.q"|....N.....
;[010] 08 00 06 04 00 01 00 1d 93 00 4e 8f c0 a8 64 fe ..........N...d.
;[020] 00 00 00 00 00 00 c0 a8 64 65                   ........de
;
;# 00:1d:93:00:4e:8f -> 00:24:d7:71:22:7c [ARP]
;[000] 00 24 d7 71 22 7c 00 1d 93 00 4e 8f 08 06 00 01 .$.q"|....N.....
;[010] 08 00 06 04 00 01 00 1d 93 00 4e 8f c0 a8 64 fe ..........N...d.
;[020] 00 00 00 00 00 00 c0 a8 64 65                   ........de
;


;;; 低レベルAPI使用版
(snif:with-channel (cnl "eth0" :promisc t) 
  (loop
    (multiple-value-bind (octets source destination protocol) 
                         (snif:read-frame cnl)
      (print (list "送信元:" source
                   "送信先:" destination
                   "プロトコル:" protocol
                   "データ:" octets)))))

============
=== 参照 ===
・http://www.fenix.ne.jp/~thomas/memo/linux_raw_packet/http://linuxjm.sourceforge.jp/html/LDP_man-pages/man7/packet.7.html


============
=== TODO ===
・ソースコード整理
・SOCK_DGRAMに対応