Exemple #1
0
def get_ifname_and_smacaddr(saddr):
    err = 0
    plib = pcaplib.pcaplib()
    if plib.lib == None:
        print "Error: failed to load libpcap"
	return "", 0, -1
    devs, err = plib.Pcap_findalldevs()
    if err:
	return "", 0, err
    ostype = os.uname()[0]
    
    ifname = ""
    smacaddr = 0
    found = 0
    for dev in devs:
        if len(dev) < 2: 
	    continue
        for addr in dev[1:len(dev)]:
            if addr[0] == socket.AF_INET and addr[1] == saddr:
	        ifname = dev[0]
		for tmp in dev[1:len(dev)]:
		    if ((ostype == 'FreeBSD' or ostype == 'Darwin') and \
			tmp[0] == 18) or \
			ostype == 'Linux' and tmp[0] == 17:
		        smacaddr = tmp[1]
			break
		return ifname, smacaddr, 0
    return ifname, smacaddr, -1
Exemple #2
0
def pcap_send_segments(ifname, pkts, smacaddr=0, dmacaddr=0, sent=None):
    # Open pcap descripter
    plib = pcaplib.pcaplib()
    if plib.lib == None:
        print "Error: failed to load libpcap"
	return -1
    descrip = plib.Pcap_open_live(ifname)
    if descrip == None:
        print "Error: failed to open pcap descripter"
	return -1

    # Compose packets including datalink header
    frms = []
    dltype = plib.Pcap_datalink(descrip)
    for pkt in pkts:
        frm = ""
        if dltype == pcaplib.DLT_EN10MB:
	    etherh = tcplib.etherhdr(dmacaddr, smacaddr, 0x0800)
	    frm = etherh.bin()
	elif dltype == pcaplib.DLT_PPP or (dltype == 0 and re.match('ng[0-9]', ifname)):
	    frm = struct.pack('!BBBB', 0xff, 0x03, 0x00, 0x21)
	else:
	    print "Error: unsupported link type"
	    return -1
	frm += pkt
	frms.append(frm)

    # Send frames
    for frm in frms:
        err = plib.Pcap_inject(descrip, frm, len(frm))
	if err < 0:
	    plib.Pcap_close(descrip)
            print "Error: pcap_inject failed"
	    return -1

    if sent != None:
        sent.set()
    plib.Pcap_close(descrip)
    return 0
Exemple #3
0
def pcap_sendrecv_segments(ifname, pkts, timeout=1.0, sflags=0, \
		smacaddr=0, dmacaddr=0):
    rcvfrms = []
    rcvpkts = []
    err = 0

    # Open pcap descripter
    plib = pcaplib.pcaplib()
    if plib.lib == None:
        print "Error: failed to load libpcap"
	return rcvpkts, -1
    to_ms = int(1.0*1000)
    descrip = plib.Pcap_open_live(ifname, to_ms=to_ms)
    if descrip == None:
        print "Error: failed to open pcap descripter"
	return rcvpkts, -1

    dltype = plib.Pcap_datalink(descrip)

    # Set bpf filter
    iph, tcph, tcpo, payload = parse_headers(pkts[0])
    filter ='(src host %s and src port %d and dst port %d and udp and ip[8] = 1) or '%\
	    (socket.inet_ntop(socket.AF_INET, struct.pack('!L', iph.srcaddr)), \
	     tcph.srcport, PCAP_BREAK_DPORT)
    filter += '(ip[8] > 1 and src host %s and src port %d and dst host %s and dst port %d and tcp'%\
		  (socket.inet_ntop(socket.AF_INET, \
		   struct.pack('!L', iph.dstaddr)), tcph.dstport, 
		   socket.inet_ntop(socket.AF_INET, \
		   struct.pack('!L', iph.srcaddr)), tcph.srcport)
    if (sflags & tcplib.TH_SYN) is True:
        filter += ' and tcp[tcpflags] & (tcp-syn|tcp-ack) != 0'
    filter += ')'

    err = plib.Pcap_compile(descrip, filter)
    if err != 0:
	plib.Pcap_close(descrip)
        print "Error: failed to set pcap filter"
	return rcvpkts, -1

    sent = threading.Event()
    th = threading.Thread(target=pcap_send_segments, args=(ifname, tuple(pkts), smacaddr, dmacaddr, sent))
    th.setDaemon(True)

    # In some platforms (e.g., old Linux), timeout at open_live doesn't work
    # We define the killer packet to force finish pcap reading packets
    stopped = threading.Event()
    stopper = threading.Timer(timeout , send_pcapbreak, args=(pkts[0], stopped))
    stopper.start()

    th.start()
    while True:
        err, rcvfrm = plib.Pcap_next_ex(descrip)
	if err > 0:
	    # Quick check of TTL and Protocol in IP header
	    if dltype == pcaplib.DLT_EN10MB:
	        if struct.unpack('!BB', rcvfrm[22:24]) == (1, 17):
	            err = -2
	            break
	    elif dltype == pcaplib.DLT_PPP:
	        if struct.unpack('!BB', rcvfrm[12:14]) == (1, 17):
	            err = -2
	            break
	    rcvfrms.append(rcvfrm)
	    if sflags & tcplib.TH_SYN:
	        break
	    continue
	elif err == 0:
	    continue
	elif err == -2:
	    break
	elif err == -1:
            print "Error: failed in pcap_next_ex"
	    break
    if sent.isSet() == False:
        print "Error: timeout in pcap_send_segments"
	err = -1
    stopper.cancel()
    stopped.set()
    th.join()

    plib.Pcap_close(descrip)
    if err == -1:
        return rcvpkts, -1

    for rcvfrm in rcvfrms:
        if dltype == pcaplib.DLT_EN10MB:
            etherhdr, pkt = parse_ether_header(rcvfrm)
	elif dltype == pcaplib.DLT_PPP:
	    pkt = rcvfrm[4:]
	iph, tcph, tcpo, payload = parse_headers(pkt)
	rcvpkts.append((iph, tcph, tcpo, payload))

    return rcvpkts, 0
def peep_os_synack():

    global Peeped_synacks

    Peeper_lock.acquire()
    for i in range(0, 10):
        Peeped_synacks.append((0,0,0))
    Peeper_lock.release()

    os.putenv('LANG', 'C')
    os.putenv('PATH', '/bin:/sbin:/usr/bin:/usr/sbin:$PATH')
    cmd = 'netstat -rn | grep ^0.0.0.0 | sed s/\' \{2,\}\'/\' \'/g | cut -d\' \' -f2,8' 
    s = commands.getoutput(cmd)
    (nxthop_str, dummy, ifname) = s.partition(' ')
    try:
        fqdn = socket.getfqdn()
    except socket.gaierror:
        sys.exit(1)
    try:
        saddr_str = socket.gethostbyname(fqdn)
    except socket.gaierror:
        sys.exit(1)

    plib = pcaplib.pcaplib()
    if plib.lib == None:
	return
    descrip = plib.Pcap_open_live(ifname, to_ms=4000)
    if descrip == None:
	return
    filter = '(ip[8] = 1 and src host %s and src port %d and tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack != 0) or (ip[8] = 1 and src host %s and dst port %d and udp)'%(saddr_str, MPTCP_PORT, saddr_str, PEEP_BREAK_DPORT)

    err = plib.Pcap_compile(descrip, filter)
    if err != 0:
        plib.Pcap_close(descrip)
	return
    
    while True:
        err, rcvfrm = plib.Pcap_next_ex(descrip)
	if err > 0:
	    ttl, proto = struct.unpack('!BB', rcvfrm[22:24])
	    # handling breaking packet (1-TTL UDP packet to BREAK_DPORT)
	    if ttl == 1 and proto == 17:
		err = -2
		break
	    # handling reset for managing accepted list
	    # quick filtering of SYNACK from OS by TTL
	    elif ttl != 1 or proto != 6:
		continue
	    Peeper_lock.acquire()
	    Peeped_synacks.pop(0)
	    Peeped_synacks.append((struct.unpack('!L', rcvfrm[30:34])[0], \
				    struct.unpack('!H', rcvfrm[36:38])[0], \
				    struct.unpack('!L', rcvfrm[38:42])[0]))
	    Peeper_lock.release()
	    continue
	elif err == 0:
	    continue
	elif err == -2 or err == -1:
#	    print 'Error: pcap_next_ex returned %d'%err
	    break
    plib.Pcap_close(descrip)
    return