パケットキャプチャ作ってみた。


自分で プロトコルが選べるパケットをキャプチャ出来た…ふふふっ。
簡易Wiresharkって思ってくれたらいいですね、


tpc.py って名付けました。 TinyPacketCaptureです。

from socket import *
from AlPRO import AlPro
import sys

capture_start = lambda proto: AlPro()[proto]

"""
WTF CODE
def capture_start(proto):
    #AlPro().keys()
    v = AlPro().keys().index(proto)
    return AlPro().values()[v] 
"""

#print capture_start("ETH_P_IP")

def main():
    if  len(sys.argv) != 2:
        print "Usage:python tpc.py <PROTO> or 'PL'\n"
        print "PROTO: example ... ETH_P_IP , ETH_P_ARP or ETH_P_ALL.etc look at PL"
        print "PL:PL means ProtoList.  U can read Proto's List.  Should check"
        exit(0)

    elif sys.argv[1] == "PL":
        for i in AlPro():
            print i
        print 
        print '"ETH_P_IP or ETH_P_ALL" is famous...'
        exit(0)

    elif len(sys.argv) == 2:
        if sys.argv[1] not in AlPro().keys():
            print "Oh...look at PL..."
            print "Let's python tpc.py PL"
            exit(0)

# int(hex(2048)[2:],16)

    PROTO = int(capture_start(sys.argv[1])[2:],16)
    s = socket(PF_PACKET, SOCK_RAW,PROTO)
    s.bind(("eth1",PROTO))

    while True:
        p = s.recv(0x800)
        pl = len(p)

        f = lambda q,w: ":".join(["%02x" % ord(x) for x in q[w:w+6]])
        src = f(p,0)
        dst = f(p,6)
        ty = ntohs(ord(p[12:13]))
        print"%s > %s, ethertype %04x, length %d"%(src,dst,ty,pl)

        print "\t",
        for i in xrange(0,pl,2):
            print"%02x%02x"%(ord(p[i]),ord(p[i+1])),
            if i % 16 == 14:
                print "\n\t",
        print

if __name__ == '__main__':
    main()

プロトコルとその値をやってるからです。

ってことは、これを連携するものが必要ですね。

def AlPro():
    with file("/usr/include/linux/if_ether.h") as pc:
        Arr = {}
        for line in pc:
            FLAG=0
            if line.startswith('#define'):
                Va=line.split()
                if len(Va) > 2:
                    Arr[Va[1]] = Va[2]
            else:
                continue
    return Arr


AlPRO.py と tpc.py を隣り合わせに置いて、

python tpc.py ETH_P_IP

ってしましょう。
すると、IPパケットがキャプチャされ出力されます。


あってか、 ETH_P_IP とか(その他の名称なんて)知るか!!!!

だから、

python tpc.py PL

ってしてみてください。

Protocol LIST という意味で、全部見れます。
はい。

出力結果!!

$python tpc.py PL
ETH_P_8021Q
ETH_P_PHONET
ETH_P_RARP
ETH_P_LOCALTALK
ETH_P_WCCP
ETH_P_PPP_DISC
ETH_P_TIPC
ETH_P_IP
ETH_P_ATMFATE
ETH_DATA_LEN
ETH_P_IPX
ETH_HLEN
ETH_P_PUP

ってなったり、

$ python tpc.py ETH_P_ALL
ff:ff:ff:ff:ff:ff > 10:40:f3:95:4f:5e, ethertype 0800, length 60
	ffff ffff ffff 1040 f395 4f5e 0800 4500 
	002c 8ba7 0000 4011 6ac6 c0a8 0104 c0a8 
	01ff c630 21a4 0018 0608 424a 4a42 0101 
	0000 0000 0000 0000 0000 0000
01:00:5e:00:00:01 > 10:40:f3:95:4f:5e, ethertype 0800, length 60
	0100 5e00 0001 1040 f395 4f5e 0800 4500 
	002c e282 0000 0111 3591 c0a8 0104 e000 
	0001 e976 21a4 0018 c567 424a 4a42 0101 
	0000 0000 0000 0000 0000 0000

ってなったりします。

感想:
 Wiresharkのような高級パケットキャプチャの根本にはこれらのようなことが行われているのだと思うと、そんな難しいように思わなかったです。非常に面白かったです。