blob: ab7a0c001f2d643b66f8c9c043e428c968b89c53 [file] [log] [blame]
Scott Bakerb90c4312020-03-12 21:33:25 -07001// Copyright 2012 Google, Inc. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style license
4// that can be found in the LICENSE file in the root of the source
5// tree.
6
7// +build ignore
8
9// This binary pulls known ports from IANA, and uses them to populate
10// iana_ports.go's TCPPortNames and UDPPortNames maps.
11//
12// go run gen.go | gofmt > iana_ports.go
13package main
14
15import (
16 "bytes"
17 "encoding/xml"
18 "flag"
19 "fmt"
20 "io/ioutil"
21 "net/http"
22 "os"
23 "strconv"
24 "time"
25)
26
27const fmtString = `// Copyright 2012 Google, Inc. All rights reserved.
28
29package layers
30
31// Created by gen.go, don't edit manually
32// Generated at %s
33// Fetched from %q
34
35// TCPPortNames contains the port names for all TCP ports.
36var TCPPortNames = tcpPortNames
37
38// UDPPortNames contains the port names for all UDP ports.
39var UDPPortNames = udpPortNames
40
41// SCTPPortNames contains the port names for all SCTP ports.
42var SCTPPortNames = sctpPortNames
43
44var tcpPortNames = map[TCPPort]string{
45%s}
46var udpPortNames = map[UDPPort]string{
47%s}
48var sctpPortNames = map[SCTPPort]string{
49%s}
50`
51
52var url = flag.String("url", "http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml", "URL to grab port numbers from")
53
54func main() {
55 fmt.Fprintf(os.Stderr, "Fetching ports from %q\n", *url)
56 resp, err := http.Get(*url)
57 if err != nil {
58 panic(err)
59 }
60 defer resp.Body.Close()
61 body, err := ioutil.ReadAll(resp.Body)
62 if err != nil {
63 panic(err)
64 }
65 fmt.Fprintln(os.Stderr, "Parsing XML")
66 var registry struct {
67 Records []struct {
68 Protocol string `xml:"protocol"`
69 Number string `xml:"number"`
70 Name string `xml:"name"`
71 } `xml:"record"`
72 }
73 xml.Unmarshal(body, &registry)
74 var tcpPorts bytes.Buffer
75 var udpPorts bytes.Buffer
76 var sctpPorts bytes.Buffer
77 done := map[string]map[int]bool{
78 "tcp": map[int]bool{},
79 "udp": map[int]bool{},
80 "sctp": map[int]bool{},
81 }
82 for _, r := range registry.Records {
83 port, err := strconv.Atoi(r.Number)
84 if err != nil {
85 continue
86 }
87 if r.Name == "" {
88 continue
89 }
90 var b *bytes.Buffer
91 switch r.Protocol {
92 case "tcp":
93 b = &tcpPorts
94 case "udp":
95 b = &udpPorts
96 case "sctp":
97 b = &sctpPorts
98 default:
99 continue
100 }
101 if done[r.Protocol][port] {
102 continue
103 }
104 done[r.Protocol][port] = true
105 fmt.Fprintf(b, "\t%d: %q,\n", port, r.Name)
106 }
107 fmt.Fprintln(os.Stderr, "Writing results to stdout")
108 fmt.Printf(fmtString, time.Now(), *url, tcpPorts.String(), udpPorts.String(), sctpPorts.String())
109}