如何从TCP端口范围计算掩码

时间:2015-08-04 11:05:34

标签: tcp range port mask

我正在试图计算一个可以表示L4端口范围的掩码值。假设输入范围是500-1000。给定掩码和较低值,如何计算上限值?

1 个答案:

答案 0 :(得分:0)

端口掩码通常遵循以下格式:<port>/<mask>。可以在 OvS ovs-ofctl 手册中找到端口屏蔽的示例:

https://www.openvswitch.org/support/dist-docs-2.5/ovs-ofctl.8.html

摘录:

...
       tcp_src=port/mask
       tcp_dst=port/mask
       udp_src=port/mask
       udp_dst=port/mask
       sctp_src=port/mask
       sctp_dst=port/mask
              Bitwise  match  on  TCP  (or  UDP or SCTP) source or destination
              port.  The port and mask are 16-bit numbers written  in  decimal
              or  in  hexadecimal prefixed by 0x.  Each 1-bit in mask requires
              that the corresponding bit in port must match.   Each  0-bit  in
              mask causes the corresponding bit to be ignored.

              Bitwise  matches  on transport ports are rarely useful in isola‐
              tion, but a group of them can be used to reduce  the  number  of
              flows  required  to  match  on  a range of transport ports.  For
              example, suppose that the goal is to match TCP source ports 1000
              to  1999,  inclusive.   One way is to insert 1000 flows, each of
              which matches on a single source port.  Another way is  to  look
              at the binary representations of 1000 and 1999, as follows:
              01111101000
              11111001111
              and  then  to  transform  those into a series of bitwise matches
              that accomplish the same results:
              01111101xxx
              0111111xxxx
              10xxxxxxxxx
              110xxxxxxxx
              1110xxxxxxx
              11110xxxxxx
              1111100xxxx
              which become the following when written in the  syntax  required
              by ovs-ofctl:
              tcp,tcp_src=0x03e8/0xfff8
              tcp,tcp_src=0x03f0/0xfff0
              tcp,tcp_src=0x0400/0xfe00
              tcp,tcp_src=0x0600/0xff00
              tcp,tcp_src=0x0700/0xff80
              tcp,tcp_src=0x0780/0xffc0
              tcp,tcp_src=0x07c0/0xfff0

              Only  Open  vSwitch  1.6  and later supports bitwise matching on
              transport ports.

              Like the exact-match forms described above,  the  bitwise  match
              forms apply only when dl_type and nw_proto specify TCP or UDP or
              SCTP.

以下 python3 mask_range 函数返回给定开始和结束端口号的端口掩码列表。

# port_mask.py
LIMIT = 65535


def max_port(port, mask):
    xid = LIMIT - mask
    nid = port & mask
    return nid + xid


def port_mask(port, end):
    bit = 1
    mask = LIMIT
    test_mask = LIMIT
    net = port & LIMIT
    max_p = max_port(net, LIMIT)

    while net and max_p < end:
        net = port & test_mask
        if net < port:
            break
        max_p = max_port(net, test_mask)
        if max_p <= end:
            mask = test_mask
        test_mask -= bit
        bit <<= 1

    return mask


def mask_range(start, end):
    port_masks = []

    if end <= start or end > LIMIT:
        exit(1)

    port = start

    while port <= end:
        mask = port_mask(port, end)
        port_masks.append(f'{hex(port)}/{hex(mask)}')
        port = max_port(port, mask) + 1

    return port_masks

示例:

# test.py
from port_mask import mask_range

if __name__ == '__main__':
    masks = mask_range(1000, 1999)
    print(f'1000-1999: {masks}')

输出:

1000-1999: ['0x3e8/0xfff8', '0x3f0/0xfff0', '0x400/0xfe00', '0x600/0xff00', '0x700/0xff80', '0x780/0xffc0', '0x7c0/0xfff0']