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
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 '''
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())
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())
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)
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
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
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)
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
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")
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)
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")
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)
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)
def _fix_ip(n): if n is None: return n return parse_cidr(n, infer=False)