NewLionwang / dpkt

Automatically exported from code.google.com/p/dpkt
Other
0 stars 0 forks source link

some sample code took me some time #8

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
import dpkt
import socket
import struct,string

def eth_aton(buffer):
    addr =''
    temp = string.split(buffer,':')
    buffer = string.join(temp,'')
    for i in range(0, len(buffer), 2):
        addr = ''.join([addr,struct.pack('B', int(buffer[i: i + 2], 16))],)
    return addr

#############
### here is some secret sauce
### dpkt does not have this for some reason
### but you gotta have this header
### \xaa\xaa is for SNAP packet
### \x03 for Control field
### \x00\x00\x0c is Cisco org code
### the " \x00" somehow comes out to 0x2000, protocol id for CDP
############

cdp_header='\xaa\xaa\x03\x00\x00\x0c \x00'

###############
### more sauce
### this is the ethernet multicast addr
### for cdp messages HA! 01:00:0c:cc:cc:cc
###############

eth_dst = '\x01\x00\x0c\xcc\xcc\xcc'

#######
##change if you like, 00:07:85 OID for Cisco
#########
ipaddr = "192.168.0.1"
src_eth = "00:07:85:12:34:56"

###################################################################
###################################################################

def make_addr(ipaddr): ## make an address packet for a TLV
        tmp_addr = dpkt.cdp.CDP.Address()
        tmp_addr.data = socket.inet_aton(ipaddr)
        return tmp_addr.pack()

def make_tlv(addpack): ## take address packet and put in TLV (type,len,value)
        tmp_tlv = dpkt.cdp.CDP.TLV()
        tmp_tlv.data = addpack
        tmp_tlv.type = dpkt.cdp.CDP_ADDRESS
        tmp_tlv.len = tmp_tlv.__len__()
#########
### this is to make up for prob with the dpkt libs, trying to mod lib code
### appears to not pack TLVs with type == CDP_addresses right
### TLVS with type=address include a number in front that
### is how many addresses to follow. dpkt uses len of data field, while I am
### using len/9 because my test data has len of 9 (so an 18 byte field has 2
### addresses - DRM
#########
        j = struct.pack('>I', len(tmp_tlv.data)/9)
        data = tmp_tlv.pack_hdr() + j + tmp_tlv.data
        return data

def make_cdp(data): ## and now the CDP packet part
        tmp_cdp = dpkt.cdp.CDP()
        tmp_cdp.data = data
        tmp_cdp.sum=dpkt.in_cksum(tmp_cdp.data)
        return tmp_cdp.pack()

def make_ethf(data,src,dst): ##and then the ethernet frame
        tmp_eth = dpkt.ethernet.Ethernet()
        tmp_eth.data = cdp_header+data
        tmp_eth.dst = dst
        tmp_eth.src = src
        tmp_eth.type = len(tmp_eth.data) ## for a SNAP packet, the type= len
        return tmp_eth.pack()

################################################################
### build it
################################################################
eth_src = eth_aton(src_eth)
addrpacket = make_addr(ipaddr)
tlv_packet = make_tlv(addrpacket)
cdp_packet = make_cdp(tlv_packet)
eth_frame = make_ethf(cdp_packet,eth_src,eth_dst)

########################################33
### open the socket
#########################################
s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW)
s.bind(("eth0",dpkt.ethernet.ETH_TYPE_CDP))

##########################################
### fire off 3 packets
#########################################
for i in range(3):
        s.send(eth_frame)

###################
### close it
##################
s.close()

Original issue reported on code.google.com by don.mi...@gmail.com on 23 Apr 2008 at 11:26

GoogleCodeExporter commented 8 years ago
problems:  wireshark/tcpdump will decode, but see checksum on cdp as incorrect. 
 Next
step is to add more CDP fields, with the ultimate goal to be able to 
impersonate a
Cisco phone.  Most Cisco Voip implementations depend on CDP messages to place 
phones
in a special VOIP vlan....

Original comment by don.mi...@gmail.com on 23 Apr 2008 at 11:30

GoogleCodeExporter commented 8 years ago
Final comment: eth_aton function stolen from http://zeaster.blogspot.com/, but 
rest
of his sample code I can't get to work.  He calls whole class (ip_p = ip.IP()...
packet.data = ip_p) which errors out for me.  I find you have to call {packet
type}.pack() or a variation of {packet type).__str__ or (packet type).data 
depending
on what you are doing.  Also when programming this {packet type}.__dict__ is 
uber
helpful to keep track of what class attributes are necessary.

Original comment by don.mi...@gmail.com on 23 Apr 2008 at 11:36