1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
# -*- coding: utf-8 -*-
"""Module provide utilities to find ephemeral port ranges for the current OS.
See http://www.ncftp.com/ncftpd/doc/misc/ephemeral_ports.html for more info
about ephemeral port ranges.
Currently only Linux and BSD (including OS X) are supported.
"""
import subprocess
from typing import Dict, List, Tuple
DEFAULT_EPHEMERAL_PORT_RANGE = (32768, 65535)
def port_ranges() -> List[Tuple[int, int]]:
"""Return a list of ephemeral port ranges for current machine."""
try:
return _linux_ranges()
except (OSError, IOError): # not linux, try BSD
try:
ranges = _bsd_ranges()
if ranges:
return ranges
except (OSError, IOError):
pass
# fallback
return [DEFAULT_EPHEMERAL_PORT_RANGE]
def _linux_ranges() -> List[Tuple[int, int]]:
with open("/proc/sys/net/ipv4/ip_local_port_range") as f:
# use readline() instead of read() for linux + musl
low, high = f.readline().split()
return [(int(low), int(high))]
def _bsd_ranges() -> List[Tuple[int, int]]:
pp = subprocess.Popen(
["sysctl", "net.inet.ip.portrange"], stdout=subprocess.PIPE
)
stdout, stderr = pp.communicate()
lines = stdout.decode("ascii").split("\n")
out: Dict[str, str] = dict(
[
[x.strip().rsplit(".")[-1] for x in line.split(":")]
for line in lines
if line
]
)
ranges = [
# FreeBSD & Mac
("first", "last"),
("lowfirst", "lowlast"),
("hifirst", "hilast"),
# OpenBSD
("portfirst", "portlast"),
("porthifirst", "porthilast"),
]
res = []
for rng in ranges:
try:
low, high = int(out[rng[0]]), int(out[rng[1]])
if low <= high:
res.append((low, high))
except KeyError:
pass
return res
|