github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/internal/iana/gen.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build ignore 6 7 //go:generate go run gen.go 8 9 // This program generates internet protocol constants and tables by 10 // reading IANA protocol registries. 11 package main 12 13 import ( 14 "bytes" 15 "encoding/xml" 16 "fmt" 17 "go/format" 18 "io" 19 "io/ioutil" 20 "net/http" 21 "os" 22 "strconv" 23 "strings" 24 ) 25 26 var registries = []struct { 27 url string 28 parse func(io.Writer, io.Reader) error 29 }{ 30 { 31 "http://www.iana.org/assignments/dscp-registry/dscp-registry.xml", 32 parseDSCPRegistry, 33 }, 34 { 35 "http://www.iana.org/assignments/ipv4-tos-byte/ipv4-tos-byte.xml", 36 parseTOSTCByte, 37 }, 38 { 39 "http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml", 40 parseProtocolNumbers, 41 }, 42 } 43 44 func main() { 45 var bb bytes.Buffer 46 fmt.Fprintf(&bb, "// go generate gen.go\n") 47 fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n") 48 fmt.Fprintf(&bb, "// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).\n") 49 fmt.Fprintf(&bb, `package iana // import "golang.org/x/net/internal/iana"`+"\n\n") 50 for _, r := range registries { 51 resp, err := http.Get(r.url) 52 if err != nil { 53 fmt.Fprintln(os.Stderr, err) 54 os.Exit(1) 55 } 56 defer resp.Body.Close() 57 if resp.StatusCode != http.StatusOK { 58 fmt.Fprintf(os.Stderr, "got HTTP status code %v for %v\n", resp.StatusCode, r.url) 59 os.Exit(1) 60 } 61 if err := r.parse(&bb, resp.Body); err != nil { 62 fmt.Fprintln(os.Stderr, err) 63 os.Exit(1) 64 } 65 fmt.Fprintf(&bb, "\n") 66 } 67 b, err := format.Source(bb.Bytes()) 68 if err != nil { 69 fmt.Fprintln(os.Stderr, err) 70 os.Exit(1) 71 } 72 if err := ioutil.WriteFile("const.go", b, 0644); err != nil { 73 fmt.Fprintln(os.Stderr, err) 74 os.Exit(1) 75 } 76 } 77 78 func parseDSCPRegistry(w io.Writer, r io.Reader) error { 79 dec := xml.NewDecoder(r) 80 var dr dscpRegistry 81 if err := dec.Decode(&dr); err != nil { 82 return err 83 } 84 drs := dr.escape() 85 fmt.Fprintf(w, "// %s, Updated: %s\n", dr.Title, dr.Updated) 86 fmt.Fprintf(w, "const (\n") 87 for _, dr := range drs { 88 fmt.Fprintf(w, "DiffServ%s = %#x", dr.Name, dr.Value) 89 fmt.Fprintf(w, "// %s\n", dr.OrigName) 90 } 91 fmt.Fprintf(w, ")\n") 92 return nil 93 } 94 95 type dscpRegistry struct { 96 XMLName xml.Name `xml:"registry"` 97 Title string `xml:"title"` 98 Updated string `xml:"updated"` 99 Note string `xml:"note"` 100 RegTitle string `xml:"registry>title"` 101 PoolRecords []struct { 102 Name string `xml:"name"` 103 Space string `xml:"space"` 104 } `xml:"registry>record"` 105 Records []struct { 106 Name string `xml:"name"` 107 Space string `xml:"space"` 108 } `xml:"registry>registry>record"` 109 } 110 111 type canonDSCPRecord struct { 112 OrigName string 113 Name string 114 Value int 115 } 116 117 func (drr *dscpRegistry) escape() []canonDSCPRecord { 118 drs := make([]canonDSCPRecord, len(drr.Records)) 119 sr := strings.NewReplacer( 120 "+", "", 121 "-", "", 122 "/", "", 123 ".", "", 124 " ", "", 125 ) 126 for i, dr := range drr.Records { 127 s := strings.TrimSpace(dr.Name) 128 drs[i].OrigName = s 129 drs[i].Name = sr.Replace(s) 130 n, err := strconv.ParseUint(dr.Space, 2, 8) 131 if err != nil { 132 continue 133 } 134 drs[i].Value = int(n) << 2 135 } 136 return drs 137 } 138 139 func parseTOSTCByte(w io.Writer, r io.Reader) error { 140 dec := xml.NewDecoder(r) 141 var ttb tosTCByte 142 if err := dec.Decode(&ttb); err != nil { 143 return err 144 } 145 trs := ttb.escape() 146 fmt.Fprintf(w, "// %s, Updated: %s\n", ttb.Title, ttb.Updated) 147 fmt.Fprintf(w, "const (\n") 148 for _, tr := range trs { 149 fmt.Fprintf(w, "%s = %#x", tr.Keyword, tr.Value) 150 fmt.Fprintf(w, "// %s\n", tr.OrigKeyword) 151 } 152 fmt.Fprintf(w, ")\n") 153 return nil 154 } 155 156 type tosTCByte struct { 157 XMLName xml.Name `xml:"registry"` 158 Title string `xml:"title"` 159 Updated string `xml:"updated"` 160 Note string `xml:"note"` 161 RegTitle string `xml:"registry>title"` 162 Records []struct { 163 Binary string `xml:"binary"` 164 Keyword string `xml:"keyword"` 165 } `xml:"registry>record"` 166 } 167 168 type canonTOSTCByteRecord struct { 169 OrigKeyword string 170 Keyword string 171 Value int 172 } 173 174 func (ttb *tosTCByte) escape() []canonTOSTCByteRecord { 175 trs := make([]canonTOSTCByteRecord, len(ttb.Records)) 176 sr := strings.NewReplacer( 177 "Capable", "", 178 "(", "", 179 ")", "", 180 "+", "", 181 "-", "", 182 "/", "", 183 ".", "", 184 " ", "", 185 ) 186 for i, tr := range ttb.Records { 187 s := strings.TrimSpace(tr.Keyword) 188 trs[i].OrigKeyword = s 189 ss := strings.Split(s, " ") 190 if len(ss) > 1 { 191 trs[i].Keyword = strings.Join(ss[1:], " ") 192 } else { 193 trs[i].Keyword = ss[0] 194 } 195 trs[i].Keyword = sr.Replace(trs[i].Keyword) 196 n, err := strconv.ParseUint(tr.Binary, 2, 8) 197 if err != nil { 198 continue 199 } 200 trs[i].Value = int(n) 201 } 202 return trs 203 } 204 205 func parseProtocolNumbers(w io.Writer, r io.Reader) error { 206 dec := xml.NewDecoder(r) 207 var pn protocolNumbers 208 if err := dec.Decode(&pn); err != nil { 209 return err 210 } 211 prs := pn.escape() 212 prs = append([]canonProtocolRecord{{ 213 Name: "IP", 214 Descr: "IPv4 encapsulation, pseudo protocol number", 215 Value: 0, 216 }}, prs...) 217 fmt.Fprintf(w, "// %s, Updated: %s\n", pn.Title, pn.Updated) 218 fmt.Fprintf(w, "const (\n") 219 for _, pr := range prs { 220 if pr.Name == "" { 221 continue 222 } 223 fmt.Fprintf(w, "Protocol%s = %d", pr.Name, pr.Value) 224 s := pr.Descr 225 if s == "" { 226 s = pr.OrigName 227 } 228 fmt.Fprintf(w, "// %s\n", s) 229 } 230 fmt.Fprintf(w, ")\n") 231 return nil 232 } 233 234 type protocolNumbers struct { 235 XMLName xml.Name `xml:"registry"` 236 Title string `xml:"title"` 237 Updated string `xml:"updated"` 238 RegTitle string `xml:"registry>title"` 239 Note string `xml:"registry>note"` 240 Records []struct { 241 Value string `xml:"value"` 242 Name string `xml:"name"` 243 Descr string `xml:"description"` 244 } `xml:"registry>record"` 245 } 246 247 type canonProtocolRecord struct { 248 OrigName string 249 Name string 250 Descr string 251 Value int 252 } 253 254 func (pn *protocolNumbers) escape() []canonProtocolRecord { 255 prs := make([]canonProtocolRecord, len(pn.Records)) 256 sr := strings.NewReplacer( 257 "-in-", "in", 258 "-within-", "within", 259 "-over-", "over", 260 "+", "P", 261 "-", "", 262 "/", "", 263 ".", "", 264 " ", "", 265 ) 266 for i, pr := range pn.Records { 267 if strings.Contains(pr.Name, "Deprecated") || 268 strings.Contains(pr.Name, "deprecated") { 269 continue 270 } 271 prs[i].OrigName = pr.Name 272 s := strings.TrimSpace(pr.Name) 273 switch pr.Name { 274 case "ISIS over IPv4": 275 prs[i].Name = "ISIS" 276 case "manet": 277 prs[i].Name = "MANET" 278 default: 279 prs[i].Name = sr.Replace(s) 280 } 281 ss := strings.Split(pr.Descr, "\n") 282 for i := range ss { 283 ss[i] = strings.TrimSpace(ss[i]) 284 } 285 if len(ss) > 1 { 286 prs[i].Descr = strings.Join(ss, " ") 287 } else { 288 prs[i].Descr = ss[0] 289 } 290 prs[i].Value, _ = strconv.Atoi(pr.Value) 291 } 292 return prs 293 }