def callback(test, payload): data = payload.get_data() pkt = IP(data) print("Got a packet : " + str(datetime.now())) print(" Source ip : " + str(pkt.src)) print(" Dest ip : " + str(pkt.dst)) print(" Source port : " + str(pkt.sport)) print(" Dest port : " + str(pkt.dport)) print(" Protocol : " + str(pkt.proto)) print(" Flags :" + pkt.sprintf('%TCP.flags%'))
def callback(test, payload): global interval global limit global requestIPs global blackList data = payload.get_data() pkt = IP(data) print("Got a packet : "+str(datetime.now())) print(" Source ip : " + str(pkt.src)) print(" Dest ip : " + str(pkt.dst)) print(" Source port : "+str(pkt.sport)) print(" Dest port : "+str(pkt.dport)) print(" Protocol : "+str(pkt.proto)) print(" Flags :"+pkt.sprintf('%TCP.flags%')) if(int(pkt.proto)!=6): # We let all non tcp messages go through without filtering payload.set_verdict(nfqueue.NF_ACCEPT) else: if(str(pkt.src) in blackList): print("This source has been blacklisted for DOSing") payload.set_verdict(nfqueue.NF_DROP) else: if(str(pkt[TCP].flags)=="20"): print("Response to a request") ### This is a response to a request, so we don't execute the checking procedure on this ip payload.set_verdict(nfqueue.NF_ACCEPT) else: if(str(pkt[TCP].flags)=="0"): print("TCP synchronisation request") indexes = getIpSource(str(pkt.src),requestIPs) if(indexes==[]): print("First request to this destination") requestIPs.append([str(pkt.src),time.time()*1000,1,str(pkt.dst)]) payload.set_verdict(nfqueue.NF_ACCEPT) else: index = isAssociatedToThisDestination(str(pkt.dst),requestIPs,indexes) if(index==None): print("First request to this destination.") requestIPs.append([str(pkt.src), time.time() * 1000, 1, str(pkt.dst)]) payload.set_verdict(nfqueue.NF_ACCEPT) elif(requestIPs[index][2]>=limit): print(str(pkt.src) + " is blacklisted for DOS this destination") blackList.append(str(pkt.src)) payload.set_verdict(nfqueue.NF_DROP) else: request = requestIPs[index] lastRequest = request[1] t = time.time()*1000 if ((t - lastRequest) < interval): requestIPs[index] = [str(pkt.src),t,request[2]+1,str(pkt.dst)] else: requestIPs[index] = [str(pkt.src),t,request[2],str(pkt.dst)] payload.set_verdict(nfqueue.NF_ACCEPT) print
def snoop_create(pkt): global dcache # data cache global acache # ack cache global lastseq global transmit logger.debug("SNOOP_CREATE") sp = IP(pkt.get_payload()) ips = (sp["IP"].getfieldval('src'),sp["IP"].getfieldval('dst')) logger.debug("\tIP: %s" % str(ips)) ports = (sp["TCP"].getfieldval('sport'),sp["IP"].getfieldval('dport')) logger.debug("\tPORTS: %s" % str(ports)) flow = (ips,ports) logger.debug("\tFLOW: %s" % str(flow)) seqnum = int(sp["TCP"].getfieldval('seq')) acknum = int(sp["TCP"].getfieldval('ack')) inv_flow = ((ips[1],ips[0]),(ports[1],ports[0])) logger.debug("\tseq: %s, ack:%s" % (seqnum,acknum)) # handle the SYN lastseq[flow] = (seqnum,acknum) # if "S" in sp.sprintf('%TCP.flags%'): # dcache.insert(flow,seqnum,sp) # this will get called if and only if there is an S # so this is a SA packet if "A" in sp.sprintf('%TCP.flags%'): # verify # dcache.remove(inv_flow,acknum-1) # acache.insert(flow,acknum,sp) lastseq[inv_flow] = (acknum,seqnum) fin_hand[flow] = False fin_hand[inv_flow] = False pkt.accept() logger.debug("lastseq: %s" % str(lastseq)) logger.debug("dcache:\n%s" % dcache) print_accept()
def snoop_create(pkt): global dcache # data cache global acache # ack cache global lastseq global transmit logger.debug("SNOOP_CREATE") sp = IP(pkt.get_payload()) ips = (sp["IP"].getfieldval('src'), sp["IP"].getfieldval('dst')) logger.debug("\tIP: %s" % str(ips)) ports = (sp["TCP"].getfieldval('sport'), sp["IP"].getfieldval('dport')) logger.debug("\tPORTS: %s" % str(ports)) flow = (ips, ports) logger.debug("\tFLOW: %s" % str(flow)) seqnum = int(sp["TCP"].getfieldval('seq')) acknum = int(sp["TCP"].getfieldval('ack')) inv_flow = ((ips[1], ips[0]), (ports[1], ports[0])) logger.debug("\tseq: %s, ack:%s" % (seqnum, acknum)) # handle the SYN lastseq[flow] = (seqnum, acknum) # if "S" in sp.sprintf('%TCP.flags%'): # dcache.insert(flow,seqnum,sp) # this will get called if and only if there is an S # so this is a SA packet if "A" in sp.sprintf('%TCP.flags%'): # verify # dcache.remove(inv_flow,acknum-1) # acache.insert(flow,acknum,sp) lastseq[inv_flow] = (acknum, seqnum) fin_hand[flow] = False fin_hand[inv_flow] = False pkt.accept() logger.debug("lastseq: %s" % str(lastseq)) logger.debug("dcache:\n%s" % dcache) print_accept()
def snoop(pkt): global first_pkt logger.debug("SNOOP") sp = IP(pkt.get_payload()) seqnum = int(sp["TCP"].getfieldval('seq')) acknum = int(sp["TCP"].getfieldval('ack')) ips = (sp["IP"].getfieldval('src'),sp["IP"].getfieldval('dst')) #Tear down and create states # if you see an F in flags it means FIN, clean up all connection info. logger.info("\tflags: %3s | src:%s dst:%s | seq:%s ack:%s" %\ (sp.sprintf('%TCP.flags%'),str(ips[0]),str(ips[1]),seqnum,acknum)) if "F" in sp.sprintf('%TCP.flags%') or "R" in sp.sprintf('%TCP.flags%'): logger.debug("\tFIN detected, cleaning.") # snoop_clean(pkt) # pkt.accept() # return # create flow information in SYN rather than in ack and data. elif "S" in sp.sprintf('%TCP.flags%'): logger.debug("\tSYN detected, creating flow.") snoop_create(pkt) return ports = (sp["TCP"].getfieldval('sport'),sp["IP"].getfieldval('dport')) flow = (ips,ports) inv_flow = ((ips[1],ips[0]),(ports[1],ports[0])) # handle the last ACK in 3-way handshake if not fin_hand[flow]: snoop_create(pkt) fin_hand[flow] = True fin_hand[inv_flow] = True first_pkt[flow] = True first_pkt[inv_flow] = True return try: prev_seq = lastseq[flow][0] prev_ack = lastseq[flow][1] logger.debug("\tprev ack: %s | current ack: %s" % (prev_ack,acknum)) logger.debug("\tprev seq: %s | current seq: %s" % (prev_seq,seqnum)) # if seqnum is less or greather than previous, we will accept and forward if seqnum > prev_seq: logger.debug("\tData detected") first_pkt[flow] = False # snoop data will catch the piggys snoop_data(pkt) return elif acknum > prev_ack: logger.debug("\tACK") first_pkt[flow] = False snoop_ack(pkt) return # if the acknum is greater or less than, we will accept greater and reject lower else: if flow in first_pkt and first_pkt[flow]: #FIXME, this packet never gets acked. logger.debug("\tFirst Packet") first_pkt[flow] = False if first_pkt[inv_flow]: accept_packet(pkt,flow,seqnum,acknum,0) else: accept_packet(pkt,flow,seqnum,acknum,1) return else: logger.debug("Out of date.") if dcache.get(flow,seqnum): logger.debug("\t\tflow: %s, in dcache: %s, DATA" % (flow,dcache.get(flow,seqnum))) snoop_data(pkt) elif acache.get(flow,acknum-1): logger.debug("\t\tflow: %s, in acache: %s, ACK" % (flow,acache.get(flow,acknum))) snoop_ack(pkt) # again our assumptions are that the data link side is not lossy, ack side is with iperf. else: logger.debug("flow: %s, inv_flow: %s" % (flow,inv_flow)) logger.debug("seq: %s, ack: %s" % (seqnum,acknum)) if dcache.get(inv_flow,acknum-1): snoop_ack(pkt) else: snoop_data(pkt) except Exception, e: logger.error("ERROR IN SNOOP HANDLE") logger.error(str(e)) logger.error(traceback.format_exc())
def snoop(pkt): global first_pkt logger.debug("SNOOP") sp = IP(pkt.get_payload()) seqnum = int(sp["TCP"].getfieldval('seq')) acknum = int(sp["TCP"].getfieldval('ack')) ips = (sp["IP"].getfieldval('src'), sp["IP"].getfieldval('dst')) #Tear down and create states # if you see an F in flags it means FIN, clean up all connection info. logger.info("\tflags: %3s | src:%s dst:%s | seq:%s ack:%s" %\ (sp.sprintf('%TCP.flags%'),str(ips[0]),str(ips[1]),seqnum,acknum)) if "F" in sp.sprintf('%TCP.flags%') or "R" in sp.sprintf('%TCP.flags%'): logger.debug("\tFIN detected, cleaning.") # snoop_clean(pkt) # pkt.accept() # return # create flow information in SYN rather than in ack and data. elif "S" in sp.sprintf('%TCP.flags%'): logger.debug("\tSYN detected, creating flow.") snoop_create(pkt) return ports = (sp["TCP"].getfieldval('sport'), sp["IP"].getfieldval('dport')) flow = (ips, ports) inv_flow = ((ips[1], ips[0]), (ports[1], ports[0])) # handle the last ACK in 3-way handshake if not fin_hand[flow]: snoop_create(pkt) fin_hand[flow] = True fin_hand[inv_flow] = True first_pkt[flow] = True first_pkt[inv_flow] = True return try: prev_seq = lastseq[flow][0] prev_ack = lastseq[flow][1] logger.debug("\tprev ack: %s | current ack: %s" % (prev_ack, acknum)) logger.debug("\tprev seq: %s | current seq: %s" % (prev_seq, seqnum)) # if seqnum is less or greather than previous, we will accept and forward if seqnum > prev_seq: logger.debug("\tData detected") first_pkt[flow] = False # snoop data will catch the piggys snoop_data(pkt) return elif acknum > prev_ack: logger.debug("\tACK") first_pkt[flow] = False snoop_ack(pkt) return # if the acknum is greater or less than, we will accept greater and reject lower else: if flow in first_pkt and first_pkt[flow]: #FIXME, this packet never gets acked. logger.debug("\tFirst Packet") first_pkt[flow] = False if first_pkt[inv_flow]: accept_packet(pkt, flow, seqnum, acknum, 0) else: accept_packet(pkt, flow, seqnum, acknum, 1) return else: logger.debug("Out of date.") if dcache.get(flow, seqnum): logger.debug("\t\tflow: %s, in dcache: %s, DATA" % (flow, dcache.get(flow, seqnum))) snoop_data(pkt) elif acache.get(flow, acknum - 1): logger.debug("\t\tflow: %s, in acache: %s, ACK" % (flow, acache.get(flow, acknum))) snoop_ack(pkt) # again our assumptions are that the data link side is not lossy, ack side is with iperf. else: logger.debug("flow: %s, inv_flow: %s" % (flow, inv_flow)) logger.debug("seq: %s, ack: %s" % (seqnum, acknum)) if dcache.get(inv_flow, acknum - 1): snoop_ack(pkt) else: snoop_data(pkt) except Exception, e: logger.error("ERROR IN SNOOP HANDLE") logger.error(str(e)) logger.error(traceback.format_exc())