Exemple #1
0
def tests():
    f = Firewall()

    ip = ipv4()
    ip.dstip = IPAddr("192.168.100.2")
    ip.srcip = IPAddr("172.16.42.1")
    ip.protocol = ip.TCP_PROTOCOL
    xudp = tcp()
    xudp.srcport = 49662
    xudp.dstport = 80 
    xudp.payload = "Hello, world"
    xudp.len = 8 + len(xudp.payload)
    ip.payload = xudp

    print len(ip) # print the length of the packet, just for fun

    # you can name this method what ever you like, but you'll
    # need some method that gets periodically invoked for updating
    # token bucket state for any rules with rate limits
    f.update_tokens()

    # again, you can name your "checker" as you want, but the
    # idea here is that we call some method on the firewall to
    # test whether a given packet should be permitted or denied.
    print f.forward_packet(ip)
    
    ip2 = ipv4()
    ip2.srcip = IPAddr("192.168.100.2")
    ip2.dstip = IPAddr("172.16.42.1")
    ip2.protocol = ip2.TCP_PROTOCOL
    xudp2 = tcp()
    xudp2.srcport = 80
    xudp2.dstport = 49662
    xudp2.payload = "Hello, world"
    xudp2.len = 8 + len(xudp2.payload)
    ip2.payload = xudp2

    print len(ip2) # print the length of the packet, just for fun

    # you can name this method what ever you like, but you'll
    # need some method that gets periodically invoked for updating
    # token bucket state for any rules with rate limits
    f.update_tokens()

    # again, you can name your "checker" as you want, but the
    # idea here is that we call some method on the firewall to
    # test whether a given packet should be permitted or denied.
    print f.forward_packet(ip2)


    # if you want to simulate a time delay and updating token buckets,
    # you can just call time.sleep and then update the buckets.
    time.sleep(0.5)
    f.update_tokens()
Exemple #2
0
def tests():
    f = Firewall()
    ip = ipv4()
    ip.srcip = IPAddr("172.16.42.1")
    ip.dstip = IPAddr("172.16.42.35")
    # 17 for udp, 6 tcp, 1 icmp
    ip.protocol = 6

    icmppkt = pktlib.icmp()
    icmppkt.type = pktlib.TYPE_ECHO_REQUEST
    icmppkt.payload ="Hello, world"
    
    xudp = udp()
    xudp.srcport = 53
    xudp.dstport = 53
    xudp.payload = "Hello, world"
    xudp.len = 8 + len(xudp.payload)
    
    tcppkt = pktlib.tcp()
    tcppkt.SYN = 1
    tcppkt.seq = 14
    tcppkt.srcport = 80
    tcppkt.dstport = 80
    tcppkt.offset = 5
    tcppkt.payload = "Hello, world"
    tcppkt.tcplen = 20
    
#    ip.payload = xudp
#    ip.payload = icmppkt
    ip.payload = tcppkt

    f=Firewall()
    f.mainframe(ip, time.time())
    def new_packet(self, ack=True, data=None, syn=False):
        """
    Creates and returns a new TCP segment encapsulated in an IP packet.

    If ack is set, it sets the ACK flag.
    If data is set, it is set as the TCP payload.
    If syn is set, it sets the SYN flag
    """
        assert self.is_peered
        assert self.is_bound
        p = self.stack.new_packet()
        p.ipv4 = pkt.ipv4(srcip=self.name[0], dstip=self.peer[0])
        p.ipv4.protocol = pkt.ipv4.TCP_PROTOCOL
        p.tcp = pkt.tcp(srcport=self.name[1], dstport=self.peer[1])
        p.ipv4.payload = p.tcp

        p.tcp.seq = self.snd.nxt
        p.tcp.ack = self.rcv.nxt
        p.tcp.ACK = ack
        p.tcp.SYN = syn

        if data:
            p.tcp.payload = data

        p.tcp.win = min(0xffFF, self.rcv.wnd)
        return p
Exemple #4
0
 def create_packet(e1, e2, i1, i2, t1, t2):
     e = pkt.ethernet(src=e1, dst=e2, type=pkt.ethernet.IP_TYPE)
     i = pkt.ipv4(srcip=i1, dstip=i2, protocol=pkt.ipv4.TCP_PROTOCOL)
     t = pkt.tcp(srcport=t1, dstport=t2, off=5, win=1)
     t.ACK = True
     i.payload = t
     e.payload = i
     return e
    def import_rules(self):
        file = open("firewall_rules.txt", "r")
        for line in file:
            if len(line) != 1:                  #this is to get rid of the empty lines
                words = []
                words = line.split()
                if words[0] == "permit" or words[0] == "deny":          #make sure it is not a comment
                    ruleObject = Rules()
                    ruleObject.line = line
                    for idx in range(len(words)):
                        if words[idx] == "permit":
                            ruleObject.action = "permit"
                        if words[idx] == "deny":
                            ruleObject.action = "deny"
                        if words[idx] == "ip":
                            ruleObject.type = type(pktlib.ipv4())
                        if words[idx] == "tcp":
                            ruleObject.type = type(pktlib.tcp())
                        if words[idx] == "udp":
                            ruleObject.type = type(pktlib.udp())
                        if words[idx] == "icmp":
                            ruleObject.type = type(pktlib.icmp())
                        if words[idx] == "src":
                            if words[idx+1] == "any":
                                ruleObject.src = 1
                            else:
                                ruleObject.src = words[idx+1]
                                if "/" in ruleObject.src:               #meaning its a net addr-we need the netmask
                                    temp = parse_cidr(ruleObject.src)
                                    srcnetMask = cidr_to_netmask(temp[1])
                                    ruleObject.netMask = srcnetMask
                        if words[idx] == "srcport":
                            if words[idx+1] == "any":
                                ruleObject.srcport = 1
                            else:
                                ruleObject.srcport = words[idx+1]
                        if words[idx] == "dst":
                            if words[idx+1] == "any":
                                ruleObject.dst = 1
                            else:
                                ruleObject.dst = words[idx+1]
                        if words[idx] == "dstport":
                            if words[idx+1] == "any":
                                ruleObject.dstport = 1
                            else:
                                ruleObject.dstport = words[idx+1]
                        if words[idx] == "ratelimit":
                            ruleObject.ratelimit = words[idx+1]

                    self.rules.append(ruleObject)
Exemple #6
0
def flowlet_to_packet(flowlet):
    if hasattr(flowlet, "origpkt"):
        return getattr(flowlet, "origpkt")

    ident = flowlet.ident.key

    etherhdr = pktlib.ethernet()
    etherhdr.src = EthAddr(flowlet.srcmac)
    etherhdr.dst = EthAddr(flowlet.dstmac)
    etherhdr.type = pktlib.ethernet.IP_TYPE

    ipv4 = pktlib.ipv4()
    ipv4.srcip = IPAddr(ident.srcip)
    ipv4.dstip = IPAddr(ident.dstip)
    ipv4.protocol = ident.ipproto
    ipv4.tos = flowlet.iptos
    iplen = flowlet.bytes / flowlet.pkts
    ipv4.iplen = iplen
    payloadlen = 0

    etherhdr.payload = ipv4

    if ident.ipproto == IPPROTO_ICMP:
        layer4 = pktlib.icmp()
        layer4.type = ident.dport >> 8
        layer4.code = ident.dport & 0x00FF
        payloadlen = max(iplen - 28, 0)
    elif ident.ipproto == IPPROTO_UDP:
        layer4 = pktlib.udp()
        layer4.srcport = ident.sport
        layer4.dstport = ident.dport
    elif ident.ipproto == IPPROTO_TCP:
        layer4 = pktlib.tcp()
        layer4.srcport = ident.sport
        layer4.dstport = ident.dport
        layer4.flags = flowlet.tcpflags
        layer4.off = 5
        payloadlen = max(iplen - 40, 0)
        layer4.tcplen = payloadlen
        layer4.payload = spack("{}x".format(payloadlen))
    else:
        raise UnhandledPoxPacketFlowletTranslation(
            "Can't translate IP protocol {} from flowlet to POX packet".format(fident.ipproto)
        )
    ipv4.payload = layer4
    etherhdr.origflet = flowlet
    return etherhdr
Exemple #7
0
def send_tcp_fin_ack (event,packet): 

   # Check if TCP 
   tcp_in = packet.find("tcp")        
   
   #print "Send TCP Reset" 
   http_resp = pkt.tcp()
   payload = ""
       
   # Send HTTP response packet
   # Ethernet frame
   e = pkt.ethernet()
   e.src = packet.dst
   e.dst = packet.src
   e.type = e.IP_TYPE
       
   # Now create the IPv4 packet
   ipp = pkt.ipv4()
   ipp.protocol = ipp.TCP_PROTOCOL
       
   ipp.srcip = packet.find("ipv4").dstip
   ipp.dstip = packet.find("ipv4").srcip
   ipp.flags = packet.find("ipv4").flags
        
   #http_resp.FIN = True 
   http_resp.ACK = True     
           
   http_resp.dstport = tcp_in.srcport
   http_resp.srcport = tcp_in.dstport
   http_resp.seq = tcp_in.ack
   http_resp.ack = tcp_in.seq +1
   http_resp.options = tcp_in.options
   http_resp.off = 8
   http_resp.win = tcp_in.win
       
    
   # Hook them up...
   ipp.payload = http_resp
   e.payload = ipp
       
       
   # Send it back to the input port
   msg = of.ofp_packet_out()
   msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
   msg.data = e.pack()
   msg.in_port = event.port
   event.connection.send(msg)       
Exemple #8
0
def flowlet_to_packet(flowlet):
    '''Translate an fs flowlet to a POX packet'''
    if hasattr(flowlet, "origpkt"):
        return getattr(flowlet, "origpkt")

    ident = flowlet.ident.key

    etherhdr = pktlib.ethernet()
    etherhdr.src = EthAddr(flowlet.srcmac)
    etherhdr.dst = EthAddr(flowlet.dstmac)
    etherhdr.type = pktlib.ethernet.IP_TYPE

    ipv4 = pktlib.ipv4() 
    ipv4.srcip = IPAddr(ident.srcip)
    ipv4.dstip = IPAddr(ident.dstip)
    ipv4.protocol = ident.ipproto
    ipv4.tos = flowlet.iptos
    iplen = flowlet.bytes / flowlet.pkts
    ipv4.iplen = iplen
    payloadlen = 0

    etherhdr.payload = ipv4

    if ident.ipproto == IPPROTO_ICMP:
        layer4 = pktlib.icmp()
        layer4.type = ident.dport >> 8
        layer4.code = ident.dport & 0x00FF
        payloadlen = max(iplen-28,0)
    elif ident.ipproto == IPPROTO_UDP:
        layer4 = pktlib.udp()
        layer4.srcport = ident.sport 
        layer4.dstport = ident.dport 
    elif ident.ipproto == IPPROTO_TCP:
        layer4 = pktlib.tcp()
        layer4.srcport = ident.sport 
        layer4.dstport = ident.dport 
        layer4.flags = flowlet.tcpflags
        layer4.off = 5
        payloadlen = max(iplen-40,0)
        layer4.tcplen = payloadlen
        layer4.payload = spack('{}x'.format(payloadlen))
    else:
        raise UnhandledPoxPacketFlowletTranslation("Can't translate IP protocol {} from flowlet to POX packet".format(fident.ipproto))
    ipv4.payload = layer4
    etherhdr.origflet = flowlet
    return etherhdr
Exemple #9
0
 def create_packet (e1,e2,i1,i2,t1,t2):
   e = pkt.ethernet(
       src = e1,
       dst = e2,
       type = pkt.ethernet.IP_TYPE)
   i = pkt.ipv4(
       srcip = i1,
       dstip = i2,
       protocol = pkt.ipv4.TCP_PROTOCOL)
   t = pkt.tcp(
       srcport = t1,
       dstport = t2,
       off = 5,
       win = 1)
   t.ACK = True
   i.payload = t
   e.payload = i
   return e
Exemple #10
0
 def create_packet(self, e1, e2, i1, i2, t1, t2):
     """
     Cria um pacote Ethernet.
     :param e1: Endereço de origem do pacote.
     :param e2: Endereço de destino do pacote.
     :param i1: IP de origem do pacote.
     :param i2: IP de destino do pacote.
     :param t1: Porta de origem do pacote.
     :param t2: Porta de destino do pacote.
     :return: Pacote Ethernet.
     """
     e = pkt.ethernet(src=e1, dst=e2, type=pkt.ethernet.IP_TYPE)
     i = pkt.ipv4(srcip=i1, dstip=i2, protocol=pkt.ipv4.TCP_PROTOCOL)
     t = pkt.tcp(srcport=t1, dstport=t2, off=5, win=1)
     t.ACK = True
     i.payload = t
     e.payload = i
     return e
Exemple #11
0
    def send_control_packet(self, packet, port, SYN, ACK, FIN):
        """
        Send control packet SYN, ACK, FIN according to specified flag
        """
        src_mac = packet.src
        ip_packet = packet.find('ipv4')
        tcpp = packet.find('tcp')

        key = str(ip_packet.srcip)+":"+str(tcpp.srcport)
        client = self.clients[key]
        conn_seq = client['seq']

        if tcpp.FIN:
            client['ack'] = client['ack'] + 1
        else:
            client['ack'] = tcpp.seq + tcpp.tcplen - tcpp.off * 4

        tcp_packet = pkt.tcp()
        tcp_packet.srcport = 11111
        tcp_packet.dstport = tcpp.srcport
        tcp_packet.seq = conn_seq
        tcp_packet.ack = client['ack']
        tcp_packet.off = 5
        tcp_packet.tcplen = pkt.tcp.MIN_LEN
        tcp_packet.win = 29000
        tcp_packet._setflag(tcp_packet.SYN_flag, SYN)
        tcp_packet._setflag(tcp_packet.ACK_flag, ACK)
        tcp_packet._setflag(tcp_packet.FIN_flag, FIN)

        ipv4_packet = pkt.ipv4()
        ipv4_packet.iplen = pkt.ipv4.MIN_LEN + len(tcp_packet)
        ipv4_packet.protocol = pkt.ipv4.TCP_PROTOCOL
        ipv4_packet.dstip = ip_packet.srcip
        ipv4_packet.srcip = self.ip
        ipv4_packet.set_payload(tcp_packet)

        eth_packet = pkt.ethernet()
        eth_packet.set_payload(ipv4_packet)
        eth_packet.dst = src_mac
        eth_packet.src = self.mac
        eth_packet.type = pkt.ethernet.IP_TYPE

        self.send_packet(eth_packet, port)
def tests():
    f = Firewall()
    ip = pktlib.tcp()
    ip.srcip = IPAddr("172.16.42.42")
    ip.dstip = IPAddr("192.128.42.42")
    ip.protocol = 17
    xudp = pktlib.udp()
    xudp.srcport = 80
    xudp.dstport = 53
    xudp.payload = "Hello, world"
    xudp.len = 8 + len(xudp.payload)
    ip.payload = xudp

    print len(ip) # print the length of the packet, just for fun

    assert(f.allow(ip) == True)

    time.sleep(0.5)
    f.update_token_buckets()
    def networkMatch(self, ruleObject, pkt):
        if (ruleObject.type == type(pkt)):
            if ruleObject.netMask != None:            
                pktsrc =  IPAddr(ruleObject.netMask.toUnsigned() & pkt.srcip.toUnsigned())
            else:
                pktsrc = pkt.srcip
            #checks if it is a network address or not
            if "/" in str(ruleObject.src):
                templist = []
                templist = ruleObject.src.split("/")
                rulesrc = IPAddr(templist[0])
            else:   
                rulesrc = ruleObject.src

            if "/" in str(ruleObject.dst):
                templist = []
                templist = ruleObject.dst.split("/")
                ruledst = IPAddr(templist[0])
            else:   
                ruledst = ruleObject.dst 

            #first type: ipv4/icmp
            if type(pkt) == type(pktlib.ipv4()) or type(pkt) == type(pktlib.icmp()):
                conditional1 = (ruleObject.type == type(pkt)), (rulesrc == pktsrc or rulesrc == 1), (ruledst == pkt.dstip or ruledst == 1)
                if ruleObject.ratelimit != None:

                    conditional1a = (ruleObject.type == type(pkt)), (rulesrc == pktsrc or rulesrc == 1), (ruledst == pkt.dstip or ruledst == 1), (ruleObject.bucket >= len(pkt.pack()))
                    return all(conditional1a)
                else:                    
                    return  all(conditional1)   
          
            #second type: udp/tcp
            if type(pkt) == type(pktlib.tcp()) or type(pkt) == type(pktlib.udp()):
                conditional2 = (ruleObject.type == type(pkt)), (rulesrc == pktsrc or rulesrc == 1), ((ruledst == 1) or (ruledst == pkt.dstip)), (int(ruleObject.srcport) == int(pkt.payload.srcport) or int(ruleObject.srcport) == 1), (int(ruleObject.dstport) == int(pkt.payload.dstport) or int(ruleObject.dstport) == 1)
          
                if ruleObject.ratelimit != None:
                    conditional2a = (ruleObject.type == type(pkt)), (rulesrc == pktsrc or rulesrc == 1), (ruledst == pkt.dstip or ruledst ==1), (int(ruleObject.srcport) == int(pkt.payload.srcport) or int(ruleObject.srcport) == 1), (int(ruleObject.dstport) == int(pkt.payload.dstport) or int(ruleObject.dstport) == 1), (ruleObject.bucket >= len(pkt.pack()))
                    return all(conditional2a)
                else:
                    return all(conditional2)
Exemple #14
0
    def pack_message(self, packet, client):
        """
        Repack a message packet according to different clients connection info
        """
        ip_packet = packet.find('ipv4')
        tcpp = packet.find('tcp')

        client_ip = client['ip']
        client_mac = client['mac']
        client_port = client['host_port']
        conn_seq = client['seq']
        conn_ack = client['ack']

        tcp_packet = pkt.tcp()
        tcp_packet.srcport = 11111
        tcp_packet.dstport = client_port
        tcp_packet.seq = conn_seq
        tcp_packet.ack = conn_ack
        tcp_packet.off = 5
        tcp_packet.tcplen = tcpp.tcplen
        tcp_packet.win = 29000
        tcp_packet._setflag(tcp_packet.SYN_flag,0)
        tcp_packet._setflag(tcp_packet.ACK_flag,1)
        tcp_packet._setflag(tcp_packet.PSH_flag,1)
        tcp_packet.payload = tcpp.payload

        ipv4_packet = pkt.ipv4()
        ipv4_packet.iplen = pkt.ipv4.MIN_LEN + len(tcp_packet)
        ipv4_packet.protocol = pkt.ipv4.TCP_PROTOCOL
        ipv4_packet.dstip = client_ip
        ipv4_packet.srcip = self.ip
        ipv4_packet.set_payload(tcp_packet)

        eth_packet = pkt.ethernet()
        eth_packet.set_payload(ipv4_packet)
        eth_packet.dst = client_mac
        eth_packet.src = self.mac
        eth_packet.type = pkt.ethernet.IP_TYPE

        return eth_packet
Exemple #15
0
    def new_connection(self, packet, in_port):
        """
        Send SYN/ACK to client, maintain connection info for new client
        """
        src_mac = packet.src
        ip_packet = packet.find('ipv4')
        tcpp = packet.find('tcp')

        tcp_packet = pkt.tcp()
        tcp_packet.srcport = 11111
        tcp_packet.dstport = tcpp.srcport
        tcp_packet.seq = 0
        tcp_packet.ack = tcpp.seq + 1
        tcp_packet.off = 10
        tcp_packet.win = 29000
        tcp_packet.tcplen = tcpp.tcplen
        tcp_packet._setflag(tcp_packet.SYN_flag,1)
        tcp_packet._setflag(tcp_packet.ACK_flag,1)
        tcp_packet.options = tcpp.options

        ipv4_packet = pkt.ipv4()
        ipv4_packet.iplen = pkt.ipv4.MIN_LEN + len(tcp_packet)
        ipv4_packet.protocol = pkt.ipv4.TCP_PROTOCOL
        ipv4_packet.dstip = ip_packet.srcip
        ipv4_packet.srcip = self.ip
        ipv4_packet.set_payload(tcp_packet)

        eth_packet = pkt.ethernet()
        eth_packet.set_payload(ipv4_packet)
        eth_packet.dst = src_mac
        eth_packet.src = self.mac
        eth_packet.type = pkt.ethernet.IP_TYPE

        client = {'ip':ip_packet.srcip, 'host_port':tcpp.srcport, 
                    'switch_port':in_port, 'mac':src_mac, 'seq':1, 'ack':1}
        key = str(ip_packet.srcip)+":"+str(tcpp.srcport)
        self.clients[key] = client
        self.send_packet(eth_packet, in_port)
Exemple #16
0
def tests():
     f = Firewall()
     
     ip = ipv4()
     ip.srcip = IPAddr("172.16.42.1")
     ip.dstip = IPAddr("10.0.0.2")
     ip.protocol = 17
     xudp = udp()
     xudp.srcport = 53
     xudp.dstport = 53
     xudp.payload = "Hello, world"
     xudp.len = 8 + len(xudp.payload)
     ip.payload = xudp
     print len(ip) # print the length of the packet, just for fun
     # you can name this method what ever you like, but you'll
     # need some method that gets periodically invoked for updating
     # token bucket state for any rules with rate limits
     f.update_token_buckets()
     # again, you can name your "checker" as you want, but the
     # idea here is that we call some method on the firewall to
     # test whether a given packet should be permitted or denied.
     assert(f.allow(ip) == True) #if you want to simulate a time delay and updating token buckets,
     #you can just call time.sleep and then update the buckets.
     ##time.sleep(0.5)
     ##f.update_token_buckets()
     
     ####
     
     #192.168.42.0/24, should be denied
     
     ip = ipv4()
     ip.srcip = IPAddr("192.168.42.1")
     ip.dstip = IPAddr("10.0.0.2")
     ip.protocol = 17
     xudp = udp()
     xudp.srcport = 53
     xudp.dstport = 53
     xudp.payload = "Hello, world, ye shall never know me"
     xudp.len = 8 + len(xudp.payload)
     ip.payload = xudp
     print len(ip) # print the length of the packet, just for fun
     assert(f.allow(ip) == False)
     
     #####
     #permit tcp src 172.16.42.0/24 srcport any dst any dstport 443
     
     ip = ipv4()
     ip.srcip = IPAddr("172.16.42.3")
     ip.dstip = IPAddr("192.168.0.2")
     ip.protocol = 6
     
     xtcp = tcp()
     xtcp.srcport = 666
     xtcp.dstport = 443
     xtcp.payload = "And so I shall pass from this world and into the next"
     xtcp.len = 8 + len(xtcp.payload)
     
     ip.payload = xtcp
     
     print len(ip) # print the length of the packet, just for fun
     
     assert(f.allow(ip) == True)
     
     ######
     
     ip = ipv4()
     ip.srcip = IPAddr("172.16.42.1")
     ip.dstip = IPAddr("10.0.0.2")
     ip.protocol = 6
     
     xtcp = tcp()
     xtcp.srcport = 53
     xtcp.dstport = 80
     xtcp.payload = "Hello, world"
     xtcp.len = 8 + len(xtcp.payload)
     
     ip.payload = xtcp
     
     print len(ip) # print the length of the packet, just for fun
     
     for i in range(400): #Trying to break the bucket. Works at a bit above 400
        if i % 100 == 0:
            print i/100            
        assert(f.allow(ip) == True)
        
     #####
     
     time.sleep(0.5)
     f.update_token_buckets()
Exemple #17
0
def send_redirect (event,packet,url): 
  
   # Check if TCP 
   tcp_in = packet.find("tcp")        
   
   
   #print "Send TCP Reset" 
   http_resp = pkt.tcp()
   payload = ""
       
   # Send HTTP response packet
   # Ethernet frame
   e = pkt.ethernet()
   e.src = packet.dst
   e.dst = packet.src
   e.type = e.IP_TYPE
       
   # Now create the IPv4 packet
   ipp = pkt.ipv4()
   ipp.protocol = ipp.TCP_PROTOCOL
       
   ipp.srcip = packet.find("ipv4").dstip
   ipp.dstip = packet.find("ipv4").srcip
   ipp.flags = packet.find("ipv4").flags
   
   # Now that we are established respond to any request with an ACK
   http_resp.ACK = True
   http_resp.dstport = tcp_in.srcport
   http_resp.srcport = tcp_in.dstport
   http_resp.seq = tcp_in.seq 
   # Needs to be seq_num + 
   http_resp.ack = tcp_in.seq + tcp_in.payload_len
   http_resp.options = tcp_in.options
   http_resp.off = 8
   http_resp.win = tcp_in.win
   
   # Hook them up...
   ipp.payload = http_resp
   e.payload = ipp
       
   # Send it back to the input port
   msg = of.ofp_packet_out()
   msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
   msg.data = e.pack()
   msg.in_port = event.port
   event.connection.send(msg)


   # Next lets send the HTTP redirect
   http_resp.PSH = True
   # ADD MAC AND IP TO URL
   url_f = url + "?mac=" + str(e.dst) + "&ip=" + str(ipp.dstip)
   http_resp.payload = get_redirect_payload(url_f)
         
   #PRINT "GET TOTAL SIZE %D" % LEN(TCP_IN)
   print "GET PAYLOAD SIZE %d" % tcp_in.payload_len
   # Hook them up...
   ipp.payload = http_resp
   e.payload = ipp
       
   # Send it back to the input port
   msg = of.ofp_packet_out()
   msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
   msg.data = e.pack()
   msg.in_port = event.port
   event.connection.send(msg)
Exemple #18
0
    def _handle_openflow_PacketIn(self, event):
        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed
        log.warning("Inho #5168 : %s %s ", type(dpid), dpid)
        if not packet.parsed:
            log.warning("%i %i ignoring unparsed packet", dpid, inport)
            return

        if dpid not in self.arpTable:
            # New switch -- create an empty table
            self.arpTable[dpid] = {}
            for fake in self.fakeways:
                self.arpTable[dpid][IPAddr(fake)] = Entry(
                    of.OFPP_NONE, dpid_to_mac(dpid))

        if packet.type == ethernet.LLDP_TYPE:
            # Ignore LLDP packets
            return

        if isinstance(packet.next, ipv4):
            log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip,
                      packet.next.dstip)

            # Send any waiting packets...
            self._send_lost_buffers(dpid, packet.next.srcip, packet.src,
                                    inport)

            # Learn or update port/MAC info
            if packet.next.srcip in self.arpTable[dpid]:
                if self.arpTable[dpid][packet.next.srcip] != (inport,
                                                              packet.src):
                    log.info("%i %i RE-learned %s", dpid, inport,
                             packet.next.srcip)
                    if self.wide:
                        # Make sure we don't have any entries with the old info...
                        msg = of.ofp_flow_mod(command=of.OFPFC_DELETE)
                        msg.match.nw_dst = packet.next.srcip
                        msg.match.dl_type = ethernet.IP_TYPE
                        event.connection.send(msg)
            else:
                log.debug("%i %i learned %s", dpid, inport, packet.next.srcip)
            self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)

            # Try to forward
            dstaddr = packet.next.dstip
            if dstaddr not in self.arpTable[dpid]:
                if packet.next.srcip == IPAddr("10.0.0.1"):
                    self.arpTable[dpid][packet.next.dstip] = Entry(
                        inport, packet.src)
                    self.arpTable[dpid][packet.next.dstip].mac = EthAddr(
                        "32:d5:a3:be:19:77")
                else:
                    self.arpTable[dpid][packet.next.dstip] = Entry(
                        inport, packet.src)
                    self.arpTable[dpid][packet.next.dstip].mac = EthAddr(
                        "08:00:27:2a:87:c3")

            if packet.next.protocol == ipv4.TCP_PROTOCOL:
                if packet.next.dstip == "10.0.0.1":
                    e = pkt.ethernet()
                    e.src = EthAddr(packet.src)
                    e.dst = self.arpTable[dpid][dstaddr].mac
                    e.type = e.IP_TYPE
                    tcpp = pkt.tcp()
                    tcpp.srcport = packet.next.payload.srcport  #packet.next.payload = tcpp, packet.next = ip, packet = E
                    tcpp.dstport = packet.next.payload.dstport
                    tcpp.seq = packet.next.payload.seq
                    tcpp.ack = packet.next.payload.ack
                    tcpp.win = 29200
                    tcpp.SYN = True  #send SYN
                    tcpp.ACK = False

                    tcp = pkt.ipv4()
                    tcp.protocol = tcp.TCP_PROTOCOL
                    tcp.srcip = packet.next.srcip
                    tcp.dstip = packet.next.dstip
                    tcp.payload = tcpp

                    e.payload = tcp
                    msg = of.ofp_packet_out()
                    msg.data = e.pack()
                    msg.actions.append(
                        of.ofp_action_output(port=of.OFPP_IN_PORT))
                    msg.in_port = inport
                    event.connection.send(msg)

                    print(e.dst)
                    print(packet.next.dstip)

            if packet.next.protocol == ipv4.ICMP_PROTOCOL:
                e = pkt.ethernet()
                e.src = self.arpTable[dpid][dstaddr].mac
                e.dst = EthAddr(packet.src)
                e.type = e.IP_TYPE
                ipp = pkt.ipv4()
                ipp.protocol = ipp.ICMP_PROTOCOL
                ipp.srcip = packet.next.dstip
                print(ipp.srcip)
                ipp.dstip = packet.next.srcip
                icmp = pkt.icmp()
                icmp.type = pkt.ICMP.TYPE_ECHO_REPLY
                icmp.payload = packet.next.payload.payload  #copy the ping payload of the packet that they receive
                ipp.payload = icmp
                e.payload = ipp
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))
                msg.in_port = inport
                event.connection.send(msg)
                return

            if packet.next.protocol == ipv4.TCP_PROTOCOL and packet.next.dstip != "10.0.0.1":

                if packet.next.payload.SYN and not packet.next.payload.ACK:  #this is to send SYN, ACK
                    print "SYN packet", packet.next.payload

                    e = pkt.ethernet()
                    e.src = self.arpTable[dpid][dstaddr].mac
                    e.dst = EthAddr(packet.src)
                    e.type = e.IP_TYPE
                    tcpp = pkt.tcp()
                    tcpp.srcport = packet.next.payload.dstport  #packet.next.payload = tcpp, packet.next = ip, packet = E
                    tcpp.dstport = packet.next.payload.srcport
                    tcpp.seq = 0
                    tcpp.ack = packet.next.payload.seq + 1
                    tcpp.win = 29200
                    tcpp.SYN = True  #send SYN
                    tcpp.ACK = True  #send ACK

                    tcp = pkt.ipv4()
                    tcp.protocol = tcp.TCP_PROTOCOL
                    tcp.srcip = packet.next.dstip
                    tcp.dstip = packet.next.srcip
                    tcp.payload = tcpp

                    e.payload = tcp
                    msg = of.ofp_packet_out()
                    msg.data = e.pack()
                    msg.actions.append(
                        of.ofp_action_output(port=of.OFPP_IN_PORT))
                    msg.in_port = inport
                    event.connection.send(msg)

                    time.sleep(0.15)

                    e = pkt2.ethernet()
                    e.src = self.arpTable[dpid][dstaddr].mac
                    e.dst = EthAddr(packet.src)
                    e.type = e.IP_TYPE
                    tcpp = pkt2.tcp()
                    tcpp.srcport = packet.next.payload.dstport
                    tcpp.dstport = packet.next.payload.srcport
                    #print(packet.next.payload.ack)
                    tcpp.seq = 1
                    tcpp.ack = packet.next.payload.seq + 127
                    tcpp.win = 29200
                    tcpp.PSH = True  #send PSH
                    tcpp.ACK = True  #send ACK
                    tcpp.payload = makeMessage(
                        magic, "version",
                        makeVersionPayload(str(packet.next.dstip),
                                           str(packet.next.srcip)))

                    tcp = pkt2.ipv4()
                    tcp.protocol = tcp.TCP_PROTOCOL
                    tcp.srcip = packet.next.dstip
                    tcp.dstip = packet.next.srcip
                    tcp.payload = tcpp
                    e.payload = tcp

                    print "*****"
                    msg = of.ofp_packet_out()
                    msg.data = e.pack()
                    msg.actions.append(
                        of.ofp_action_output(port=of.OFPP_IN_PORT))
                    msg.in_port = inport
                    event.connection.send(msg)
                    return

                # if not packet.next.payload.SYN and packet.next.payload.ACK:
                #   print "ACK packet", packet.next.payload
                #   e = pkt.ethernet()
                #   e.src = self.arpTable[dpid][dstaddr].mac
                #   e.dst = EthAddr(packet.src)
                #   e.type = e.IP_TYPE
                #   tcpp = pkt.tcp()
                #   tcpp.srcport = packet.next.payload.dstport
                #   tcpp.dstport = packet.next.payload.srcport
                #   # tcpp.seq = 1 # will be random
                #   tcpp.ack = packet.next.payload.ack+1
                #   # tcpp.SYN = True
                #   tcpp.ACK = True

                #   tcp = pkt.ipv4()
                #   tcp.protocol = tcp.TCP_PROTOCOL
                #   tcp.srcip = packet.next.dstip
                #   tcp.dstip = packet.next.srcip
                #   tcp.payload = tcpp

                #   e.payload = tcp
                #   msg = of.ofp_packet_out()
                #   msg.data = e.pack()
                #   msg.actions.append(of.ofp_action_output(port =
                #                                           of.OFPP_IN_PORT))
                #   msg.in_port = inport
                #   event.connection.send(msg)
                #   return
                else:
                    print "Not SYN", packet.next.payload
            elif self.arp_for_unknowns:
                # We don't know this destination.
                # First, we track this buffer so that we can try to resend it later
                # if we learn the destination, second we ARP for the destination,
                # which should ultimately result in it responding and us learning
                # where it is

                # Add to tracked buffers
                if (dpid, dstaddr) not in self.lost_buffers:
                    self.lost_buffers[(dpid, dstaddr)] = []
                bucket = self.lost_buffers[(dpid, dstaddr)]
                entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id,
                         inport)
                bucket.append(entry)
                while len(bucket) > MAX_BUFFERED_PER_IP:
                    del bucket[0]

                # Expire things from our outstanding ARP list...
                self.outstanding_arps = {
                    k: v
                    for k, v in self.outstanding_arps.iteritems()
                    if v > time.time()
                }

                # Check if we've already ARPed recently
                if (dpid, dstaddr) in self.outstanding_arps:
                    # Oop, we've already done this one recently.
                    return

                # And ARP...
                self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4

                r = arp()
                r.hwtype = r.HW_TYPE_ETHERNET
                r.prototype = r.PROTO_TYPE_IP
                r.hwlen = 6
                r.protolen = r.protolen
                r.opcode = r.REQUEST
                r.hwdst = ETHER_BROADCAST
                r.protodst = dstaddr
                r.hwsrc = packet.src
                r.protosrc = packet.next.srcip
                e = ethernet(type=ethernet.ARP_TYPE,
                             src=packet.src,
                             dst=ETHER_BROADCAST)
                e.set_payload(r)
                log.debug("%i %i ARPing for %s on behalf of %s" %
                          (dpid, inport, r.protodst, r.protosrc))
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
                msg.in_port = inport
                event.connection.send(msg)

        elif isinstance(packet.next, arp):
            a = packet.next
            log.debug("%i %i ARP %s %s => %s", dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst)

            if a.protosrc == IPAddr("10.0.0.1"):
                if a.opcode == arp.REQUEST:

                    if a.protodst not in self.arpTable[dpid]:
                        self.arpTable[dpid][a.protodst] = Entry(
                            inport, packet.src)
                        self.arpTable[dpid][a.protodst].mac = EthAddr(
                            "32:d5:a3:be:19:77")

                    r = arp()
                    r.hwtype = a.hwtype
                    r.prototype = a.prototype
                    r.hwlen = a.hwlen
                    r.protolen = a.protolen
                    r.opcode = arp.REPLY
                    r.hwdst = a.hwsrc
                    r.protodst = a.protosrc
                    r.protosrc = a.protodst
                    r.hwsrc = self.arpTable[dpid][a.protodst].mac
                    e = ethernet(type=packet.type,
                                 src=dpid_to_mac(dpid),
                                 dst=a.hwsrc)
                    e.set_payload(r)
                    log.debug("%i %i answering ARP for %s: %s" %
                              (dpid, inport, r.protosrc, r.hwsrc))
                    msg = of.ofp_packet_out()
                    msg.data = e.pack()
                    msg.actions.append(
                        of.ofp_action_output(port=of.OFPP_IN_PORT))
                    msg.in_port = inport
                    event.connection.send(msg)
                    return

            # Didn't know how to answer or otherwise handle this ARP, so just flood it
            log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst))

            msg = of.ofp_packet_out(
                in_port=inport,
                data=event.ofp,
                action=of.ofp_action_output(port=of.OFPP_FLOOD))
            event.connection.send(msg)