| // Copyright 2012 Google, Inc. All rights reserved. |
| // |
| // Use of this source code is governed by a BSD-style license |
| // that can be found in the LICENSE file in the root of the source |
| // tree. |
| |
| // +build ignore |
| |
| // This binary pulls known ports from IANA, and uses them to populate |
| // iana_ports.go's TCPPortNames and UDPPortNames maps. |
| // |
| // go run gen.go | gofmt > iana_ports.go |
| package main |
| |
| import ( |
| "bytes" |
| "encoding/xml" |
| "flag" |
| "fmt" |
| "io/ioutil" |
| "net/http" |
| "os" |
| "strconv" |
| "time" |
| ) |
| |
| const fmtString = `// Copyright 2012 Google, Inc. All rights reserved. |
| |
| package layers |
| |
| // Created by gen.go, don't edit manually |
| // Generated at %s |
| // Fetched from %q |
| |
| // TCPPortNames contains the port names for all TCP ports. |
| var TCPPortNames = tcpPortNames |
| |
| // UDPPortNames contains the port names for all UDP ports. |
| var UDPPortNames = udpPortNames |
| |
| // SCTPPortNames contains the port names for all SCTP ports. |
| var SCTPPortNames = sctpPortNames |
| |
| var tcpPortNames = map[TCPPort]string{ |
| %s} |
| var udpPortNames = map[UDPPort]string{ |
| %s} |
| var sctpPortNames = map[SCTPPort]string{ |
| %s} |
| ` |
| |
| var url = flag.String("url", "http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml", "URL to grab port numbers from") |
| |
| func main() { |
| fmt.Fprintf(os.Stderr, "Fetching ports from %q\n", *url) |
| resp, err := http.Get(*url) |
| if err != nil { |
| panic(err) |
| } |
| defer resp.Body.Close() |
| body, err := ioutil.ReadAll(resp.Body) |
| if err != nil { |
| panic(err) |
| } |
| fmt.Fprintln(os.Stderr, "Parsing XML") |
| var registry struct { |
| Records []struct { |
| Protocol string `xml:"protocol"` |
| Number string `xml:"number"` |
| Name string `xml:"name"` |
| } `xml:"record"` |
| } |
| xml.Unmarshal(body, ®istry) |
| var tcpPorts bytes.Buffer |
| var udpPorts bytes.Buffer |
| var sctpPorts bytes.Buffer |
| done := map[string]map[int]bool{ |
| "tcp": map[int]bool{}, |
| "udp": map[int]bool{}, |
| "sctp": map[int]bool{}, |
| } |
| for _, r := range registry.Records { |
| port, err := strconv.Atoi(r.Number) |
| if err != nil { |
| continue |
| } |
| if r.Name == "" { |
| continue |
| } |
| var b *bytes.Buffer |
| switch r.Protocol { |
| case "tcp": |
| b = &tcpPorts |
| case "udp": |
| b = &udpPorts |
| case "sctp": |
| b = &sctpPorts |
| default: |
| continue |
| } |
| if done[r.Protocol][port] { |
| continue |
| } |
| done[r.Protocol][port] = true |
| fmt.Fprintf(b, "\t%d: %q,\n", port, r.Name) |
| } |
| fmt.Fprintln(os.Stderr, "Writing results to stdout") |
| fmt.Printf(fmtString, time.Now(), *url, tcpPorts.String(), udpPorts.String(), sctpPorts.String()) |
| } |