Recently I had to work with openvswitch to apply drop some VIP traffic on some particular IPs. The problem was that those particular IPs had port ranges and the job was to only block those particular IP addresses with a specific port range.
Openvswitch does not allows to specify port ranges like numbers, so if i were to add a rule for port range e.g 7 to 14 I cannot specify it like 7 - 14. Instead, I must specify the first number and wildcard the port numbers until the least significant 1 of the number changes to 0.
For example:
Number Binary Number of trailing 0s Covered Range Port Mask
7 0111 0 only 7 f
8 1000 3 8-11 c
12 1100 2 12-13 e
14 1110 1 only 14 f
Exaplanation:
We want range 7-14.. In case of 8 there are 3 trailing zeros. If we wildcard all three zeros, the range will reach 15 but we want to limit it to 14 so we limit it to 2 zeros and then adjust remaining numbers in the next range.
Number 1***
9 : 1001
10 : 1010
11 : 1011
12 : 1100
13 : 1101
14 : 1110
15 : 1111
Python Code for calculating 32 bit Port Masks
This code is inspired by a blog post jpwise. Original post can be found at:
http://blog.of.geek.nz/2012/07/22/u32-port-masks-calculator/
Openvswitch does not allows to specify port ranges like numbers, so if i were to add a rule for port range e.g 7 to 14 I cannot specify it like 7 - 14. Instead, I must specify the first number and wildcard the port numbers until the least significant 1 of the number changes to 0.
For example:
Number Binary Number of trailing 0s Covered Range Port Mask
7 0111 0 only 7 f
8 1000 3 8-11 c
12 1100 2 12-13 e
14 1110 1 only 14 f
Exaplanation:
We want range 7-14.. In case of 8 there are 3 trailing zeros. If we wildcard all three zeros, the range will reach 15 but we want to limit it to 14 so we limit it to 2 zeros and then adjust remaining numbers in the next range.
Number 1***
9 : 1001
10 : 1010
11 : 1011
12 : 1100
13 : 1101
14 : 1110
15 : 1111
Python Code for calculating 32 bit Port Masks
def dec2bin(val): if val is None: return False if int(val) > 65535: return False return '{0:016b}'.format(val) def getMask(bits): return { '0': "0xffff", '1': "0xfffe", '2': "0xfffc", '3': "0xfff8", '4': "0xfff0", '5': "0xffe0", '6': "0xffc0", '7': "0xff80", '8': "0xff00", '9': "0xfe00", '10': "0xfc00", '11': "0xf800", '12': "0xf000", '13': "0xe000", '14': "0xc000", '15': "0x8000" }[str(bits)] def binLower(binary,bits): outBin = binary[0:16-bits] for i in range(0,bits): outBin += "0" return int(outBin,2) def binHigher(binary, bits): outBin = binary[0:16-bits] for i in range(0,bits): outBin += "1" return int(outBin,2) def testMasks(binary, start, end): if binary is None: return None for mask in range(0,17): maskStart = binLower(binary, mask) maskEnd = binHigher(binary, mask) if maskStart < start or maskEnd > end: return mask-1 return mask def get_port_mask(range_start, range_end): container = [] mask_range = [] if range_end < range_start: raise: print "First port value must be lower than the second" return None if range_start <=0 or range_start > 65535: raise: print "Port end : ", range_start , "is out of range. Valid range: 1-65535" return None if range_end <=0 or range_end > 65535: raise: print "Port end : ", range_end , "is out of range. Valid range: 1-65535" return None processing = True while processing: binary = [] binary_start = dec2bin(range_start) binary_lastOne = str(binary_start).rfind("1")+1 binary_bitsToChange = 16 - binary_lastOne mask = testMasks(binary_start, range_start, range_end) if mask is None: return None maskStart = binLower(binary_start, mask) maskEnd = binHigher(binary_start, mask) container.append ((maskStart, getMask(mask))) range_port = range_start range_mask = getMask(mask) range_start = maskEnd + 1 if range_start > range_end: processing = False return container #Call this script like this: print get_port_mask(7,14)
This code is inspired by a blog post jpwise. Original post can be found at:
http://blog.of.geek.nz/2012/07/22/u32-port-masks-calculator/
Comments
Post a Comment