Example #1
0
    def firewallInit(self):
        ind = 0
        for rule in self.rules:
            field = rule.split()
            temp={}
            action, type = field[0:2]
            rtlimit = 65535
            src = self.toInt(IPAddr(0),0)
            dst = self.toInt(IPAddr(0),0)
            srcpt, dstpt, srcip, dstip = ['*', '*', '*', '*']
            srccidr, dstcidr = [0, 0]

            if (field[0]=='deny'):
                action = False
            type = protocol[field[1]]
       
            for i in range(2, len(field)):
                if (field[i] == 'src') and (field[i+1]!='any'):
                    srcip, srccidr = parse_cidr(field[i+1])
                    src=self.toInt(srcip, srccidr)
                elif (field[i] == 'dst') and (field[i+1]!='any'):
                    dstip, dstcidr = parse_cidr(field[i+1])
                    dst=self.toInt(dstip, dstcidr)
                elif (field[i] == 'srcport') and (field[i+1]!='any'):
                    srcpt=int(field[i+1])
                elif (field[i] == 'dstport') and (field[i+1]!='any'):
                    dstpt=int(field[i+1])
                elif (field[i] == 'ratelimit'):
                    rtlimit=int(field[i+1])
    
            self.append([action,type,srcip,srccidr,dstip,dstcidr,srcpt,dstpt,rtlimit,ind])
            self.firewall.append([type,src,dst,srcpt,dstpt])
            self.token.append(0)
            ind+=1
Example #2
0
    def __init__(self, permit, protocol, srcip, dstip, srcport, dstport, rate):
        self.permit = permit=='permit'
        srccidr = parse_cidr(srcip)
        dstcidr = parse_cidr(dstip)

        self.srcip = srccidr[0].toUnsigned()&cidr_to_netmask(srccidr[1]).toUnsigned()
        self.srcip += 2**(32-srccidr[1])-1
        self.dstip = dstcidr[0].toUnsigned()&cidr_to_netmask(dstcidr[1]).toUnsigned()
        self.dstip += 2**(32-dstcidr[1])-1

        self.protocol = protocol
        self.srcport = srcport
        self.dstport = dstport
        self.rate = rate
        '''
Example #3
0
    def sync_table(self):
        # This is pretty awful!
        rt = runout(*("ip route list table " + str(self.tableno)).split())
        rt = rt.strip().split("\n")

        def get_field(e, f, t=None, d=None):
            if f not in e: return d
            v = e[e.index(f) + 1]
            if t is not None: v = t(v)
            return v

        def get_int(e, f):
            return get_field(e, f, t=int)

        add = []
        cur = {}
        remove = set()
        for re in [x.split() for x in rt if x]:
            dst, size = parse_cidr(re[0])
            k = "%s/%s" % (dst, size)
            assert k not in cur
            cur[k] = re
            if k not in self.table:
                remove.add(k)

        for e in self.table.values():
            if e.local: continue
            if e.key not in cur:
                add.append(e)
                continue
            c = cur[e.key]
            if get_int(c, "metric") != e.metric:
                remove.add(e.key)
                add.append(e)
                continue
            if e.dev:
                if e.dev != get_field(c, "dev"):
                    remove.add(e.key)
                    add.append(e)
                    continue
            elif e.next_hop != get_field(c, "via"):
                remove.add(e.key)
                add.append(e)
                continue

        #if add or remove:
        #  self.log.info("Removing %s routes and adding %s", len(remove), len(add))
        modify = set(remove).intersection([e.key for e in add])
        for e in remove:
            cmd = "ip route del " + e + " table " + str(self.tableno)
            if e not in modify:
                # Yes, the modify code below isn't used anymore.
                self.log.info("%s route for %s",
                              "Modifying" if e in modify else "Removing", e)
            runfail(*cmd.split())
        for e in add:
            cmd = "ip route add " + _cmd(e) + " table " + str(self.tableno)
            self.log.info("%s route for %s",
                          "Modifying" if e.key in modify else "Adding", e.key)
            runfail(*cmd.split())
Example #4
0
  def _add_del_route (self, network, gateway=None, dev=(), metric=0,
                      command=None):
    """
    Add or remove a routing table entry

    If dev is unspecified, it defaults to this device
    """
    r = rtentry()
    if isinstance(network, tuple):
      addr,mask = network
      addr = str(addr)
      if isinstance(mask, (int,long)):
        mask = cidr_to_netmask(mask)
      mask = str(mask)
      network = "%s/%s" % (addr,mask)
    host = False
    if isinstance(network, IPAddr) or (isinstance(network, str)
                                       and "/" not in network):
      host = True
    network,bits = parse_cidr(network)
    r.rt_dst = network
    r.rt_genmask = cidr_to_netmask(bits)
    if gateway is not None:
      r.rt_gateway = IPAddr(gateway)
      r.rt_flags |= r.RTF_GATEWAY
    r.rt_metric = metric
    if dev is (): dev = self
    if isinstance(dev, Interface): dev = dev.name
    if dev: r.rt_dev = dev
    if host: r.rt_flags |= r.RTF_HOST
    r.rt_flags |= r.RTF_UP
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    rv = ioctl(sock, command, r.pack())
Example #5
0
    def _handle_IPv4In(self,event):
        dst_ip = event.ipv4p.dstip
        dpid = dpid_to_str(event.connection.dpid)
        inport = event.inport

        #判断是否是Core收到了IPv4In事件
        if dpid in core.SRPConfig.core_list:
            return
        #判断目的网段是否在对应DPID连接的网段中
        if not same_network(dst_ip,core.SRPConfig.get_tor_lan_addr(dpid)):
            return

        if dst_ip in self.arp_table[dpid]:
            #判断之前是否已经获得目的IP地址的MAC地址
            table = self.arp_table[dpid][dst_ip]

            log.debug("[%s] Send out the ipv4 packet: %s =>%s",dpid,event.ipv4p.srcip,dst_ip)
            msg = of.ofp_packet_out(buffer_id = event.ofp.buffer_id, in_port = inport)
            msg.actions.append(of.ofp_action_dl_addr.set_dst(table.mac))
            msg.actions.append(of.ofp_action_output(port = table.port))
            event.connection.send(msg)

            log.debug("[%s] Set up the Flow for destination: %s",dpid,dst_ip)
            actions = list()
            actions.append(of.ofp_action_dl_addr.set_dst(table.mac))
            actions.append(of.ofp_action_output(port = table.port))
            match = of.ofp_match()
            match.dl_type = pkt.ethernet.IP_TYPE
            match.nw_dst = dst_ip
            msg = of.ofp_flow_mod(command = of.OFPFC_MODIFY,
                                  actions = actions,
                                  match = match,
                                  idle_timeout = FLOW_IDLE_TIMEOUT,
                                  hard_timeout = of.OFP_FLOW_PERMANENT)
            event.connection.send(msg)
        else:
            #缓存IPv4报文,并广播ARPRequest报文请求目的IP地址的MAC地址
            log.debug("[%s] Buffer unsent IPv4 packet point to %s",dpid,dst_ip)
            if (dpid,dst_ip) not in self.ipv4_buffers:
                self.ipv4_buffers[(dpid,dst_ip)] = []
            buffers  = self.ipv4_buffers[(dpid,dst_ip)]
            entry = (time.time()+MAX_BUFFER_TIME,event.ofp.buffer_id,inport)
            buffers.append(entry)
            while len(buffers)>MAX_BUFFERED_PER_IP:
                msg = of.ofp_packet_out(buffer_id=buffers[0][1],in_port=buffers[0][2])
                event.connection.send(msg)
                del buffers[0]

            #触发SendARPRequest事件,请求该IPv4报文的目的IP地址对应的MAC地址
            src_ip = parse_cidr(core.SRPConfig.get_tor_lan_addr(dpid))[0]
            src_mac = _dpid_to_mac(event.connection.dpid)

            log.debug("[%s] Raise SendARPRequest Event %s | %s => %s | %s",
                  dpid,src_ip,src_mac,dst_ip,ETHER_BROADCAST)
            ev = SendARPRequest(event.connection,src_ip,src_mac,dst_ip,ETHER_BROADCAST,flood=True)
            self.raiseEvent(ev)
Example #6
0
        def _get_config():
            log.debug('Config Module is loaded!')

            self.arp_table = ARPTableSet()
            for dpid in core.SRPConfig.tor_list:
                self.arp_table[dpid] = ARPTable()
                ip = IPAddr(parse_cidr(core.SRPConfig.get_tor_lan_addr(dpid))[0])
                self.arp_table[dpid][ip] = Entry(_dpid_to_mac(str_to_dpid(dpid)), static=True)
                for k, v in kwargs.iteritems():
                    self.arp_table[dpid][IPAddr(k)] = Entry(v, static=True)
            core.Interactive.variables['arp'] = self.arp_table
Example #7
0
    def get_mask(self, ip_addr):
        if ip_addr == "any":
            return cidr_to_netmask(0).toUnsigned() #0.0...
            
        parsed = parse_cidr(ip_addr)
        
        number = parsed[0].toUnsigned()
        shift_clean = 32 - parsed[1] #So we can ignore anything the netmask tells us to

        cleaned = (number>>(shift_clean))<<shift_clean #Wipe out dangling 1's

        return cleaned
Example #8
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)
  def value (self, value):
    if isinstance(value, tuple) or isinstance(value, list):
      assert len(value) == 2
      ip = value[0]
      self.mask = value[1]
      if isinstance(mask, (int,long)):
        self.mask = mask
    elif isinstance(value, basestring) and len(value)>4 and '/' in value:
      temp = parse_cidr(value, infer=False)
      ip = temp[0]
      self.mask = 32 if temp[1] is None else temp[1]
    else:
      ip = value

    self._value = self._pack_value(value)
Example #10
0
 def add_local_routes(self, table=None):
     cmd = "ip route list".split()
     if table is not None: cmd += ["table", str(table)]
     d = runout(*cmd).strip().split("\n")
     for e in d:
         e = e.split()
         if "src" not in e: continue
         dst = parse_cidr(e[0], allow_host=False)
         src = IPAddr(e[e.index("src") + 1])
         n = self._new_entry(local=True, origin=src)
         n.ip = dst[0]
         n.size = dst[1]
         n.metric = 1
         if "metric" in e: n.metric = int(e[e.index("metric") + 1])
         self.table[n.key] = n
Example #11
0
    def __init__(self,
                 network="192.168.0.0/24",
                 first=1,
                 last=None,
                 count=None):
        """
    Simple subnet-based address pool

    Allocates count IP addresses out of network/network_size, starting
    with the first'th.  You may specify the end of the range with either
    last (to specify the last'th address to use) or count to specify the
    number to use.  If both are None, use up to the end of all
    legal addresses.

    Example for all of 192.168.x.x/16:
      SimpleAddressPool("192.168.0.0/16", 1, 65534)
    """

        network, network_size = parse_cidr(network)

        self.first = first
        self.network_size = network_size
        self.host_size = 32 - network_size
        self.network = IPAddr(network)

        # use entire host space
        if last is None and count is None:
            self.last = (1 << self.host_size) - 2
        # set last address to use
        elif last is not None:
            self.last = last
        # just use count many
        elif count is not None:
            self.last = self.first + count - 1
        else:
            raise RuntimeError("Cannot specify both last and count")

        self.removed = set()

        # error checking here
        if self.count <= 0: raise RuntimeError("Bad first/last range")
        if first == 0: raise RuntimeError("Can't allocate 0th address")
        if self.host_size < 0 or self.host_size > 32:
            raise RuntimeError("Bad network")
        if IPAddr(self.last | self.network.toUnsigned()) not in self:
            raise RuntimeError("Bad first/last range")
Example #12
0
    def _handle_ARPReply(self,event):
        dpid = dpid_to_str(event.connection.dpid)
        src_ip = event.arpp.protosrc
        src_mac = event.arpp.hwsrc
        dst_ip = event.arpp.protodst
        dst_mac = event.arpp.hwdst
        inport = event.inport

        if dpid in core.SRPConfig.core_list:
            log.debug("[%s] Ignore ARPReply Packet from Core Switch!",dpid)
            return

        if same_network(dst_ip,core.SRPConfig.get_tor_lan_addr(dpid),32):
            self._send_arp_buffer(dpid,src_ip,src_mac,inport)
        else:
            if dst_ip in self.arp_table[dpid]:
                outport = self.arp_table[dpid][dst_ip].port
                log.debug("[%s] Raise SendARPReply Event %s => %s",
                      dpid,src_ip,dst_ip)
                ev = SendARPReply(event.connection,src_ip,src_mac,dst_ip,dst_mac,outport)
                self.raiseEvent(ev)
            else:
                #缓存ARP Reply报文,并广播ARPRequest报文请求目的IP地址的MAC地址
                log.debug("[%s] Buffer unsent arp packet point to %s",dpid,dst_ip)
                if (dpid,dst_ip) not in self.arp_buffers:
                    self.arp_buffers[(dpid,dst_ip)] = []
                buffers  = self.arp_buffers[(dpid,dst_ip)]
                entry = (time.time()+MAX_BUFFER_TIME,event.ofp.buffer_id,inport)
                buffers.append(entry)
                while len(buffers)>MAX_BUFFERED_PER_IP:
                    msg = of.ofp_packet_out(buffer_id=buffers[0][1],in_port=buffers[0][2])
                    event.connection.send(msg)
                    del buffers[0]

                #触发SendARPRequest事件,请求该ARP报文的目的IP地址对应的MAC地址
                src_ip = parse_cidr(core.SRPConfig.get_tor_lan_addr(dpid))[0]
                src_mac = _dpid_to_mac(event.connection.dpid)

                log.debug("[%s] Raise SendARPRequest Event %s => %s ",
                      dpid,src_ip,dst_ip)
                ev = SendARPRequest(event.connection,src_ip,src_mac,dst_ip,ETHER_BROADCAST,flood=True)
                self.raiseEvent(ev)
Example #13
0
  def __init__ (self, network = "192.168.1.0/24", first = 2, last = None,
                count = None):
    """
    Simple subnet-based address pool

    Allocates count IP addresses out of network/network_size, starting
    with the first'th.  You may specify the end of the range with either
    last (to specify the last'th address to use) or count to specify the
    number to use.  If both are None, use up to the end of all
    legal addresses.

    Example for all of 192.168.x.x/16:
      SimpleAddressPool("192.168.0.0/16", 1, 65534)
    """
    network,network_size = parse_cidr(network)

    self.first = first
    self.network_size = network_size
    self.host_size = 32-network_size
    self.network = IPAddr(network)


    if last is None and count is None:
      self.last = (1 << self.host_size) - 2
    elif last is not None:
      self.last = last
    elif count is not None:
      self.last = self.first + count - 1
    else:
      raise RuntimeError("Cannot specify both last and count")

    self.removed = set()

    if self.count <= 0: raise RuntimeError("Bad first/last range")
    if first == 0: raise RuntimeError("Can't allocate 0th address")
    if self.host_size < 0 or self.host_size > 32:
      raise RuntimeError("Bad network")
    if IPAddr(self.last | self.network.toUnsigned()) not in self:
      raise RuntimeError("Bad first/last range")
Example #14
0
    def __init__(self, network="192.168.0.0/24", dns=None):

        # attributes of our network
        self.network, self.network_size = parse_cidr(network)
        self.dns_addr = dns
        self.subnets = {}  # IP -> subnet
        self.core = []
        self.edges = {}
        self.edge_to_tuple = {}  # dpid -> (network, core dpid)
        self.mobile_hosts = {}  # MAC -> IP

        # attributes to track DHCP
        self.lease_time = timeoutSec['leaseInterval']
        self.offers = {}  # Subnet -> {Eth -> IP we offered}
        self.leases = {}  # Subnet -> {Eth -> LeaseEntry}
        self._t = None

        # if this is the first time the server has been started up
        self._first_stable = True

        core.listen_to_dependencies(self)
        core.openflow.addListeners(self)
Example #15
0
    def buildfwt(self):
        '''
        Returns a list containing a representation of the firewall rules in the order in which they appear

        Input rule syntax:
        [permit|deny] ip src [srcnet|any] dst [dstnet|any]
        [permit|deny| icmp src [srcnet|any] dst [dstnet|any]
        [permit|deny] [udp|tcp] src [srcnet|any] srcport [portno|any] dst [dstnet|any] dstport [portno|any]

        Output list entry syntax:
        [protocol, (source IP, masklen), (dest IP, masklen), src port, dst port]

        Protocol assignments:
        (0) 000 = deny ip       (4) 100 = permit ip
        (1) 001 = deny icmp     (5) 101 = permit icmp
        (2) 010 = deny udp      (6) 110 = permit udp
        (3) 011 = deny tcp      (7) 111 = permit tcp
        '''
        print "Compiling firewall rules list..."
        fwt = []
        f = open("firewall_rules.txt",'r')
        line=0; counter=0

        while 1:
            entry = f.readline()
            line += 1

            # identify rules
            if entry == "": break
            elif entry[0] == "#": continue
            elif entry[0] == "\n": continue
            else:
                entry = entry.strip(' \n')
                counter += 1

            # variables
            esplit = entry.split()
            fwtent = []
            special = 0

            # protocol
            if esplit[0] == "deny":
                if esplit[1]=="ip":     fwtent.append(0)
                elif esplit[1]=="icmp": fwtent.append(1)
                elif esplit[1]=="udp":  fwtent.append(2); special=1
                elif esplit[1]=="tcp":  fwtent.append(3); special=1
                else: print "Error in entry line " + str(line) + ": " + str(esplit[1]); continue
            elif esplit[0] == "permit":
                if esplit[1]=="ip":     fwtent.append(4)
                elif esplit[1]=="icmp": fwtent.append(5)
                elif esplit[1]=="udp":  fwtent.append(6); special=1
                elif esplit[1]=="tcp":  fwtent.append(7); special=1
                else: print "Error in entry line " + str(line) + ": " + str(esplit[1]); continue
            else:
                print "Error in entry line " + str(line) + ": " + str(esplit[0]); continue
            
            # src IP, dst IP
            if special: pickup=[3,7]    # src IP at 3, dst IP at 7
            else: pickup=[3,5]          # src IP at 3, dst IP at 5

            for i in range(2):
                if esplit[pickup[i]]=="any": fwtent.append((IPAddr("0.0.0.0"),32))
                else: fwtent.append(parse_cidr(esplit[pickup[i]]))

            # src port, dst port
            if special:
                pickup=[5,9]            # src port at 5, dst port at 9

                for i in range(2):
                    if esplit[pickup[i]]=="any": fwtent.append(0)
                    else: fwtent.append(int(esplit[pickup[i]]))
            else:
                fwtent.append('x'); fwtent.append('x')

            # create token bucket if necessary and append to self.tbuckets
            if esplit[0]=="permit" and (len(esplit)==12 or len(esplit)==8):
                self.tbuckets.append(TBucket(counter,int(esplit[-1])))

            #print entry; print fwtent; print "*"*32 
            fwt.append(fwtent)

        print str(line-1) + " lines read; " + str(counter) + " rules compiled\n"
        return fwt
def _fix_ip (n):
  if n is None: return n
  return parse_cidr(n, infer = False)
Example #17
0
def _fix_ip(n):
    if n is None: return n
    return parse_cidr(n, infer=False)