Ejemplo n.º 1
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())
Ejemplo n.º 2
0
    def reply(cls, event, msg):
        orig = event.parsed.find('dhcp')
        broadcast = (orig.flags & orig.BROADCAST_FLAG) != 0
        msg.op = msg.BOOTREPLY
        msg.chaddr = event.parsed.src
        msg.htype = 1
        msg.hlen = 6
        msg.xid = orig.xid
        msg.add_option(pkt.DHCP.DHCPServerIdentifierOption(cls.server_addr))

        ethp = pkt.ethernet(src=EthAddr('02:00:00:00:00:24'),
                            dst=event.parsed.src)
        ethp.type = pkt.ethernet.IP_TYPE
        ipp = pkt.ipv4(srcip=cls.server_addr)
        ipp.dstip = event.parsed.find('ipv4').srcip
        if broadcast:
            ipp.dstip = IPAddr('255.255.255.255')
            eth.dst = pkt.ETHERNET.ETHER_BROADCAST
        ipp.protocol = ipp.UDP_PROTOCOL
        udpp = pkt.udp()
        udpp.srcport = pkt.dhcp.SERVER_PORT
        udpp.dstport = pkt.dhcp.CLIENT_PORT
        udpp.payload = msg
        ipp.payload = udpp
        ethp.payload = ipp
        po = of.ofp_packet_out(data=ethp.pack())
        po.actions.append(of.ofp_action_output(port=event.port))
        event.connection.send(po)
Ejemplo n.º 3
0
    def reply(self, event, subnet, msg):

        # fill out the rest of the DHCP packet
        orig = event.parsed.find('dhcp')
        broadcast = (orig.flags & orig.BROADCAST_FLAG) != 0
        msg.op = msg.BOOTREPLY
        msg.chaddr = event.parsed.src
        msg.htype = 1
        msg.hlen = 6
        msg.xid = orig.xid
        msg.add_option(pkt.DHCP.DHCPServerIdentifierOption(subnet.server.addr))

        # create ethernet header
        ethp = pkt.ethernet(src=ip_for_event(event), dst=event.parsed.src)
        ethp.type = pkt.ethernet.IP_TYPE
        ipp = pkt.ipv4(srcip=subnet.server.addr)
        ipp.dstip = event.parsed.find('ipv4').srcip
        if broadcast:
            ipp.dstip = IP_BROADCAST
            ethp.dst = pkt.ETHERNET.ETHER_BROADCAST

        # create UDP header
        ipp.protocol = ipp.UDP_PROTOCOL
        udpp = pkt.udp()
        udpp.srcport = pkt.dhcp.SERVER_PORT
        udpp.dstport = pkt.dhcp.CLIENT_PORT

        # encapsulate and reply to host
        udpp.payload = msg
        ipp.payload = udpp
        ethp.payload = ipp
        po = of.ofp_packet_out(data=ethp.pack())
        po.actions.append(of.ofp_action_output(port=event.port))
        event.connection.send(po)
Ejemplo n.º 4
0
 def create_ipv4_dns(self, req_packet,  dns_rep):
     ether_req = req_packet.find('ethernet')
     udp_req = req_packet.find('udp')
     ipv4_req = req_packet.find('ipv4')
     if ether_req is None or udp_req is None or ipv4_req is None:
             return
     ether_rep = pkt.ethernet(ether_req.raw) #reply ethernet
     udp_rep = pkt.udp(udp_req.raw)  #reply upd pkt
     ipv4_rep = pkt.ipv4(ipv4_req.raw)       #reply ipv4 pkt
     #swap MACs
     ether_rep.dst = ether_req.src
     ether_rep.src = ether_req.dst
     ether_rep.type = pkt.ethernet.IP_TYPE
     #swap udp ports.
     udp_rep.dstport = udp_req.srcport
     udp_rep.srcport = 53
     #swap ipaddresses.
     ipv4_rep.srcip = ipv4_req.dstip
     ipv4_rep.dstip = ipv4_req.srcip
     #ipv4_rep.srcport = ipv4_req.dstport
     #ipv4_rep.dstport = ipv4_req.srcport
     #put payloads
     udp_rep.payload = dns_rep
     ipv4_rep.payload = udp_rep
     ether_rep.payload = ipv4_rep
     return ether_rep
Ejemplo n.º 5
0
  def reply (self, event, msg):
    orig = event.parsed.find('dhcp')
    broadcast = (orig.flags & orig.BROADCAST_FLAG) != 0
    msg.op = msg.BOOTREPLY
    msg.chaddr = event.parsed.src
    msg.htype = 1
    msg.hlen = 6
    msg.xid = orig.xid
    msg.add_option(pkt.DHCP.DHCPServerIdentifierOption(self.ip_addr))

    ethp = pkt.ethernet(src=ip_for_event(event),dst=event.parsed.src)
    ethp.type = pkt.ethernet.IP_TYPE
    ipp = pkt.ipv4(srcip = self.ip_addr)
    ipp.dstip = event.parsed.find('ipv4').srcip
    if broadcast:
      ipp.dstip = IP_BROADCAST
      ethp.dst = pkt.ETHERNET.ETHER_BROADCAST
    ipp.protocol = ipp.UDP_PROTOCOL
    udpp = pkt.udp()
    udpp.srcport = pkt.dhcp.SERVER_PORT
    udpp.dstport = pkt.dhcp.CLIENT_PORT
    udpp.payload = msg
    ipp.payload = udpp
    ethp.payload = ipp
    po = of.ofp_packet_out(data=ethp.pack())
    po.actions.append(of.ofp_action_output(port=event.port))
    event.connection.send(po)
Ejemplo n.º 6
0
 def send_udp_packet_out(self, conn, payload, tp_src, tp_dst,src_ip, dst_ip,
                         src_mac, dst_mac, fw_port = of.OFPP_ALL):
   msg = of.ofp_packet_out(in_port=of.OFPP_NONE)
   msg.buffer_id = None
   #Make the udp packet
   udpp = pkt.udp()
   udpp.srcport = tp_src
   udpp.dstport = tp_dst
   udpp.payload = payload
   #Make the IP packet around it
   ipp = pkt.ipv4()
   ipp.protocol = ipp.UDP_PROTOCOL
   ipp.srcip = IPAddr(src_ip)
   ipp.dstip = IPAddr(dst_ip)
   # Ethernet around that...
   ethp = pkt.ethernet()
   ethp.src = EthAddr(src_mac)
   ethp.dst = EthAddr(dst_mac)
   ethp.type = ethp.IP_TYPE
   # Hook them up...
   ipp.payload = udpp
   ethp.payload = ipp
   # Send it to the sw
   msg.actions.append(of.ofp_action_output(port = fw_port))
   msg.data = ethp.pack()
   #show msg before sending
   """
   print '*******************'
   print 'msg.show(): ',msg.show()
   print '*******************'
   """
   print "self.send_udp_packet_out; sw%s and fw_port:%s" %(conn.dpid, fw_port)
   conn.send(msg)
Ejemplo n.º 7
0
 def send_udp_packet_out(self, conn, payload, tp_src, tp_dst,src_ip, dst_ip, 
                         src_mac, dst_mac, fw_port = of.OFPP_ALL):
   msg = of.ofp_packet_out(in_port=of.OFPP_NONE)
   msg.buffer_id = None
   #Make the udp packet
   udpp = pkt.udp()
   udpp.srcport = tp_src
   udpp.dstport = tp_dst
   udpp.payload = payload
   #Make the IP packet around it
   ipp = pkt.ipv4()
   ipp.protocol = ipp.UDP_PROTOCOL
   ipp.srcip = IPAddr(src_ip)
   ipp.dstip = IPAddr(dst_ip)
   # Ethernet around that...
   ethp = pkt.ethernet()
   ethp.src = EthAddr(src_mac)
   ethp.dst = EthAddr(dst_mac)
   ethp.type = ethp.IP_TYPE
   # Hook them up...
   ipp.payload = udpp
   ethp.payload = ipp
   # Send it to the sw
   msg.actions.append(of.ofp_action_output(port = fw_port))
   msg.data = ethp.pack()
   #show msg before sending
   """
   print '*******************'
   print 'msg.show(): ',msg.show()
   print '*******************'
   """
   #print "send_udp_packet_out; sw%s and fw_port:%s" %(conn.dpid, fw_port)
   conn.send(msg)
Ejemplo n.º 8
0
    def send_updates(self, force):
        conn = self._conn
        if not conn: return
        direct = self._get_port_ip_map()

        out = []

        for port, dests in direct.items():
            if port not in conn.ports:
                self.log.warn("No such port %s", port)
                continue
            if port not in self._ports:
                # We aren't configured to do RIP on this port
                continue
            responses = self.get_responses(dests, force=force)
            #self.log.debug("Sending %s RIP packets via %s", len(responses), iface)
            for r in responses:
                udpp = pkt.udp()
                udpp.payload = r
                udpp.dstport = RIP.RIP_PORT
                udpp.srcport = RIP.RIP_PORT

                ipp = pkt.ipv4()
                ipp.payload = udpp
                ipp.dstip = RIP.RIP2_ADDRESS
                ipp.protocol = ipp.UDP_PROTOCOL
                # We may have multiple IPs on this interface.  Should we send an
                # advertisement from each one?  The RIP spec isn't very clear.
                # Assume no, and we want to just send one.  So just pick a source
                # IP from the ones available.
                ipp.srcip = self._ports[port].any_ip

                ethp = pkt.ethernet()
                ethp.payload = ipp
                ethp.dst = RIP.RIP2_ADDRESS.multicast_ethernet_address
                ethp.type = ethp.IP_TYPE
                src = conn.ports.get(port)
                if src is None:
                    self.log.warn("Missing port %s", port)
                    continue
                ethp.src = src.hw_addr

                msg = of.ofp_packet_out()
                msg.actions.append(of.ofp_action_output(port=port))
                msg.data = ethp.pack()
                out.append(msg.pack())

        #self.log.debug("Sending %s updates", len(out))
        if out: conn.send(b''.join(out))

        self._mark_all_clean()
Ejemplo n.º 9
0
    def parse_dhcp(self, dhcp_packet, event):
        print "dhcp packet handler"
        if len(dhcp_packet.options) == 0:
            return
        if pkt.dhcp.HOST_NAME_OPT in dhcp_packet.options:
            self.hostname = dhcp_packet.options[pkt.dhcp.HOST_NAME_OPT].data
        if pkt.dhcp.REQUEST_IP_OPT in dhcp_packet.options:
            self.requestedIp = dhcp_packet.options[pkt.dhcp.REQUEST_IP_OPT].addr
        if pkt.dhcp.MSG_TYPE_OPT in dhcp_packet.options:
            mt = dhcp_packet.options[pkt.dhcp.MSG_TYPE_OPT]
            self.dhcp_msg_type = mt
            if mt == pkt.dhcp.INFORM_MSG:
                return
            elif mt == pkt.dhcp.DECLINE_MSG:
                return
        ip = self.select_ip(dhcp_packet.chaddr, mt)

        if mt == pkt.dhcp.RELEASE_MSG:
            #find mapping and delete it
            self.insert_couchdb("del", ip, dhcp_packet.chaddr, None)
            return

        reply_msg_type = pkt.dhcp.OFFER_MSG if self.dhcp_msg_type.type == pkt.dhcp.DISCOVER_MSG else pkt.dhcp.ACK_MSG
        if self.requestedIp != 0 and self.dhcp_msg_type == pkt.dhcp.REQUEST_MSG and self.requestedIp != int(ip):
            reply_msg_type = pkt.dhcp.nak
            ip = self.requestedIp
            print "not allowed that address"
        reply = self.generate_dhcp_reply(dhcp_packet, ip, reply_msg_type, MAX_ROUTABLE_LEASE)
        if reply_msg_type == pkt.dhcp.ACK_MSG:
            self.add_addr(str(self.increment_ip(ip)))
            self.insert_couchdb("add", ip, dhcp_packet.chaddr, self.hostname)

        eth = pkt.ethernet(src=ip_for_event(event), dst=event.parsed.src)
        eth.type = pkt.ethernet.IP_TYPE

        ipp = pkt.ipv4(srcip=self.increment_ip(ip))
        ipp.dstip = event.parsed.find('ipv4').srcip
        broadcast = (dhcp_packet.ciaddr == 0)
        if broadcast:
            ipp.dstip = IP_BROADCAST
            eth.dst = pkt.ETHERNET.ETHER_BROADCAST
        ipp.protocol = ipp.UDP_PROTOCOL
        udpp = pkt.udp()
        udpp.srcport = pkt.dhcp.SERVER_PORT
        udpp.dstport = pkt.dhcp.CLIENT_PORT
        udpp.payload = reply
        ipp.payload = udpp
        eth.payload = ipp
        msg = of.ofp_packet_out(data=eth.pack())
        msg.actions.append(of.ofp_action_output(port=event.port))
        event.connection.send(msg)
Ejemplo n.º 10
0
    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)
Ejemplo n.º 11
0
 def _send_dhcp (self, msg):
   ethp = pkt.ethernet(src=self.port_eth, dst=pkt.ETHER_BROADCAST)
   ethp.type = pkt.ethernet.IP_TYPE
   ipp = pkt.ipv4()
   ipp.srcip = pkt.IP_ANY #NOTE: If rebinding, use existing local IP?
   ipp.dstip = pkt.IP_BROADCAST
   ipp.protocol = ipp.UDP_PROTOCOL
   udpp = pkt.udp()
   udpp.srcport = pkt.dhcp.CLIENT_PORT
   udpp.dstport = pkt.dhcp.SERVER_PORT
   udpp.payload = msg
   ipp.payload = udpp
   ethp.payload = ipp
   self._send_data(ethp.pack())
  def handle_dns_packet(self, packet, event):
      dns_name = str(packet.questions[0].name)
      dns_type = packet.questions[0].qtype
      dns_class = packet.questions[0].qclass
      log.info("name " + dns_name + " type " + pkt.rrtype_to_str[dns_type] + " class " + pkt.rrclass_to_str[dns_class])
      log.info("Len " + str(len(packet.questions)))

      dns_reply = dns()
      dns_reply.qr = True
      dns_reply.rd = True
      dns_reply.ra = True

      answ = dns.rr("www.google.com",1,1,3600,4,IPAddr("1.1.1.1"))

      dns_reply.answers.append(answ)
      dns_reply.questions = packet.questions
      dns_reply.id = packet.id
      #dns_reply.total_questions = packet.total_questions
      #dns_reply.total_answers = 1

      udp_req = event.parsed.find("udp")
      udp_reply = udp()
      udp_reply.srcport = udp_req.srcport
      udp_reply.dstport = udp_req.dstport
      udp_reply.len = len(dns_reply) + udp_reply.MIN_LEN
      udp_reply.set_payload(dns_reply)

      ip_reply = ipv4()
      ip_req = event.parsed.find("ipv4")
      reqSrc = ip_req.dstip
      reqDst = ip_req.srcip
      ip_reply = ip_req
      ip_reply.srcip = reqDst
      ip_reply.dstip = reqSrc
      ip_reply.set_payload(udp_reply)

      eth_reply = ethernet()
      eth_reply.type = ethernet.IP_TYPE
      eth_reply.dst = EthAddr("00:00:00:00:00:02")
      eth_reply.src = EthAddr("00:00:00:00:00:01")
      eth_reply.set_payload(ip_reply)

      msg = of.ofp_packet_out()
      msg.data = eth_reply.pack()
      msg.actions.append(of.ofp_action_output(port = 2))
      msg.in_port = event.port
      self.connection.send(msg)
      log.info("send DNS response...")
Ejemplo n.º 13
0
 def _send_dhcp (self, msg):
   ethp = pkt.ethernet(src=self.port_eth, dst=pkt.ETHER_BROADCAST)
   ethp.type = pkt.ethernet.IP_TYPE
   ipp = pkt.ipv4()
   ipp.srcip = pkt.IP_ANY #NOTE: If rebinding, use existing local IP?
   ipp.dstip = pkt.IP_BROADCAST
   ipp.protocol = ipp.UDP_PROTOCOL
   udpp = pkt.udp()
   udpp.srcport = pkt.dhcp.CLIENT_PORT
   udpp.dstport = pkt.dhcp.SERVER_PORT
   udpp.payload = msg
   ipp.payload = udpp
   ethp.payload = ipp
   po = of.ofp_packet_out(data=ethp.pack())
   po.actions.append(of.ofp_action_output(port=self.portno))
   self._con.send(po)
Ejemplo n.º 14
0
 def _send_dhcp(self, msg):
     ethp = pkt.ethernet(src=self.port_eth, dst=pkt.ETHER_BROADCAST)
     ethp.type = pkt.ethernet.IP_TYPE
     ipp = pkt.ipv4()
     ipp.srcip = pkt.IP_ANY  #NOTE: If rebinding, use existing local IP?
     ipp.dstip = pkt.IP_BROADCAST
     ipp.protocol = ipp.UDP_PROTOCOL
     udpp = pkt.udp()
     udpp.srcport = pkt.dhcp.CLIENT_PORT
     udpp.dstport = pkt.dhcp.SERVER_PORT
     udpp.payload = msg
     ipp.payload = udpp
     ethp.payload = ipp
     po = of.ofp_packet_out(data=ethp.pack())
     po.actions.append(of.ofp_action_output(port=self.portno))
     self._con.send(po)
Ejemplo n.º 15
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
Ejemplo n.º 16
0
  def _handle_PacketIn (self, event):
    if not event.parsed:
      return
    q_dns = event.parsed.find('dns')
    if q_dns is None:
      return
    if not event.parsed.find('ipv4'):
      return

    log.debug(q_dns)
    r_dns = pkt_dns()
    r_dns.qr = True
    r_dns.aa = True
    for q in q_dns.questions:
      if rrclass_to_str[q.qclass] != "IN":
        # Internet only
        continue 
      log.debug('q: (%s,%s)' % (q.name, q.qtype))
      qtype = rrtype_to_str.get(q.qtype, 'unknown')
      attr = getattr(self, "_answer_" + qtype, self._answer_unknown)
      port, rr = attr(q)
      if port:
        r_dns.answers.append(rr)
        r_mac_src = EthAddr(port.mac)
        r_ip_src = IPAddr(port.ip)

    if not r_dns.answers:
      log.debug('cannot answer questions')
      return
    q_eth = event.parsed.find('ethernet')
    q_ip = event.parsed.find('ipv4')
    q_udp = event.parsed.find('udp')
    r_eth = pkt.ethernet(src=r_mac_src, dst=q_eth.dst)
    r_eth.type = pkt.ethernet.IP_TYPE
    r_ip = pkt.ipv4(srcip=r_ip_src, dstip=q_ip.dstip)
    r_ip.protocol = r_ip.UDP_PROTOCOL
    r_udp = pkt.udp()
    r_udp.srcport = q_udp.dstport
    r_udp.dstport = q_udp.srcport
    r_udp.payload = r_dns
    r_ip.payload = r_udp
    r_eth.payload = r_ip
    r_pkt = of.ofp_packet_out(data=r_eth.pack())
    r_pkt.actions.append(of.ofp_action_output(port=event.port))
    log.debug('response: %s' % r_dns)
    event.connection.send(r_pkt)
Ejemplo n.º 17
0
  def _handle_PacketIn (self, event):
    if not event.parsed:
      return
    q_dns = event.parsed.find('dns')
    if q_dns is None:
      return
    if not event.parsed.find('ipv4'):
      return

    log.debug(q_dns)
    r_dns = pkt_dns()
    r_dns.qr = True
    r_dns.aa = True
    for q in q_dns.questions:
      if rrclass_to_str[q.qclass] != "IN":
        # Internet only
        continue 
      log.debug('q: (%s,%s)' % (q.name, q.qtype))
      attr = getattr(self, "_answer_" + rrtype_to_str[q.qtype],
                     self._answer_unknown)
      port, rr = attr(q)
      if port:
        r_dns.answers.append(rr)
        r_mac_src = EthAddr(port.mac)
        r_ip_src = IPAddr(port.ip)

    if not r_dns.answers:
      log.debug('cannot answer questions')
      return
    q_eth = event.parsed.find('ethernet')
    q_ip = event.parsed.find('ipv4')
    q_udp = event.parsed.find('udp')
    r_eth = pkt.ethernet(src=r_mac_src, dst=q_eth.dst)
    r_eth.type = pkt.ethernet.IP_TYPE
    r_ip = pkt.ipv4(srcip=r_ip_src, dstip=q_ip.dstip)
    r_ip.protocol = r_ip.UDP_PROTOCOL
    r_udp = pkt.udp()
    r_udp.srcport = q_udp.dstport
    r_udp.dstport = q_udp.srcport
    r_udp.payload = r_dns
    r_ip.payload = r_udp
    r_eth.payload = r_ip
    r_pkt = of.ofp_packet_out(data=r_eth.pack())
    r_pkt.actions.append(of.ofp_action_output(port=event.port))
    log.debug('response: %s' % r_dns)
    event.connection.send(r_pkt)
Ejemplo n.º 18
0
def tests():
    f = Firewall()

    ip1 = ipv4()
    ip1.srcip = IPAddr("172.16.42.1")
    ip1.dstip = IPAddr("10.0.0.2")
    ip1.protocol = 17
    xudp1 = udp()
    xudp1.srcport = 53
    xudp1.dstport = 53
    xudp1.payload = "Hello, world"
    xudp1.len = 8 + len(xudp1.payload)
    ip1.payload = xudp1

    ip2 = ipv4()
    ip2.srcip = IPAddr("172.16.40.1")
    ip2.dstip = IPAddr("10.0.0.1")
    ip2.protocol = ip2.ICMP_PROTOCOL
    icmppkt = icmp()
    icmppkt.type = pktlib.TYPE_ECHO_REQUEST
    ping = pktlib.echo()
    ping.id = 5
    ping.seq = 10
    icmppkt.payload = ping
    ip2.payload = icmppkt

    ip3 = ipv4()
    ip3.srcip = IPAddr("172.16.38.0")
    ip3.dstip = IPAddr("10.0.0.5")
    ip3.protocol = ip2.ICMP_PROTOCOL
    icmppkt = icmp()
    icmppkt.type = pktlib.TYPE_ECHO_REQUEST
    ping = pktlib.echo()
    ping.id = 5
    ping.seq = 10
    icmppkt.payload = ping
    ip3.payload = icmppkt

    i=0
    while i<10:
        print "+"*70
        f.update_token_buckets()
        f.allow(ip2)
        f.allow(ip3)
        time.sleep(0.5)
        i+=1
Ejemplo n.º 19
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
Ejemplo n.º 20
0
    def broadcast_routing_table(self):
        rip_msg = pkt.rip()
        rip_msg.version = 2
        rip_msg.command = pkt.RIP_RESPONSE
        for entry in self.routing_table:
            rip_entry = pkt.RIPEntry()
            rip_entry.ip = adr.IPAddr(entry.split("/")[0])
            rip_entry.netmask = int(entry.split("/")[1])
            rip_entry.metric = self.routing_table[entry][-1]
            rip_msg.entries.append(rip_entry)
            if entry[1] != forever_ttl:
                --self.routing_table[entry][1]
                if self.routing_table[entry][1] == 0:
                    del self.routing_table[entry]

        udp = pkt.udp()
        udp.srcport = 520
        udp.dstport = 520
        # log.debug( "Created rip msg of len: %d", len(rip_msg) )
        udp.len = len(rip_msg)
        udp.payload = rip_msg

        ipv4 = pkt.ipv4()
        ipv4.protocol = pkt.ipv4.UDP_PROTOCOL
        ipv4.srcip = pkt.IP_ANY
        ipv4.dstip = pkt.rip.RIP2_ADDRESS
        ipv4.payload = udp

        ether = pkt.ethernet()
        ether.type = pkt.ethernet.IP_TYPE
        ether.dst = adr.EthAddr('ff:ff:ff:ff:ff:ff')
        ether.payload = ipv4
        for port in self.port_to_hwaddr.keys()[0:-1]:
            ether.src = self.port_to_hwaddr[port]

            # log.debug( "Broadcasting routing table" )

            msg = of.ofp_packet_out()
            msg.data = ether.pack()

            # Add an action to send to the specified port
            action = of.ofp_action_output(port=port)
            msg.actions.append(action)
            self.connection.send(msg)
Ejemplo n.º 21
0
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()
Ejemplo n.º 22
0
    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)
Ejemplo n.º 23
0
def create_udp_pkt(srcip, dstip, dstport, dstmac, data):
  """
  """
  payload = data
  udp_pkt = pkt.udp()
  udp_pkt.srcport = 10000
  udp_pkt.dstport = dstport
  udp_pkt.payload = payload

  ipv4_pkt = pkt.ipv4()
  ipv4_pkt.protocol = pkt.ipv4.UDP_PROTOCOL
  ipv4_pkt.srcip = srcip
  ipv4_pkt.dstip = dstip
  ipv4_pkt.payload = udp_pkt

  ether_pkt = pkt.ethernet()
  ether_pkt.dst = dstmac
  ether_pkt.src = EthAddr("00:11:22:33:44:55")
  ether_pkt.type = ether_pkt.IP_TYPE
  ether_pkt.payload = ipv4_pkt

  return ether_pkt
Ejemplo n.º 24
0
    def send_UDP_response(self, responseCode, destIP, data):

        routable, destination_network = self.checkRoutableDestination(destIP)
        if routable:
            print "#Building a UDP packet destined for " + str(destIP)
            sourceMAC = self.arp_table[self.routing_table[destination_network]
                                       ['RouterInterface']]
            destMAC = self.arp_table[destIP]
            output_port = self.routing_table[destination_network]['Port']
            sourceIP = self.routing_table[destination_network][
                'RouterInterface']

            print "#Source IP : " + str(sourceIP) + " Source MAC : " + str(
                sourceMAC) + " destMAC : " + str(
                    destMAC) + " output_port : " + str(output_port)
            if destIP not in self.arp_table:
                print "\n#Sending ARP Request to destination IP ...#"
                self.ARPResolve(destIP, destination_network, output_port)
                print "Waiting for ARP Reply ..."
                while destIP not in self.buffer.keys():
                    pass
                print "ARP Response was received!"

            #Building and sending a UDP response to the client.
            e = pkt.ethernet(src=EthAddr(sourceMAC),
                             dst=EthAddr(destMAC),
                             type=pkt.ethernet.IP_TYPE)
            i = pkt.ipv4(srcip=IPAddr(sourceIP),
                         dstip=IPAddr(destIP),
                         protocol=pkt.ipv4.UDP_PROTOCOL)
            u = pkt.udp(srcport=10000, dstport=10000)  #,off = 5,win = 1)
            #t.ACK = True
            u.payload = str({"res": responseCode, "data": data})
            i.payload = u
            e.payload = i
            self.resend_packet(e, output_port)
  def _handle_PacketIn (self, event):
    packet = event.parsed

    # Hold on to the original UDP packet we received
    old_udp = packet.find("udp")

    # Check for some conditions
    # In our Mozilla experiment, we send UDP packets on port 10002
    # so we look for those
    if old_udp and old_udp.dstport == 10002:
      # The goal here is to take the contents of the original
      # UDP packet and modify them. When then need to package
      # It up in an enclosing IP packet
      # And finally, enclose it in an Ethernet packet

      # Create a new packet with the same info as the old
      # - ecept the contents are modified
      new_udp         = pkt.udp()
      new_udp.srcport = old_udp.srcport
      new_udp.dstport = old_udp.dstport
      new_udp.payload = 'Modified with Openflow:' + old_udp.payload

      # Create new new IP packet to enclose the UDP
      # packet we just created. The line that says new_ip.payload = new_udp
      # is where that happens
      new_ip = pkt.ipv4()
      new_ip.protocol = new_ip.UDP_PROTOCOL
      new_ip.srcip = packet.find("ipv4").srcip
      new_ip.dstip = packet.find("ipv4").dstip
      new_ip.payload = new_udp

      # And like before, enclose the IP packet in an ethernet packet
      new_eth = pkt.ethernet()
      new_eth.src = packet.src
      new_eth.dst = packet.dst
      new_eth.type = new_eth.IP_TYPE
      new_eth.payload = new_ip

      # Now let's encapsulate all this in a special message that
      #  will be sent back to our router. The instruction here
      #  for the switch is to forward the packet we created on
      #  all of the router/switch's physical ports
      msg = of.ofp_packet_out()
      msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))
      msg.data = new_eth.pack()

      # Send it along
      event.connection.send(msg)

      # Log some data describing what just happened
      log.debug("Sent a modified UDP packet from %s to %s", new_ip.dstip, new_ip.srcip)
      log.debug('Original Payload: ' + old_udp.payload)
      log.debug('New Payload: ' + new_udp.payload)
    else:
      # In the event we received some packet we don't care about,
      #  send it to along to where it was headed on all physical ports
      msg = of.ofp_packet_out()
      # A bit of a shortcode. Here we're just jamming the old
      #  packet data into a message for the switch. We don't
      #  need to construct a new packet like we did before
      msg.data = event.ofp
      msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))
      # Send the instruction to switch
      self.connection.send(msg)
Ejemplo n.º 26
0
    def _handle_PacketIn(self, event):
        packet = event.parsed

        # Hold on to the original UDP packet we received
        old_udp = packet.find("udp")

        # Check for some conditions
        # In our Mozilla experiment, we send UDP packets on port 10002
        # so we look for those
        if old_udp and old_udp.dstport == 10002:
            # The goal here is to take the contents of the original
            # UDP packet and modify them. When then need to package
            # It up in an enclosing IP packet
            # And finally, enclose it in an Ethernet packet

            # Create a new packet with the same info as the old
            # - ecept the contents are modified
            new_udp = pkt.udp()
            new_udp.srcport = old_udp.srcport
            new_udp.dstport = old_udp.dstport
            new_udp.payload = 'Modified with Openflow:' + old_udp.payload

            # Create new new IP packet to enclose the UDP
            # packet we just created. The line that says new_ip.payload = new_udp
            # is where that happens
            new_ip = pkt.ipv4()
            new_ip.protocol = new_ip.UDP_PROTOCOL
            new_ip.srcip = packet.find("ipv4").srcip
            new_ip.dstip = packet.find("ipv4").dstip
            new_ip.payload = new_udp

            # And like before, enclose the IP packet in an ethernet packet
            new_eth = pkt.ethernet()
            new_eth.src = packet.src
            new_eth.dst = packet.dst
            new_eth.type = new_eth.IP_TYPE
            new_eth.payload = new_ip

            # Now let's encapsulate all this in a special message that
            #  will be sent back to our router. The instruction here
            #  for the switch is to forward the packet we created on
            #  all of the router/switch's physical ports
            msg = of.ofp_packet_out()
            msg.actions.append(of.ofp_action_output(port=of.OFPP_ALL))
            msg.data = new_eth.pack()

            # Send it along
            event.connection.send(msg)

            # Log some data describing what just happened
            log.debug("Sent a modified UDP packet from %s to %s", new_ip.dstip,
                      new_ip.srcip)
            log.debug('Original Payload: ' + old_udp.payload)
            log.debug('New Payload: ' + new_udp.payload)
        else:
            # In the event we received some packet we don't care about,
            #  send it to along to where it was headed on all physical ports
            msg = of.ofp_packet_out()
            # A bit of a shortcode. Here we're just jamming the old
            #  packet data into a message for the switch. We don't
            #  need to construct a new packet like we did before
            msg.data = event.ofp
            msg.actions.append(of.ofp_action_output(port=of.OFPP_ALL))
            # Send the instruction to switch
            self.connection.send(msg)
  def sendPacket(self, event, new_addr):
    dpid    = event.connection.dpid
    ipEth   = core.learning_switch.arpTable[dpid]
    packet  = event.parsed
    old_udp = packet.find('udp')

    # The goal here is to take the contents of the original
    # UDP packet and modify them. When then need to package
    # It up in an enclosing IP packet
    # And finally, enclose it in an Ethernet packet
    new_addr = IPAddr(new_addr)
    #log.debug('Sent packet to: %s', new_addr)
    #log.debug(ipEth)

    if new_addr in ipEth:
      packet.dst = ipEth[new_addr]
      packet.payload.dstip = new_addr
      log.debug('Sending SUPERCAST from %s to %s: %s', packet.payload.srcip, new_addr, old_udp.payload)

      new_udp         = pkt.udp()
      new_udp.srcport = old_udp.srcport
      new_udp.dstport = old_udp.dstport
      new_udp.payload = old_udp.payload

      # Create new new IP packet to enclose the UDP
      # packet we just created. The line that says new_ip.payload = new_udp
      # is where that happens
      new_ip = pkt.ipv4()
      new_ip.protocol = new_ip.UDP_PROTOCOL
      new_ip.srcip    = packet.find("ipv4").srcip
      new_ip.dstip    = new_addr
      new_ip.payload  = new_udp

      # And like before, enclose the IP packet in an ethernet packet
      new_eth         = pkt.ethernet()
      new_eth.src     = packet.src
      new_eth.dst     = ipEth[new_addr].mac
      new_eth.type    = new_eth.IP_TYPE
      new_eth.payload = new_ip

      # Now let's encapsulate all this in a special message that
      #  will be sent back to our router. The instruction here
      #  for the switch is to forward the packet we created on
      #  all of the router/switch's physical ports
      msg = of.ofp_packet_out()
      msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))
      msg.data = new_eth.pack()

      # Send it along
      event.connection.send(msg)

    else:
      log.debug('Saw a SUPERCAST packet with %s as a recipient, but unknown MAC', new_addr)
      # Now let's encapsulate all this in a special message that
      #  will be sent back to our router. The instruction here
      #  for the switch is to forward the packet we created on
      #  all of the router/switch's physical ports
      msg = of.ofp_packet_out()
      msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))
      msg.data = event.ofp

      # Send it along
      event.connection.send(msg)
Ejemplo n.º 28
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()
    def sendPacket(self, event, new_addr):
        dpid = event.connection.dpid
        ipEth = core.learning_switch.arpTable[dpid]
        packet = event.parsed
        old_udp = packet.find('udp')

        # The goal here is to take the contents of the original
        # UDP packet and modify them. When then need to package
        # It up in an enclosing IP packet
        # And finally, enclose it in an Ethernet packet
        new_addr = IPAddr(new_addr)
        #log.debug('Sent packet to: %s', new_addr)
        #log.debug(ipEth)

        if new_addr in ipEth:
            packet.dst = ipEth[new_addr]
            packet.payload.dstip = new_addr
            log.debug('Sending SUPERCAST from %s to %s: %s',
                      packet.payload.srcip, new_addr, old_udp.payload)

            new_udp = pkt.udp()
            new_udp.srcport = old_udp.srcport
            new_udp.dstport = old_udp.dstport
            new_udp.payload = old_udp.payload

            # Create new new IP packet to enclose the UDP
            # packet we just created. The line that says new_ip.payload = new_udp
            # is where that happens
            new_ip = pkt.ipv4()
            new_ip.protocol = new_ip.UDP_PROTOCOL
            new_ip.srcip = packet.find("ipv4").srcip
            new_ip.dstip = new_addr
            new_ip.payload = new_udp

            # And like before, enclose the IP packet in an ethernet packet
            new_eth = pkt.ethernet()
            new_eth.src = packet.src
            new_eth.dst = ipEth[new_addr].mac
            new_eth.type = new_eth.IP_TYPE
            new_eth.payload = new_ip

            # Now let's encapsulate all this in a special message that
            #  will be sent back to our router. The instruction here
            #  for the switch is to forward the packet we created on
            #  all of the router/switch's physical ports
            msg = of.ofp_packet_out()
            msg.actions.append(of.ofp_action_output(port=of.OFPP_ALL))
            msg.data = new_eth.pack()

            # Send it along
            event.connection.send(msg)

        else:
            log.debug(
                'Saw a SUPERCAST packet with %s as a recipient, but unknown MAC',
                new_addr)
            # Now let's encapsulate all this in a special message that
            #  will be sent back to our router. The instruction here
            #  for the switch is to forward the packet we created on
            #  all of the router/switch's physical ports
            msg = of.ofp_packet_out()
            msg.actions.append(of.ofp_action_output(port=of.OFPP_ALL))
            msg.data = event.ofp

            # Send it along
            event.connection.send(msg)