diff --git a/.github/workflows/proto_num_filepull.yml b/.github/workflows/proto_num_filepull.yml new file mode 100644 index 00000000..ced8694e --- /dev/null +++ b/.github/workflows/proto_num_filepull.yml @@ -0,0 +1,56 @@ +--- +name: "Protocol-Number-Updates" + +on: # yamllint disable-line rule:truthy + schedule: + - cron: "0 2 1 * *" + +jobs: + data_gathering: + runs-on: "ubuntu-latest" + env: + BRANCH_NAME: "PROTO_NUM_Updates" + steps: + # Checkout repo + - name: "Check out code" + uses: "actions/checkout@v2" + with: + ref: "develop" + # Delete old branch if it exists + - name: "Delete existing branch" + run: "git branch -D $BRANCH_NAME || true" + # Create branch for Flatbot + - name: "Create Flatbot branch" + run: "git checkout -b $BRANCH_NAME" + # Push new branch so Flatbot can make its commit + - name: "Push Flatbot branch" + run: "git push -f --set-upstream origin $BRANCH_NAME" + # Install Black + - name: "Install Python Black" + run: "pip install black" + # This step installs Deno, which is a new Javascript runtime that improves on Node. Can be used for an optional postprocessing step + - name: "Setup deno" + uses: "denoland/setup-deno@main" + with: + deno-version: "v1.10.x" + # The Flat Action step. We fetch the data in the http_url and save it as downloaded_filename + - name: "Fetch data" + uses: "githubocto/flat@v3" + with: + http_url: "https://www.iana.org/assignments/protocol-numbers/protocol-numbers-1.csv" + downloaded_filename: "./netutils/data_files/protocol_number_mappings.py" + postprocess: "./flat_postprocess/protocol_number_postprocess.ts" + pr_creation: + runs-on: "ubuntu-latest" + needs: "data_gathering" + steps: + # Checkout repo + - name: "Check out code" + uses: "actions/checkout@v2" + with: + ref: "PROTO_NUM_Updates" + # Create PR from branch created above into develop + - name: "Create a Pull Request" + run: "gh pr create -B develop -H PROTO_NUM_Updates --title 'Flatbot PROTOCOL Number File Updates' --body 'Created by Flatbot action'" + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/flat_postprocess/protocol_number_postprocess.py b/flat_postprocess/protocol_number_postprocess.py new file mode 100644 index 00000000..54f50a44 --- /dev/null +++ b/flat_postprocess/protocol_number_postprocess.py @@ -0,0 +1,38 @@ +"""Python code used to postprocess Flat github action data related to Protocol mappings.""" +import csv +import os +import sys +from urllib.request import urlopen + + +if __name__ == "__main__": + if len(sys.argv) == 2: + URL = "https://www.iana.org/assignments/protocol-numbers/protocol-numbers-1.csv" + oui_textfile = urlopen(URL).read().decode("utf-8") # nosec: pylint: disable=consider-using-with + with open(sys.argv[1], "w", encoding="utf-8") as proto_mappings: + proto_mappings.write(oui_textfile) + + protocol_mapping = {} + reverse_mapping = {} + with open(sys.argv[1], encoding="utf-8") as file: + next(file) + reader = csv.reader(file) + for row in reader: + number = row[0] + name = row[1] + if not number.isnumeric(): + continue + if not name: + continue + name = name.replace(" (deprecated)", "") + protocol_mapping[name] = int(number) + reverse_mapping[int(number)] = name + + with open(sys.argv[1], "w", encoding="utf-8") as proto_mappings: + proto_mappings.write('"""Dictionary object to store Protocol Number."""\n') + proto_mappings.write("from typing import Dict\n") + proto_mappings.write(f"PROTO_NAME_TO_NUM: Dict[str, int] = {protocol_mapping}") + proto_mappings.write("\n") + proto_mappings.write(f"PROTO_NUM_TO_NAME: Dict[int, str] = {reverse_mapping}") + + os.system(f"black {sys.argv[1]}") # nosec diff --git a/flat_postprocess/protocol_number_postprocess.ts b/flat_postprocess/protocol_number_postprocess.ts new file mode 100644 index 00000000..75862cb9 --- /dev/null +++ b/flat_postprocess/protocol_number_postprocess.ts @@ -0,0 +1,7 @@ +// Forwards the execution to the python script +const py_run = Deno.run({ + // Run `python ./flat_postprocess/protocol_number_postprocess.py netutils/data_files/protocol_number_mappings.py` to test locally. + cmd: ["python", "./flat_postprocess/protocol_number_postprocess.py"].concat(Deno.args), +}); + +await py_run.status(); diff --git a/netutils/data_files/protocol_number_mappings.py b/netutils/data_files/protocol_number_mappings.py new file mode 100644 index 00000000..f0b4d2d6 --- /dev/null +++ b/netutils/data_files/protocol_number_mappings.py @@ -0,0 +1,292 @@ +"""Dictionary object to store Protocol Number.""" +from typing import Dict + +PROTO_NAME_TO_NUM: Dict[str, int] = { + "HOPOPT": 0, + "ICMP": 1, + "IGMP": 2, + "GGP": 3, + "IPv4": 4, + "ST": 5, + "TCP": 6, + "CBT": 7, + "EGP": 8, + "IGP": 9, + "BBN-RCC-MON": 10, + "NVP-II": 11, + "PUP": 12, + "ARGUS": 13, + "EMCON": 14, + "XNET": 15, + "CHAOS": 16, + "UDP": 17, + "MUX": 18, + "DCN-MEAS": 19, + "HMP": 20, + "PRM": 21, + "XNS-IDP": 22, + "TRUNK-1": 23, + "TRUNK-2": 24, + "LEAF-1": 25, + "LEAF-2": 26, + "RDP": 27, + "IRTP": 28, + "ISO-TP4": 29, + "NETBLT": 30, + "MFE-NSP": 31, + "MERIT-INP": 32, + "DCCP": 33, + "3PC": 34, + "IDPR": 35, + "XTP": 36, + "DDP": 37, + "IDPR-CMTP": 38, + "TP++": 39, + "IL": 40, + "IPv6": 41, + "SDRP": 42, + "IPv6-Route": 43, + "IPv6-Frag": 44, + "IDRP": 45, + "RSVP": 46, + "GRE": 47, + "DSR": 48, + "BNA": 49, + "ESP": 50, + "AH": 51, + "I-NLSP": 52, + "SWIPE": 53, + "NARP": 54, + "Min-IPv4": 55, + "TLSP": 56, + "SKIP": 57, + "IPv6-ICMP": 58, + "IPv6-NoNxt": 59, + "IPv6-Opts": 60, + "CFTP": 62, + "SAT-EXPAK": 64, + "KRYPTOLAN": 65, + "RVD": 66, + "IPPC": 67, + "SAT-MON": 69, + "VISA": 70, + "IPCV": 71, + "CPNX": 72, + "CPHB": 73, + "WSN": 74, + "PVP": 75, + "BR-SAT-MON": 76, + "SUN-ND": 77, + "WB-MON": 78, + "WB-EXPAK": 79, + "ISO-IP": 80, + "VMTP": 81, + "SECURE-VMTP": 82, + "VINES": 83, + "IPTM": 84, + "NSFNET-IGP": 85, + "DGP": 86, + "TCF": 87, + "EIGRP": 88, + "OSPFIGP": 89, + "Sprite-RPC": 90, + "LARP": 91, + "MTP": 92, + "AX.25": 93, + "IPIP": 94, + "MICP": 95, + "SCC-SP": 96, + "ETHERIP": 97, + "ENCAP": 98, + "GMTP": 100, + "IFMP": 101, + "PNNI": 102, + "PIM": 103, + "ARIS": 104, + "SCPS": 105, + "QNX": 106, + "A/N": 107, + "IPComp": 108, + "SNP": 109, + "Compaq-Peer": 110, + "IPX-in-IP": 111, + "VRRP": 112, + "PGM": 113, + "L2TP": 115, + "DDX": 116, + "IATP": 117, + "STP": 118, + "SRP": 119, + "UTI": 120, + "SMP": 121, + "SM": 122, + "PTP": 123, + "ISIS over IPv4": 124, + "FIRE": 125, + "CRTP": 126, + "CRUDP": 127, + "SSCOPMCE": 128, + "IPLT": 129, + "SPS": 130, + "PIPE": 131, + "SCTP": 132, + "FC": 133, + "RSVP-E2E-IGNORE": 134, + "Mobility Header": 135, + "UDPLite": 136, + "MPLS-in-IP": 137, + "manet": 138, + "HIP": 139, + "Shim6": 140, + "WESP": 141, + "ROHC": 142, + "Ethernet": 143, + "AGGFRAG": 144, + "NSH": 145, + "Reserved": 255, +} + +PROTO_NUM_TO_NAME: Dict[int, str] = { + 0: "HOPOPT", + 1: "ICMP", + 2: "IGMP", + 3: "GGP", + 4: "IPv4", + 5: "ST", + 6: "TCP", + 7: "CBT", + 8: "EGP", + 9: "IGP", + 10: "BBN-RCC-MON", + 11: "NVP-II", + 12: "PUP", + 13: "ARGUS", + 14: "EMCON", + 15: "XNET", + 16: "CHAOS", + 17: "UDP", + 18: "MUX", + 19: "DCN-MEAS", + 20: "HMP", + 21: "PRM", + 22: "XNS-IDP", + 23: "TRUNK-1", + 24: "TRUNK-2", + 25: "LEAF-1", + 26: "LEAF-2", + 27: "RDP", + 28: "IRTP", + 29: "ISO-TP4", + 30: "NETBLT", + 31: "MFE-NSP", + 32: "MERIT-INP", + 33: "DCCP", + 34: "3PC", + 35: "IDPR", + 36: "XTP", + 37: "DDP", + 38: "IDPR-CMTP", + 39: "TP++", + 40: "IL", + 41: "IPv6", + 42: "SDRP", + 43: "IPv6-Route", + 44: "IPv6-Frag", + 45: "IDRP", + 46: "RSVP", + 47: "GRE", + 48: "DSR", + 49: "BNA", + 50: "ESP", + 51: "AH", + 52: "I-NLSP", + 53: "SWIPE", + 54: "NARP", + 55: "Min-IPv4", + 56: "TLSP", + 57: "SKIP", + 58: "IPv6-ICMP", + 59: "IPv6-NoNxt", + 60: "IPv6-Opts", + 62: "CFTP", + 64: "SAT-EXPAK", + 65: "KRYPTOLAN", + 66: "RVD", + 67: "IPPC", + 69: "SAT-MON", + 70: "VISA", + 71: "IPCV", + 72: "CPNX", + 73: "CPHB", + 74: "WSN", + 75: "PVP", + 76: "BR-SAT-MON", + 77: "SUN-ND", + 78: "WB-MON", + 79: "WB-EXPAK", + 80: "ISO-IP", + 81: "VMTP", + 82: "SECURE-VMTP", + 83: "VINES", + 84: "IPTM", + 85: "NSFNET-IGP", + 86: "DGP", + 87: "TCF", + 88: "EIGRP", + 89: "OSPFIGP", + 90: "Sprite-RPC", + 91: "LARP", + 92: "MTP", + 93: "AX.25", + 94: "IPIP", + 95: "MICP", + 96: "SCC-SP", + 97: "ETHERIP", + 98: "ENCAP", + 100: "GMTP", + 101: "IFMP", + 102: "PNNI", + 103: "PIM", + 104: "ARIS", + 105: "SCPS", + 106: "QNX", + 107: "A/N", + 108: "IPComp", + 109: "SNP", + 110: "Compaq-Peer", + 111: "IPX-in-IP", + 112: "VRRP", + 113: "PGM", + 115: "L2TP", + 116: "DDX", + 117: "IATP", + 118: "STP", + 119: "SRP", + 120: "UTI", + 121: "SMP", + 122: "SM", + 123: "PTP", + 124: "ISIS over IPv4", + 125: "FIRE", + 126: "CRTP", + 127: "CRUDP", + 128: "SSCOPMCE", + 129: "IPLT", + 130: "SPS", + 131: "PIPE", + 132: "SCTP", + 133: "FC", + 134: "RSVP-E2E-IGNORE", + 135: "Mobility Header", + 136: "UDPLite", + 137: "MPLS-in-IP", + 138: "manet", + 139: "HIP", + 140: "Shim6", + 141: "WESP", + 142: "ROHC", + 143: "Ethernet", + 144: "AGGFRAG", + 145: "NSH", + 255: "Reserved", +} diff --git a/netutils/protocol_mapper.py b/netutils/protocol_mapper.py index 74f9ea28..4f3bceef 100644 --- a/netutils/protocol_mapper.py +++ b/netutils/protocol_mapper.py @@ -2,6 +2,10 @@ import typing as t from netutils.constants import PROTOCOLS +from netutils.data_files.protocol_number_mappings import ( # noqa: F401 # pylint:disable=unused-import + PROTO_NAME_TO_NUM, + PROTO_NUM_TO_NAME, +) def _number_to_name_mapper(proto: str) -> t.Dict[int, str]: @@ -46,134 +50,3 @@ def _number_to_name_mapper(proto: str) -> t.Dict[int, str]: # DCCP port name to number mapping DCCP_NAME_TO_NUM = {value: key for (key, value) in DCCP_NUM_TO_NAME.items()} - -"""Mappers used to take protocol number-->name and vice-versa. Number needed for test command, name needed for test command if querying by application-id.""" - -# Protocol mapping based on https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml. -PROTO_NAME_TO_NUM = { - "ICMP": 1, - "IGMP": 2, - "GGP": 3, - "TCP": 6, - "CBT": 7, - "EGP": 8, - "IGP": 9, - "BBN-RCC-MON": 10, - "NVP-II": 11, - "PUP": 12, - "EMCON": 14, - "XNET": 15, - "CHAOS": 16, - "UDP": 17, - "MUX": 18, - "DCN-MEAS": 19, - "HMP": 20, - "PRM": 21, - "XNS-IDP": 22, - "TRUNK-1": 23, - "TRUNK-2": 24, - "LEAF-1": 25, - "LEAF-2": 26, - "RDP": 27, - "IRTP": 28, - "ISO-TP4": 29, - "NETBLT": 30, - "MFE-NSP": 31, - "MERIT-INP": 32, - "DCCP": 33, - "3PC": 34, - "IDPR": 35, - "XTP": 36, - "DDP": 37, - "IDPR-CMTP": 38, - "TP++": 39, - "IL": 40, - "SDRP": 42, - "IDRP": 45, - "RSVP": 46, - "GRE": 47, - "DSR": 48, - "BNA": 49, - "ESP": 50, - "AH": 51, - "I-NLSP": 52, - "NARP": 54, - "MOBILE": 55, - "TLSP": 56, - "SKIP": 57, - "CFTP": 62, - "SAT-EXPAK": 64, - "KRYPTOLAN": 65, - "RVD": 66, - "IPPC": 67, - "SAT-MON": 69, - "VISA": 70, - "IPCV": 71, - "CPNX": 72, - "CPHB": 73, - "WSN": 74, - "PVP": 75, - "BR-SAT-MON": 76, - "SUN-ND": 77, - "WB-MON": 78, - "WB-EXPAK": 79, - "ISO-IP": 80, - "VMTP": 81, - "SECURE-VMTP": 82, - "VINES": 83, - "TTP": 84, - "NSFNET-IGP": 85, - "DGP": 86, - "TCF": 87, - "EIGRP": 88, - "OSPFIGP": 89, - "Sprite-RPC": 90, - "LARP": 91, - "MTP": 92, - "AX.25": 93, - "IPIP": 94, - "SCC-SP": 96, - "ETHERIP": 97, - "ENCAP": 98, - "GMTP": 100, - "IFMP": 101, - "PNNI": 102, - "PIM": 103, - "ARIS": 104, - "SCPS": 105, - "QNX": 106, - "A/N": 107, - "IPComp": 108, - "SNP": 109, - "Compaq-Peer": 110, - "IPX-in-IP": 111, - "PGM": 113, - "L2TP": 115, - "DDX": 116, - "IATP": 117, - "STP": 118, - "SRP": 119, - "UTI": 120, - "SMP": 121, - "SM": 122, - "PTP": 123, - "FIRE": 125, - "CRTP": 126, - "CRUDP": 127, - "SSCOPMCE": 128, - "IPLT": 129, - "SPS": 130, - "PIPE": 131, - "SCTP": 132, - "FC": 133, - "RSVP-E2E-IGNORE": 134, - "UDPLite": 136, - "manet": 138, - "HIP": 139, - "WESP": 141, - "ROHC": 142, - "Ethernet": 143, -} - -# Reverse the key value pair for reverse lookup. -PROTO_NUM_TO_NAME = {value: key for (key, value) in PROTO_NAME_TO_NUM.items()}