def make_segment(daddr, saddr, dport, sport, awnd, seq, ack, flags, options=(), payload=None, ipcksum=0): segment = "" if payload == "": payload = None soptions = compose_options(options) ipid = random.randrange(0x0001, 0xfffe) ipttl = 255 iplen = tcplib.BASEHDRLEN + len(soptions) if payload != None: iplen += len(payload) iph = tcplib.iphdr(saddr, daddr, iplen, ipid, ipttl) # If we use RAW socket, we don't need to calculate checksum, but if we use # Pcap, we need to calculate it if ipcksum: iph.calccksum() tcph = tcplib.tcphdr(sport, dport, seq, ack, flags, awnd, soptions) tcph.calccksum(iph, payload) segment += iph.bin() segment += tcph.bin() if payload != None: segment += payload return segment
def sendrecv_segments(daddr, pkts, timeout=1.0, sflags=0, \ usepcap=0, ifname="", smacaddr=0, dmacaddr=0): if usepcap == 1: if ifname == "": print "Error: No ifname is given to use pcap for sendrecv_segments" return [], -1 rcvpkts, err = pcap_sendrecv_segments(ifname, pkts, timeout, sflags, \ smacaddr, dmacaddr) return rcvpkts, err tmp_rcvpkts = [] rcvpkts = [] err = 0 s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP) s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) myiph, mytcph, myopts, mypayload = parse_headers(pkts[0]) mydport = mytcph.dstport mysport = mytcph.srcport mydaddr = myiph.dstaddr mysaddr = myiph.srcaddr sent = threading.Event() th = threading.Thread(target=send_segments, args=(daddr, pkts, 0, "", 0, 0, sent)) th.setDaemon(True) th.start() start = time.time() while True: if time.time() - start > timeout: break try: inputready,outputready,exceptready = select.select([s], [], [], 1) except select.error, e: print "Warn: select.error" if e[0] == errno.EINTR: continue else: break if len(inputready) == 0: continue try: (rcvdata, recvaddr) = s.recvfrom(65565) except (socket.error, OSError): err = -1 break iph = tcplib.iphdr() iph.parsehdr(rcvdata[0:20]) tcph = tcplib.tcphdr() tcph.parsehdr(rcvdata[iph.hdrlen:iph.hdrlen+20]) if tcph.srcport != mydport or tcph.dstport != mysport or \ iph.srcaddr != mydaddr or iph.dstaddr != mysaddr: continue # ignore 1 ttl packet, because it could be generated by dummy socket elif iph.ttl == 1: continue tmp_rcvpkts.append(rcvdata) if (sflags & tcplib.TH_SYN) and \ (tcph.flag & (tcplib.TH_SYN | tcplib.TH_ACK)): break
def parse_headers(pkt): ipdata = pkt[0:20] iph = tcplib.iphdr() iph.parsehdr(ipdata) tcpheader = pkt[iph.hdrlen:iph.hdrlen+20] tcph = tcplib.tcphdr() tcph.parsehdr(tcpheader) tcpofields = pkt[iph.hdrlen + 20 : iph.hdrlen + tcph.hdrlen] tcpoptions = decompose_options(tcpofields) payload = pkt[iph.hdrlen + tcph.hdrlen : len(pkt)] return iph, tcph, tcpoptions, payload
def send_packet(): global tcpsoption ackno = tcpackno # add padding to tcp option tcpsoption += tcplib.check_padding(tcpsoption) # special hack parse sdata = "" if datalen > 3 or (len(data) > 1 and tcpflag & tcplib.TH_SYN): trimmed, http = httpenc.trim_httphdr(data) if not http and \ struct.unpack('!B', trimmed[0:1])[0] == request_hdrdata_http: http = 1 if http and httpenc.is_http_get(data, 'hoge.cgi'): sdata = httpenc.httphdr_ok_dummy() elif len(trimmed) == 0: pass elif struct.unpack('!B', trimmed[0:1])[0] == request_dupack: ackno = tcph.seqno elif struct.unpack('!B', trimmed[0:1])[0] == request_differ_tsecr or \ struct.unpack('!B', trimmed[0:1])[0] == request_hdrdata or \ struct.unpack('!B', trimmed[0:1])[0] == request_hdrdata_http or \ struct.unpack('!B', trimmed[0:1])[0] == Hdrdata_and_advsyndata_ack: if struct.unpack('!B', trimmed[0:1])[0] == request_differ_tsecr: tcpsoption = tcplib.create_timestamp(TSval, tsecr-1) tcpsoption += tcplib.check_padding(tcpsoption) target_len = 512 - len(tcpsoption) if tcpflag & tcplib.TH_SYN: target_len = len(data) # Prepare HTTP OK header if http: sdata = httpenc.httphdr_ok(target_len) # Prepare receiving headers sdata += rcvhdrdata # Prepare sending headers (IP and TCP checksums are zero) tmpiph = tcplib.iphdr(ipsrc, ipdest, tcplib.BASEHDRLEN + 512, \ ipid, ipttl) tmptcph = tcplib.tcphdr(tcpsport, tcpdport, tcpseqno, ackno, \ tcpflag, tcpwindow, tcpsoption) sdata += tmpiph.bin() + tmptcph.bin() cur_len = len(sdata) if len(trimmed) >= target_len - cur_len: sdata += trimmed[0: target_len - cur_len] else: sdata += trimmed cur_len += len(trimmed) for i in range(0, target_len - cur_len): sdata += struct.pack('!B', 0xAB) # prepare ip header iplen = tcplib.BASEHDRLEN + len(tcpsoption) + len(sdata) iphs = tcplib.iphdr(ipsrc, ipdest, iplen, ipid, ipttl) # prepare tcp header tcphs = tcplib.tcphdr(tcpsport, tcpdport, tcpseqno, ackno, \ tcpflag, tcpwindow, tcpsoption) if len(sdata) == 0: tcphs.calccksum(iphs) else: tcphs.calccksum(iphs, sdata) payload = iphs.bin() payload += tcphs.bin() if len(sdata) > 0: payload += sdata dstr = socket.inet_ntoa(struct.pack('!L',ipdest)) s.sendto(payload, (dstr, 0))
elif struct.unpack('!L', data[0:4])[0] == FLOOD_UDP_STOP: # print "got UDP_STOP current state", Fld_udp_on.isSet() if Fld_udp_on.isSet() == True: Fld_udp_on.clear() # print "UDP flooder has been stopped" sss.sendto(struct.pack('!L', FLOOD_UDP_CONFIRMED), address) continue if recvready == 0: continue # receive a packet (rcvddata, recvaddr) = s.recvfrom(65565) # parse ip header ipdata = rcvddata[0:20] iph = tcplib.iphdr() iph.parsehdr(ipdata) # parse tcp header tcpheader = rcvddata[iph.hdrlen:iph.hdrlen+20] tcph = tcplib.tcphdr() tcph.parsehdr(tcpheader) datalen = len(rcvddata) - iph.hdrlen - tcph.hdrlen if tcph.dstport != MPTCP_PORT: continue elif tcph.flag & tcplib.TH_RST: continue elif iph.ttl == 1: continue # don't reply to pure ack if datalen == 0 and \ (tcph.flag & tcplib.TH_SYN) == 0 and (tcph.flag & tcplib.TH_FIN) == 0:
def send_packet(): global tcpsoption # add padding to tcp option tcpsoption += tcplib.check_padding(tcpsoption) # special hack parse sdata = "" http = 0 abbrev_header = "" http_response = "" if len(data) > 3: unpacked = struct.unpack(str(len(data)) + 's', data)[0] if unpacked[0:3] == "GET": http = 1 end_of_request_line = unpacked.find("\r\n") abbrev_header = "GET /%s HTTP/1.1%s" % (unpacked[6], unpacked[end_of_request_line:]) if (struct.unpack('!B', data[0:1])[0] == request_hdrdata) or (struct.unpack('!B', struct.unpack(str(len(data)) + 's', data)[0][6])[0] == request_hdrdata): # Prepare receiving headers sdata = rcvhdrdata # Prepare sending headers (IP and TCP checksums are zero) tmpiph = tcplib.iphdr(ipsrc, ipdest, tcplib.BASEHDRLEN + 512, \ ipid, ipttl) tmptcph = tcplib.tcphdr(tcpsport, tcpdport, tcpseqno, tcpackno, \ tcpflag, tcpwindow, tcpsoption) sdata += tmpiph.bin() + tmptcph.bin() target_len = 512 - len(tcpsoption) cur_len = len(sdata) if http == 1: sdata += struct.pack(str(len(abbrev_header)) + 's', abbrev_header) cur_len += len(abbrev_header) if len(data) >= target_len - cur_len: sdata += data[6: target_len - cur_len + 6] else: sdata += data[6:] cur_len += len(data)-6 for i in range(0, target_len - cur_len): sdata += struct.pack('!B', 0xAB) # prepare ip header iplen = tcplib.BASEHDRLEN + len(tcpsoption) + len(sdata) iphs = tcplib.iphdr(ipsrc, ipdest, iplen, ipid, ipttl) # prepare tcp header tcphs = tcplib.tcphdr(tcpsport, tcpdport, tcpseqno, tcpackno, \ tcpflag, tcpwindow, tcpsoption) if len(sdata) == 0: tcphs.calccksum(iphs) else: tcphs.calccksum(iphs, sdata) payload = iphs.bin() payload += tcphs.bin() if http == 1: if (len(sdata) > 0): http_response = "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n" % (len(sdata)-40) payload += struct.pack(str(len(http_response)) + 's', http_response) payload += sdata[:-(len(http_response))] else: http_response = "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n" % 0 payload += struct.pack(str(len(http_response)) + 's', http_response) elif len(sdata) > 0: payload += sdata dstr = socket.inet_ntoa(struct.pack('!L',ipdest)) s.sendto(payload, (dstr, 0))