go.net/ipv4: make use of internal/{iana,icmp} packages
LGTM=iant
R=iant
CC=golang-codereviews
https://golang.org/cl/154880043
diff --git a/ipv4/control_bsd.go b/ipv4/control_bsd.go
index 97f36bf..51076e6 100644
--- a/ipv4/control_bsd.go
+++ b/ipv4/control_bsd.go
@@ -10,11 +10,13 @@
"net"
"syscall"
"unsafe"
+
+ "code.google.com/p/go.net/internal/iana"
)
func marshalDst(b []byte, cm *ControlMessage) []byte {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
- m.Level = ianaProtocolIP
+ m.Level = iana.ProtocolIP
m.Type = sysIP_RECVDSTADDR
m.SetLen(syscall.CmsgLen(net.IPv4len))
return b[syscall.CmsgSpace(net.IPv4len):]
@@ -26,7 +28,7 @@
func marshalInterface(b []byte, cm *ControlMessage) []byte {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
- m.Level = ianaProtocolIP
+ m.Level = iana.ProtocolIP
m.Type = sysIP_RECVIF
m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrDatalink))
return b[syscall.CmsgSpace(syscall.SizeofSockaddrDatalink):]
diff --git a/ipv4/control_pktinfo.go b/ipv4/control_pktinfo.go
index 2613599..5ad3b61 100644
--- a/ipv4/control_pktinfo.go
+++ b/ipv4/control_pktinfo.go
@@ -9,11 +9,13 @@
import (
"syscall"
"unsafe"
+
+ "code.google.com/p/go.net/internal/iana"
)
func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
- m.Level = ianaProtocolIP
+ m.Level = iana.ProtocolIP
m.Type = sysIP_PKTINFO
m.SetLen(syscall.CmsgLen(sysSizeofInetPktinfo))
if cm != nil {
diff --git a/ipv4/control_unix.go b/ipv4/control_unix.go
index 04f0330..6505247 100644
--- a/ipv4/control_unix.go
+++ b/ipv4/control_unix.go
@@ -10,6 +10,8 @@
"os"
"syscall"
"unsafe"
+
+ "code.google.com/p/go.net/internal/iana"
)
func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
@@ -112,7 +114,7 @@
}
cm := &ControlMessage{}
for _, m := range cmsgs {
- if m.Header.Level != ianaProtocolIP {
+ if m.Header.Level != iana.ProtocolIP {
continue
}
switch int(m.Header.Type) {
@@ -153,7 +155,7 @@
func marshalTTL(b []byte, cm *ControlMessage) []byte {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
- m.Level = ianaProtocolIP
+ m.Level = iana.ProtocolIP
m.Type = sysIP_RECVTTL
m.SetLen(syscall.CmsgLen(1))
return b[syscall.CmsgSpace(1):]
diff --git a/ipv4/example_test.go b/ipv4/example_test.go
index bd4dc67..2b0f646 100644
--- a/ipv4/example_test.go
+++ b/ipv4/example_test.go
@@ -5,9 +5,11 @@
package ipv4_test
import (
- "code.google.com/p/go.net/ipv4"
"log"
"net"
+
+ "code.google.com/p/go.net/internal/iana"
+ "code.google.com/p/go.net/ipv4"
)
func ExampleUnicastTCPListener() {
@@ -23,7 +25,7 @@
}
go func(c net.Conn) {
defer c.Close()
- err := ipv4.NewConn(c).SetTOS(DiffServAF11)
+ err := ipv4.NewConn(c).SetTOS(iana.DiffServAF11)
if err != nil {
log.Fatal(err)
}
@@ -81,7 +83,7 @@
continue
}
}
- p.SetTOS(DiffServCS7)
+ p.SetTOS(iana.DiffServCS7)
p.SetTTL(16)
_, err = p.WriteTo(b[:n], nil, src)
if err != nil {
@@ -175,7 +177,7 @@
if err != nil {
log.Fatal(err)
}
- r.SetTOS(DiffServCS6)
+ r.SetTOS(iana.DiffServCS6)
parseOSPFHeader := func(b []byte) *OSPFHeader {
if len(b) < OSPFHeaderLen {
@@ -264,7 +266,7 @@
iph := &ipv4.Header{}
iph.Version = ipv4.Version
iph.Len = ipv4.HeaderLen
- iph.TOS = DiffServCS6
+ iph.TOS = iana.DiffServCS6
iph.TotalLen = ipv4.HeaderLen + len(ospf)
iph.TTL = 1
iph.Protocol = 89
diff --git a/ipv4/gen.go b/ipv4/gen.go
index d7aea51..f2721a5 100644
--- a/ipv4/gen.go
+++ b/ipv4/gen.go
@@ -4,11 +4,10 @@
// +build ignore
+//go:generate go run gen.go
+
// This program generates internet protocol constants and tables by
// reading IANA protocol registries.
-//
-// Usage of this program:
-// go run gen.go > iana.go
package main
import (
@@ -17,6 +16,7 @@
"fmt"
"go/format"
"io"
+ "io/ioutil"
"net/http"
"os"
"strconv"
@@ -31,15 +31,11 @@
"http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xml",
parseICMPv4Parameters,
},
- {
- "http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml",
- parseProtocolNumbers,
- },
}
func main() {
var bb bytes.Buffer
- fmt.Fprintf(&bb, "// go run gen.go\n")
+ fmt.Fprintf(&bb, "// go generate gen.go\n")
fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n")
fmt.Fprintf(&bb, "package ipv4\n\n")
for _, r := range registries {
@@ -64,7 +60,10 @@
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
- os.Stdout.Write(b)
+ if err := ioutil.WriteFile("iana.go", b, 0644); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
}
func parseICMPv4Parameters(w io.Writer, r io.Reader) error {
@@ -158,89 +157,3 @@
}
return prs
}
-
-func parseProtocolNumbers(w io.Writer, r io.Reader) error {
- dec := xml.NewDecoder(r)
- var pn protocolNumbers
- if err := dec.Decode(&pn); err != nil {
- return err
- }
- prs := pn.escape()
- prs = append([]canonProtocolRecord{{
- Name: "IP",
- Descr: "IPv4 encapsulation, pseudo protocol number",
- Value: 0,
- }}, prs...)
- fmt.Fprintf(w, "// %s, Updated: %s\n", pn.Title, pn.Updated)
- fmt.Fprintf(w, "const (\n")
- for _, pr := range prs {
- if pr.Name == "" {
- continue
- }
- fmt.Fprintf(w, "ianaProtocol%s = %d", pr.Name, pr.Value)
- s := pr.Descr
- if s == "" {
- s = pr.OrigName
- }
- fmt.Fprintf(w, "// %s\n", s)
- }
- fmt.Fprintf(w, ")\n")
- return nil
-}
-
-type protocolNumbers struct {
- XMLName xml.Name `xml:"registry"`
- Title string `xml:"title"`
- Updated string `xml:"updated"`
- RegTitle string `xml:"registry>title"`
- Note string `xml:"registry>note"`
- Records []struct {
- Value string `xml:"value"`
- Name string `xml:"name"`
- Descr string `xml:"description"`
- } `xml:"registry>record"`
-}
-
-type canonProtocolRecord struct {
- OrigName string
- Name string
- Descr string
- Value int
-}
-
-func (pn *protocolNumbers) escape() []canonProtocolRecord {
- prs := make([]canonProtocolRecord, len(pn.Records))
- sr := strings.NewReplacer(
- "-in-", "in",
- "-within-", "within",
- "-over-", "over",
- "+", "P",
- "-", "",
- "/", "",
- ".", "",
- " ", "",
- )
- for i, pr := range pn.Records {
- prs[i].OrigName = pr.Name
- s := strings.TrimSpace(pr.Name)
- switch pr.Name {
- case "ISIS over IPv4":
- prs[i].Name = "ISIS"
- case "manet":
- prs[i].Name = "MANET"
- default:
- prs[i].Name = sr.Replace(s)
- }
- ss := strings.Split(pr.Descr, "\n")
- for i := range ss {
- ss[i] = strings.TrimSpace(ss[i])
- }
- if len(ss) > 1 {
- prs[i].Descr = strings.Join(ss, " ")
- } else {
- prs[i].Descr = ss[0]
- }
- prs[i].Value, _ = strconv.Atoi(pr.Value)
- }
- return prs
-}
diff --git a/ipv4/gentest.go b/ipv4/gentest.go
deleted file mode 100644
index 3b21d7a..0000000
--- a/ipv4/gentest.go
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// This program generates internet protocol constants by reading IANA
-// protocol registries.
-//
-// Usage:
-// go run gentest.go > iana_test.go
-package main
-
-import (
- "bytes"
- "encoding/xml"
- "fmt"
- "go/format"
- "io"
- "net/http"
- "os"
- "strconv"
- "strings"
-)
-
-var registries = []struct {
- url string
- parse func(io.Writer, io.Reader) error
-}{
- {
- "http://www.iana.org/assignments/dscp-registry/dscp-registry.xml",
- parseDSCPRegistry,
- },
- {
- "http://www.iana.org/assignments/ipv4-tos-byte/ipv4-tos-byte.xml",
- parseTOSTCByte,
- },
-}
-
-func main() {
- var bb bytes.Buffer
- fmt.Fprintf(&bb, "// go run gentest.go\n")
- fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n")
- fmt.Fprintf(&bb, "package ipv4_test\n\n")
- for _, r := range registries {
- resp, err := http.Get(r.url)
- if err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- defer resp.Body.Close()
- if resp.StatusCode != http.StatusOK {
- fmt.Fprintf(os.Stderr, "got HTTP status code %v for %v\n", resp.StatusCode, r.url)
- os.Exit(1)
- }
- if err := r.parse(&bb, resp.Body); err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- fmt.Fprintf(&bb, "\n")
- }
- b, err := format.Source(bb.Bytes())
- if err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- os.Stdout.Write(b)
-}
-
-func parseDSCPRegistry(w io.Writer, r io.Reader) error {
- dec := xml.NewDecoder(r)
- var dr dscpRegistry
- if err := dec.Decode(&dr); err != nil {
- return err
- }
- drs := dr.escape()
- fmt.Fprintf(w, "// %s, Updated: %s\n", dr.Title, dr.Updated)
- fmt.Fprintf(w, "const (\n")
- for _, dr := range drs {
- fmt.Fprintf(w, "DiffServ%s = %#x", dr.Name, dr.Value)
- fmt.Fprintf(w, "// %s\n", dr.OrigName)
- }
- fmt.Fprintf(w, ")\n")
- return nil
-}
-
-type dscpRegistry struct {
- XMLName xml.Name `xml:"registry"`
- Title string `xml:"title"`
- Updated string `xml:"updated"`
- Note string `xml:"note"`
- RegTitle string `xml:"registry>title"`
- PoolRecords []struct {
- Name string `xml:"name"`
- Space string `xml:"space"`
- } `xml:"registry>record"`
- Records []struct {
- Name string `xml:"name"`
- Space string `xml:"space"`
- } `xml:"registry>registry>record"`
-}
-
-type canonDSCPRecord struct {
- OrigName string
- Name string
- Value int
-}
-
-func (drr *dscpRegistry) escape() []canonDSCPRecord {
- drs := make([]canonDSCPRecord, len(drr.Records))
- sr := strings.NewReplacer(
- "+", "",
- "-", "",
- "/", "",
- ".", "",
- " ", "",
- )
- for i, dr := range drr.Records {
- s := strings.TrimSpace(dr.Name)
- drs[i].OrigName = s
- drs[i].Name = sr.Replace(s)
- n, err := strconv.ParseUint(dr.Space, 2, 8)
- if err != nil {
- continue
- }
- drs[i].Value = int(n) << 2
- }
- return drs
-}
-
-func parseTOSTCByte(w io.Writer, r io.Reader) error {
- dec := xml.NewDecoder(r)
- var ttb tosTCByte
- if err := dec.Decode(&ttb); err != nil {
- return err
- }
- trs := ttb.escape()
- fmt.Fprintf(w, "// %s, Updated: %s\n", ttb.Title, ttb.Updated)
- fmt.Fprintf(w, "const (\n")
- for _, tr := range trs {
- fmt.Fprintf(w, "%s = %#x", tr.Keyword, tr.Value)
- fmt.Fprintf(w, "// %s\n", tr.OrigKeyword)
- }
- fmt.Fprintf(w, ")\n")
- return nil
-}
-
-type tosTCByte struct {
- XMLName xml.Name `xml:"registry"`
- Title string `xml:"title"`
- Updated string `xml:"updated"`
- Note string `xml:"note"`
- RegTitle string `xml:"registry>title"`
- Records []struct {
- Binary string `xml:"binary"`
- Keyword string `xml:"keyword"`
- } `xml:"registry>record"`
-}
-
-type canonTOSTCByteRecord struct {
- OrigKeyword string
- Keyword string
- Value int
-}
-
-func (ttb *tosTCByte) escape() []canonTOSTCByteRecord {
- trs := make([]canonTOSTCByteRecord, len(ttb.Records))
- sr := strings.NewReplacer(
- "Capable", "",
- "(", "",
- ")", "",
- "+", "",
- "-", "",
- "/", "",
- ".", "",
- " ", "",
- )
- for i, tr := range ttb.Records {
- s := strings.TrimSpace(tr.Keyword)
- trs[i].OrigKeyword = s
- ss := strings.Split(s, " ")
- if len(ss) > 1 {
- trs[i].Keyword = strings.Join(ss[1:], " ")
- } else {
- trs[i].Keyword = ss[0]
- }
- trs[i].Keyword = sr.Replace(trs[i].Keyword)
- n, err := strconv.ParseUint(tr.Binary, 2, 8)
- if err != nil {
- continue
- }
- trs[i].Value = int(n)
- }
- return trs
-}
diff --git a/ipv4/iana.go b/ipv4/iana.go
index 254d019..be10c94 100644
--- a/ipv4/iana.go
+++ b/ipv4/iana.go
@@ -1,4 +1,4 @@
-// go run gen.go
+// go generate gen.go
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
package ipv4
@@ -32,148 +32,3 @@
14: "timestamp reply",
40: "photuris",
}
-
-// Protocol Numbers, Updated: 2013-02-17
-const (
- ianaProtocolIP = 0 // IPv4 encapsulation, pseudo protocol number
- ianaProtocolHOPOPT = 0 // IPv6 Hop-by-Hop Option
- ianaProtocolICMP = 1 // Internet Control Message
- ianaProtocolIGMP = 2 // Internet Group Management
- ianaProtocolGGP = 3 // Gateway-to-Gateway
- ianaProtocolIPv4 = 4 // IPv4 encapsulation
- ianaProtocolST = 5 // Stream
- ianaProtocolTCP = 6 // Transmission Control
- ianaProtocolCBT = 7 // CBT
- ianaProtocolEGP = 8 // Exterior Gateway Protocol
- ianaProtocolIGP = 9 // any private interior gateway (used by Cisco for their IGRP)
- ianaProtocolBBNRCCMON = 10 // BBN RCC Monitoring
- ianaProtocolNVPII = 11 // Network Voice Protocol
- ianaProtocolPUP = 12 // PUP
- ianaProtocolARGUS = 13 // ARGUS
- ianaProtocolEMCON = 14 // EMCON
- ianaProtocolXNET = 15 // Cross Net Debugger
- ianaProtocolCHAOS = 16 // Chaos
- ianaProtocolUDP = 17 // User Datagram
- ianaProtocolMUX = 18 // Multiplexing
- ianaProtocolDCNMEAS = 19 // DCN Measurement Subsystems
- ianaProtocolHMP = 20 // Host Monitoring
- ianaProtocolPRM = 21 // Packet Radio Measurement
- ianaProtocolXNSIDP = 22 // XEROX NS IDP
- ianaProtocolTRUNK1 = 23 // Trunk-1
- ianaProtocolTRUNK2 = 24 // Trunk-2
- ianaProtocolLEAF1 = 25 // Leaf-1
- ianaProtocolLEAF2 = 26 // Leaf-2
- ianaProtocolRDP = 27 // Reliable Data Protocol
- ianaProtocolIRTP = 28 // Internet Reliable Transaction
- ianaProtocolISOTP4 = 29 // ISO Transport Protocol Class 4
- ianaProtocolNETBLT = 30 // Bulk Data Transfer Protocol
- ianaProtocolMFENSP = 31 // MFE Network Services Protocol
- ianaProtocolMERITINP = 32 // MERIT Internodal Protocol
- ianaProtocolDCCP = 33 // Datagram Congestion Control Protocol
- ianaProtocol3PC = 34 // Third Party Connect Protocol
- ianaProtocolIDPR = 35 // Inter-Domain Policy Routing Protocol
- ianaProtocolXTP = 36 // XTP
- ianaProtocolDDP = 37 // Datagram Delivery Protocol
- ianaProtocolIDPRCMTP = 38 // IDPR Control Message Transport Proto
- ianaProtocolTPPP = 39 // TP++ Transport Protocol
- ianaProtocolIL = 40 // IL Transport Protocol
- ianaProtocolIPv6 = 41 // IPv6 encapsulation
- ianaProtocolSDRP = 42 // Source Demand Routing Protocol
- ianaProtocolIPv6Route = 43 // Routing Header for IPv6
- ianaProtocolIPv6Frag = 44 // Fragment Header for IPv6
- ianaProtocolIDRP = 45 // Inter-Domain Routing Protocol
- ianaProtocolRSVP = 46 // Reservation Protocol
- ianaProtocolGRE = 47 // Generic Routing Encapsulation
- ianaProtocolDSR = 48 // Dynamic Source Routing Protocol
- ianaProtocolBNA = 49 // BNA
- ianaProtocolESP = 50 // Encap Security Payload
- ianaProtocolAH = 51 // Authentication Header
- ianaProtocolINLSP = 52 // Integrated Net Layer Security TUBA
- ianaProtocolSWIPE = 53 // IP with Encryption
- ianaProtocolNARP = 54 // NBMA Address Resolution Protocol
- ianaProtocolMOBILE = 55 // IP Mobility
- ianaProtocolTLSP = 56 // Transport Layer Security Protocol using Kryptonet key management
- ianaProtocolSKIP = 57 // SKIP
- ianaProtocolIPv6ICMP = 58 // ICMP for IPv6
- ianaProtocolIPv6NoNxt = 59 // No Next Header for IPv6
- ianaProtocolIPv6Opts = 60 // Destination Options for IPv6
- ianaProtocolCFTP = 62 // CFTP
- ianaProtocolSATEXPAK = 64 // SATNET and Backroom EXPAK
- ianaProtocolKRYPTOLAN = 65 // Kryptolan
- ianaProtocolRVD = 66 // MIT Remote Virtual Disk Protocol
- ianaProtocolIPPC = 67 // Internet Pluribus Packet Core
- ianaProtocolSATMON = 69 // SATNET Monitoring
- ianaProtocolVISA = 70 // VISA Protocol
- ianaProtocolIPCV = 71 // Internet Packet Core Utility
- ianaProtocolCPNX = 72 // Computer Protocol Network Executive
- ianaProtocolCPHB = 73 // Computer Protocol Heart Beat
- ianaProtocolWSN = 74 // Wang Span Network
- ianaProtocolPVP = 75 // Packet Video Protocol
- ianaProtocolBRSATMON = 76 // Backroom SATNET Monitoring
- ianaProtocolSUNND = 77 // SUN ND PROTOCOL-Temporary
- ianaProtocolWBMON = 78 // WIDEBAND Monitoring
- ianaProtocolWBEXPAK = 79 // WIDEBAND EXPAK
- ianaProtocolISOIP = 80 // ISO Internet Protocol
- ianaProtocolVMTP = 81 // VMTP
- ianaProtocolSECUREVMTP = 82 // SECURE-VMTP
- ianaProtocolVINES = 83 // VINES
- ianaProtocolTTP = 84 // TTP
- ianaProtocolIPTM = 84 // Protocol Internet Protocol Traffic Manager
- ianaProtocolNSFNETIGP = 85 // NSFNET-IGP
- ianaProtocolDGP = 86 // Dissimilar Gateway Protocol
- ianaProtocolTCF = 87 // TCF
- ianaProtocolEIGRP = 88 // EIGRP
- ianaProtocolOSPFIGP = 89 // OSPFIGP
- ianaProtocolSpriteRPC = 90 // Sprite RPC Protocol
- ianaProtocolLARP = 91 // Locus Address Resolution Protocol
- ianaProtocolMTP = 92 // Multicast Transport Protocol
- ianaProtocolAX25 = 93 // AX.25 Frames
- ianaProtocolIPIP = 94 // IP-within-IP Encapsulation Protocol
- ianaProtocolMICP = 95 // Mobile Internetworking Control Pro.
- ianaProtocolSCCSP = 96 // Semaphore Communications Sec. Pro.
- ianaProtocolETHERIP = 97 // Ethernet-within-IP Encapsulation
- ianaProtocolENCAP = 98 // Encapsulation Header
- ianaProtocolGMTP = 100 // GMTP
- ianaProtocolIFMP = 101 // Ipsilon Flow Management Protocol
- ianaProtocolPNNI = 102 // PNNI over IP
- ianaProtocolPIM = 103 // Protocol Independent Multicast
- ianaProtocolARIS = 104 // ARIS
- ianaProtocolSCPS = 105 // SCPS
- ianaProtocolQNX = 106 // QNX
- ianaProtocolAN = 107 // Active Networks
- ianaProtocolIPComp = 108 // IP Payload Compression Protocol
- ianaProtocolSNP = 109 // Sitara Networks Protocol
- ianaProtocolCompaqPeer = 110 // Compaq Peer Protocol
- ianaProtocolIPXinIP = 111 // IPX in IP
- ianaProtocolVRRP = 112 // Virtual Router Redundancy Protocol
- ianaProtocolPGM = 113 // PGM Reliable Transport Protocol
- ianaProtocolL2TP = 115 // Layer Two Tunneling Protocol
- ianaProtocolDDX = 116 // D-II Data Exchange (DDX)
- ianaProtocolIATP = 117 // Interactive Agent Transfer Protocol
- ianaProtocolSTP = 118 // Schedule Transfer Protocol
- ianaProtocolSRP = 119 // SpectraLink Radio Protocol
- ianaProtocolUTI = 120 // UTI
- ianaProtocolSMP = 121 // Simple Message Protocol
- ianaProtocolSM = 122 // SM
- ianaProtocolPTP = 123 // Performance Transparency Protocol
- ianaProtocolISIS = 124 // ISIS over IPv4
- ianaProtocolFIRE = 125 // FIRE
- ianaProtocolCRTP = 126 // Combat Radio Transport Protocol
- ianaProtocolCRUDP = 127 // Combat Radio User Datagram
- ianaProtocolSSCOPMCE = 128 // SSCOPMCE
- ianaProtocolIPLT = 129 // IPLT
- ianaProtocolSPS = 130 // Secure Packet Shield
- ianaProtocolPIPE = 131 // Private IP Encapsulation within IP
- ianaProtocolSCTP = 132 // Stream Control Transmission Protocol
- ianaProtocolFC = 133 // Fibre Channel
- ianaProtocolRSVPE2EIGNORE = 134 // RSVP-E2E-IGNORE
- ianaProtocolMobilityHeader = 135 // Mobility Header
- ianaProtocolUDPLite = 136 // UDPLite
- ianaProtocolMPLSinIP = 137 // MPLS-in-IP
- ianaProtocolMANET = 138 // MANET Protocols
- ianaProtocolHIP = 139 // Host Identity Protocol
- ianaProtocolShim6 = 140 // Shim6 Protocol
- ianaProtocolWESP = 141 // Wrapped Encapsulating Security Payload
- ianaProtocolROHC = 142 // Robust Header Compression
- ianaProtocolReserved = 255 // Reserved
-)
diff --git a/ipv4/iana_test.go b/ipv4/iana_test.go
deleted file mode 100644
index 8f9e7ba..0000000
--- a/ipv4/iana_test.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// go run gentest.go
-// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package ipv4_test
-
-// Differentiated Services Field Codepoints (DSCP), Updated: 2013-06-25
-const (
- DiffServCS0 = 0x0 // CS0
- DiffServCS1 = 0x20 // CS1
- DiffServCS2 = 0x40 // CS2
- DiffServCS3 = 0x60 // CS3
- DiffServCS4 = 0x80 // CS4
- DiffServCS5 = 0xa0 // CS5
- DiffServCS6 = 0xc0 // CS6
- DiffServCS7 = 0xe0 // CS7
- DiffServAF11 = 0x28 // AF11
- DiffServAF12 = 0x30 // AF12
- DiffServAF13 = 0x38 // AF13
- DiffServAF21 = 0x48 // AF21
- DiffServAF22 = 0x50 // AF22
- DiffServAF23 = 0x58 // AF23
- DiffServAF31 = 0x68 // AF31
- DiffServAF32 = 0x70 // AF32
- DiffServAF33 = 0x78 // AF33
- DiffServAF41 = 0x88 // AF41
- DiffServAF42 = 0x90 // AF42
- DiffServAF43 = 0x98 // AF43
- DiffServEFPHB = 0xb8 // EF PHB
- DiffServVOICEADMIT = 0xb0 // VOICE-ADMIT
-)
-
-// IPv4 TOS Byte and IPv6 Traffic Class Octet, Updated: 2001-09-06
-const (
- NotECNTransport = 0x0 // Not-ECT (Not ECN-Capable Transport)
- ECNTransport1 = 0x1 // ECT(1) (ECN-Capable Transport(1))
- ECNTransport0 = 0x2 // ECT(0) (ECN-Capable Transport(0))
- CongestionExperienced = 0x3 // CE (Congestion Experienced)
-)
diff --git a/ipv4/mockicmp_test.go b/ipv4/mockicmp_test.go
deleted file mode 100644
index be328ca..0000000
--- a/ipv4/mockicmp_test.go
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ipv4_test
-
-import (
- "code.google.com/p/go.net/ipv4"
- "errors"
- "flag"
-)
-
-var testExternal = flag.Bool("external", true, "allow use of external networks during long test")
-
-// icmpMessage represents an ICMP message.
-type icmpMessage struct {
- Type ipv4.ICMPType // type
- Code int // code
- Checksum int // checksum
- Body icmpMessageBody // body
-}
-
-// icmpMessageBody represents an ICMP message body.
-type icmpMessageBody interface {
- Len() int
- Marshal() ([]byte, error)
-}
-
-// Marshal returns the binary enconding of the ICMP echo request or
-// reply message m.
-func (m *icmpMessage) Marshal() ([]byte, error) {
- b := []byte{byte(m.Type), byte(m.Code), 0, 0}
- if m.Body != nil && m.Body.Len() != 0 {
- mb, err := m.Body.Marshal()
- if err != nil {
- return nil, err
- }
- b = append(b, mb...)
- }
- csumcv := len(b) - 1 // checksum coverage
- s := uint32(0)
- for i := 0; i < csumcv; i += 2 {
- s += uint32(b[i+1])<<8 | uint32(b[i])
- }
- if csumcv&1 == 0 {
- s += uint32(b[csumcv])
- }
- s = s>>16 + s&0xffff
- s = s + s>>16
- // Place checksum back in header; using ^= avoids the
- // assumption the checksum bytes are zero.
- b[2] ^= byte(^s)
- b[3] ^= byte(^s >> 8)
- return b, nil
-}
-
-// parseICMPMessage parses b as an ICMP message.
-func parseICMPMessage(b []byte) (*icmpMessage, error) {
- msglen := len(b)
- if msglen < 4 {
- return nil, errors.New("message too short")
- }
- m := &icmpMessage{Type: ipv4.ICMPType(b[0]), Code: int(b[1]), Checksum: int(b[2])<<8 | int(b[3])}
- if msglen > 4 {
- var err error
- switch m.Type {
- case ipv4.ICMPTypeEcho, ipv4.ICMPTypeEchoReply:
- m.Body, err = parseICMPEcho(b[4:])
- if err != nil {
- return nil, err
- }
- }
- }
- return m, nil
-}
-
-// imcpEcho represenets an ICMP echo request or reply message body.
-type icmpEcho struct {
- ID int // identifier
- Seq int // sequence number
- Data []byte // data
-}
-
-func (p *icmpEcho) Len() int {
- if p == nil {
- return 0
- }
- return 4 + len(p.Data)
-}
-
-// Marshal returns the binary enconding of the ICMP echo request or
-// reply message body p.
-func (p *icmpEcho) Marshal() ([]byte, error) {
- b := make([]byte, 4+len(p.Data))
- b[0], b[1] = byte(p.ID>>8), byte(p.ID)
- b[2], b[3] = byte(p.Seq>>8), byte(p.Seq)
- copy(b[4:], p.Data)
- return b, nil
-}
-
-// parseICMPEcho parses b as an ICMP echo request or reply message
-// body.
-func parseICMPEcho(b []byte) (*icmpEcho, error) {
- bodylen := len(b)
- p := &icmpEcho{ID: int(b[0])<<8 | int(b[1]), Seq: int(b[2])<<8 | int(b[3])}
- if bodylen > 4 {
- p.Data = make([]byte, bodylen-4)
- copy(p.Data, b[4:])
- }
- return p, nil
-}
diff --git a/ipv4/multicast_test.go b/ipv4/multicast_test.go
index 879780c..dbc0ca3 100644
--- a/ipv4/multicast_test.go
+++ b/ipv4/multicast_test.go
@@ -5,12 +5,15 @@
package ipv4_test
import (
- "code.google.com/p/go.net/ipv4"
"net"
"os"
"runtime"
"testing"
"time"
+
+ "code.google.com/p/go.net/internal/iana"
+ "code.google.com/p/go.net/internal/icmp"
+ "code.google.com/p/go.net/ipv4"
)
func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
@@ -121,15 +124,15 @@
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
for i, toggle := range []bool{true, false, true} {
- wb, err := (&icmpMessage{
+ wb, err := (&icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
- Body: &icmpEcho{
+ Body: &icmp.Echo{
ID: os.Getpid() & 0xffff, Seq: i + 1,
Data: []byte("HELLO-R-U-THERE"),
},
- }).Marshal()
+ }).Marshal(nil)
if err != nil {
- t.Fatalf("icmpMessage.Marshal failed: %v", err)
+ t.Fatalf("icmp.Message.Marshal failed: %v", err)
}
if err := p.SetControlMessage(cf, toggle); err != nil {
t.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", err)
@@ -146,9 +149,9 @@
t.Fatalf("ipv4.PacketConn.ReadFrom failed: %v", err)
} else {
t.Logf("rcvd cmsg: %v", cm)
- m, err := parseICMPMessage(b[:n])
+ m, err := icmp.ParseMessage(iana.ProtocolICMP, b[:n])
if err != nil {
- t.Fatalf("parseICMPMessage failed: %v", err)
+ t.Fatalf("icmp.ParseMessage failed: %v", err)
}
switch {
case m.Type == ipv4.ICMPTypeEchoReply && m.Code == 0: // net.inet.icmp.bmcastecho=1
@@ -161,7 +164,7 @@
}
func TestRawConnReadWriteMulticastICMP(t *testing.T) {
- if testing.Short() || !*testExternal {
+ if testing.Short() {
t.Skip("to avoid external network")
}
if os.Getuid() != 0 {
@@ -206,15 +209,15 @@
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
for i, toggle := range []bool{true, false, true} {
- wb, err := (&icmpMessage{
+ wb, err := (&icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
- Body: &icmpEcho{
+ Body: &icmp.Echo{
ID: os.Getpid() & 0xffff, Seq: i + 1,
Data: []byte("HELLO-R-U-THERE"),
},
- }).Marshal()
+ }).Marshal(nil)
if err != nil {
- t.Fatalf("icmpMessage.Marshal failed: %v", err)
+ t.Fatalf("icmp.Message.Marshal failed: %v", err)
}
wh := &ipv4.Header{
Version: ipv4.Version,
@@ -239,9 +242,9 @@
t.Fatalf("ipv4.RawConn.ReadFrom failed: %v", err)
} else {
t.Logf("rcvd cmsg: %v", cm)
- m, err := parseICMPMessage(b)
+ m, err := icmp.ParseMessage(iana.ProtocolICMP, b)
if err != nil {
- t.Fatalf("parseICMPMessage failed: %v", err)
+ t.Fatalf("icmp.ParseMessage failed: %v", err)
}
switch {
case isUnicast(rh.Dst) && m.Type == ipv4.ICMPTypeEchoReply && m.Code == 0: // net.inet.icmp.bmcastecho=1
diff --git a/ipv4/multicastlistener_test.go b/ipv4/multicastlistener_test.go
index 8b1863f..0578b37 100644
--- a/ipv4/multicastlistener_test.go
+++ b/ipv4/multicastlistener_test.go
@@ -5,11 +5,12 @@
package ipv4_test
import (
- "code.google.com/p/go.net/ipv4"
"net"
"os"
"runtime"
"testing"
+
+ "code.google.com/p/go.net/ipv4"
)
var udpMultipleGroupListenerTests = []net.Addr{
@@ -23,7 +24,7 @@
case "plan9", "windows":
t.Skipf("not supported on %q", runtime.GOOS)
}
- if testing.Short() || !*testExternal {
+ if testing.Short() {
t.Skip("to avoid external network")
}
@@ -63,7 +64,7 @@
case "plan9", "windows":
t.Skipf("not supported on %q", runtime.GOOS)
}
- if testing.Short() || !*testExternal {
+ if testing.Short() {
t.Skip("to avoid external network")
}
@@ -115,7 +116,7 @@
case "plan9", "windows":
t.Skipf("not supported on %q", runtime.GOOS)
}
- if testing.Short() || !*testExternal {
+ if testing.Short() {
t.Skip("to avoid external network")
}
@@ -158,7 +159,7 @@
case "plan9", "windows":
t.Skipf("not supported on %q", runtime.GOOS)
}
- if testing.Short() || !*testExternal {
+ if testing.Short() {
t.Skip("to avoid external network")
}
if os.Getuid() != 0 {
@@ -203,7 +204,7 @@
case "plan9", "windows":
t.Skipf("not supported on %q", runtime.GOOS)
}
- if testing.Short() || !*testExternal {
+ if testing.Short() {
t.Skip("to avoid external network")
}
if os.Getuid() != 0 {
diff --git a/ipv4/multicastsockopt_test.go b/ipv4/multicastsockopt_test.go
index c476f34..e7d9828 100644
--- a/ipv4/multicastsockopt_test.go
+++ b/ipv4/multicastsockopt_test.go
@@ -5,11 +5,12 @@
package ipv4_test
import (
- "code.google.com/p/go.net/ipv4"
"net"
"os"
"runtime"
"testing"
+
+ "code.google.com/p/go.net/ipv4"
)
var packetConnMulticastSocketOptionTests = []struct {
diff --git a/ipv4/sockopt_asmreq_unix.go b/ipv4/sockopt_asmreq_unix.go
index f2aed63..058ddf0 100644
--- a/ipv4/sockopt_asmreq_unix.go
+++ b/ipv4/sockopt_asmreq_unix.go
@@ -10,6 +10,8 @@
"net"
"os"
"unsafe"
+
+ "code.google.com/p/go.net/internal/iana"
)
func setsockoptIPMreq(fd, name int, ifi *net.Interface, grp net.IP) error {
@@ -17,13 +19,13 @@
if err := setIPMreqInterface(&mreq, ifi); err != nil {
return err
}
- return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIP, name, unsafe.Pointer(&mreq), sysSizeofIPMreq))
+ return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, name, unsafe.Pointer(&mreq), sysSizeofIPMreq))
}
func getsockoptInterface(fd, name int) (*net.Interface, error) {
var b [4]byte
l := sysSockoptLen(4)
- if err := getsockopt(fd, ianaProtocolIP, name, unsafe.Pointer(&b[0]), &l); err != nil {
+ if err := getsockopt(fd, iana.ProtocolIP, name, unsafe.Pointer(&b[0]), &l); err != nil {
return nil, os.NewSyscallError("getsockopt", err)
}
ifi, err := netIP4ToInterface(net.IPv4(b[0], b[1], b[2], b[3]))
@@ -40,5 +42,5 @@
}
var b [4]byte
copy(b[:], ip)
- return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIP, name, unsafe.Pointer(&b[0]), sysSockoptLen(4)))
+ return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, name, unsafe.Pointer(&b[0]), sysSockoptLen(4)))
}
diff --git a/ipv4/sockopt_asmreq_windows.go b/ipv4/sockopt_asmreq_windows.go
index 9591f97..ecbdac1 100644
--- a/ipv4/sockopt_asmreq_windows.go
+++ b/ipv4/sockopt_asmreq_windows.go
@@ -9,6 +9,8 @@
"os"
"syscall"
"unsafe"
+
+ "code.google.com/p/go.net/internal/iana"
)
func setsockoptIPMreq(fd syscall.Handle, name int, ifi *net.Interface, grp net.IP) error {
@@ -16,13 +18,13 @@
if err := setIPMreqInterface(&mreq, ifi); err != nil {
return err
}
- return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIP, int32(name), (*byte)(unsafe.Pointer(&mreq)), int32(sysSizeofIPMreq)))
+ return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, iana.ProtocolIP, int32(name), (*byte)(unsafe.Pointer(&mreq)), int32(sysSizeofIPMreq)))
}
func getsockoptInterface(fd syscall.Handle, name int) (*net.Interface, error) {
var b [4]byte
l := int32(4)
- if err := syscall.Getsockopt(fd, ianaProtocolIP, int32(name), (*byte)(unsafe.Pointer(&b[0])), &l); err != nil {
+ if err := syscall.Getsockopt(fd, iana.ProtocolIP, int32(name), (*byte)(unsafe.Pointer(&b[0])), &l); err != nil {
return nil, os.NewSyscallError("getsockopt", err)
}
ifi, err := netIP4ToInterface(net.IPv4(b[0], b[1], b[2], b[3]))
@@ -39,5 +41,5 @@
}
var b [4]byte
copy(b[:], ip)
- return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIP, int32(name), (*byte)(unsafe.Pointer(&b[0])), 4))
+ return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, iana.ProtocolIP, int32(name), (*byte)(unsafe.Pointer(&b[0])), 4))
}
diff --git a/ipv4/sockopt_asmreqn_unix.go b/ipv4/sockopt_asmreqn_unix.go
index fb18db6..2a9b284 100644
--- a/ipv4/sockopt_asmreqn_unix.go
+++ b/ipv4/sockopt_asmreqn_unix.go
@@ -10,12 +10,14 @@
"net"
"os"
"unsafe"
+
+ "code.google.com/p/go.net/internal/iana"
)
func getsockoptIPMreqn(fd, name int) (*net.Interface, error) {
var mreqn sysIPMreqn
l := sysSockoptLen(sysSizeofIPMreqn)
- if err := getsockopt(fd, ianaProtocolIP, name, unsafe.Pointer(&mreqn), &l); err != nil {
+ if err := getsockopt(fd, iana.ProtocolIP, name, unsafe.Pointer(&mreqn), &l); err != nil {
return nil, os.NewSyscallError("getsockopt", err)
}
if mreqn.Ifindex == 0 {
@@ -36,5 +38,5 @@
if grp != nil {
mreqn.Multiaddr = [4]byte{grp[0], grp[1], grp[2], grp[3]}
}
- return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIP, name, unsafe.Pointer(&mreqn), sysSizeofIPMreqn))
+ return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, name, unsafe.Pointer(&mreqn), sysSizeofIPMreqn))
}
diff --git a/ipv4/sockopt_unix.go b/ipv4/sockopt_unix.go
index a6531ad..d4d17f4 100644
--- a/ipv4/sockopt_unix.go
+++ b/ipv4/sockopt_unix.go
@@ -10,6 +10,8 @@
"net"
"os"
"unsafe"
+
+ "code.google.com/p/go.net/internal/iana"
)
func getInt(fd int, opt *sockOpt) (int, error) {
@@ -24,7 +26,7 @@
p = unsafe.Pointer(&b)
l = sysSockoptLen(1)
}
- if err := getsockopt(fd, ianaProtocolIP, opt.name, p, &l); err != nil {
+ if err := getsockopt(fd, iana.ProtocolIP, opt.name, p, &l); err != nil {
return 0, os.NewSyscallError("getsockopt", err)
}
if opt.typ == ssoTypeByte {
@@ -46,7 +48,7 @@
p = unsafe.Pointer(&b)
l = sysSockoptLen(1)
}
- return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIP, opt.name, p, l))
+ return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, opt.name, p, l))
}
func getInterface(fd int, opt *sockOpt) (*net.Interface, error) {
diff --git a/ipv4/sockopt_windows.go b/ipv4/sockopt_windows.go
index d5e79d4..16268dc 100644
--- a/ipv4/sockopt_windows.go
+++ b/ipv4/sockopt_windows.go
@@ -9,6 +9,8 @@
"os"
"syscall"
"unsafe"
+
+ "code.google.com/p/go.net/internal/iana"
)
func getInt(fd syscall.Handle, opt *sockOpt) (int, error) {
@@ -17,7 +19,7 @@
}
var i int32
l := int32(4)
- if err := syscall.Getsockopt(fd, ianaProtocolIP, int32(opt.name), (*byte)(unsafe.Pointer(&i)), &l); err != nil {
+ if err := syscall.Getsockopt(fd, iana.ProtocolIP, int32(opt.name), (*byte)(unsafe.Pointer(&i)), &l); err != nil {
return 0, os.NewSyscallError("getsockopt", err)
}
return int(i), nil
@@ -28,7 +30,7 @@
return errOpNoSupport
}
i := int32(v)
- return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIP, int32(opt.name), (*byte)(unsafe.Pointer(&i)), 4))
+ return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, iana.ProtocolIP, int32(opt.name), (*byte)(unsafe.Pointer(&i)), 4))
}
func getInterface(fd syscall.Handle, opt *sockOpt) (*net.Interface, error) {
diff --git a/ipv4/unicast_test.go b/ipv4/unicast_test.go
index 9845928..6a3b2f9 100644
--- a/ipv4/unicast_test.go
+++ b/ipv4/unicast_test.go
@@ -5,12 +5,15 @@
package ipv4_test
import (
- "code.google.com/p/go.net/ipv4"
"net"
"os"
"runtime"
"testing"
"time"
+
+ "code.google.com/p/go.net/internal/iana"
+ "code.google.com/p/go.net/internal/icmp"
+ "code.google.com/p/go.net/ipv4"
)
func benchmarkUDPListener() (net.PacketConn, net.Addr, error) {
@@ -159,15 +162,15 @@
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
for i, toggle := range []bool{true, false, true} {
- wb, err := (&icmpMessage{
+ wb, err := (&icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
- Body: &icmpEcho{
+ Body: &icmp.Echo{
ID: os.Getpid() & 0xffff, Seq: i + 1,
Data: []byte("HELLO-R-U-THERE"),
},
- }).Marshal()
+ }).Marshal(nil)
if err != nil {
- t.Fatalf("icmpMessage.Marshal failed: %v", err)
+ t.Fatalf("icmp.Message.Marshal failed: %v", err)
}
if err := p.SetControlMessage(cf, toggle); err != nil {
t.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", err)
@@ -188,9 +191,9 @@
t.Fatalf("ipv4.PacketConn.ReadFrom failed: %v", err)
} else {
t.Logf("rcvd cmsg: %v", cm)
- m, err := parseICMPMessage(b[:n])
+ m, err := icmp.ParseMessage(iana.ProtocolICMP, b[:n])
if err != nil {
- t.Fatalf("parseICMPMessage failed: %v", err)
+ t.Fatalf("icmp.ParseMessage failed: %v", err)
}
if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho {
// On Linux we must handle own sent packets.
@@ -234,15 +237,15 @@
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
for i, toggle := range []bool{true, false, true} {
- wb, err := (&icmpMessage{
+ wb, err := (&icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
- Body: &icmpEcho{
+ Body: &icmp.Echo{
ID: os.Getpid() & 0xffff, Seq: i + 1,
Data: []byte("HELLO-R-U-THERE"),
},
- }).Marshal()
+ }).Marshal(nil)
if err != nil {
- t.Fatalf("icmpMessage.Marshal failed: %v", err)
+ t.Fatalf("icmp.Message.Marshal failed: %v", err)
}
wh := &ipv4.Header{
Version: ipv4.Version,
@@ -271,9 +274,9 @@
t.Fatalf("ipv4.RawConn.ReadFrom failed: %v", err)
} else {
t.Logf("rcvd cmsg: %v", cm)
- m, err := parseICMPMessage(b)
+ m, err := icmp.ParseMessage(iana.ProtocolICMP, b)
if err != nil {
- t.Fatalf("parseICMPMessage failed: %v", err)
+ t.Fatalf("icmp.ParseMessage failed: %v", err)
}
if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho {
// On Linux we must handle own sent packets.
diff --git a/ipv4/unicastsockopt_test.go b/ipv4/unicastsockopt_test.go
index 3f415f8..24e29a2 100644
--- a/ipv4/unicastsockopt_test.go
+++ b/ipv4/unicastsockopt_test.go
@@ -5,11 +5,13 @@
package ipv4_test
import (
- "code.google.com/p/go.net/ipv4"
"net"
"os"
"runtime"
"testing"
+
+ "code.google.com/p/go.net/internal/iana"
+ "code.google.com/p/go.net/ipv4"
)
func TestConnUnicastSocketOptions(t *testing.T) {
@@ -108,7 +110,7 @@
}
func testUnicastSocketOptions(t *testing.T, c testIPv4UnicastConn) {
- tos := DiffServCS0 | NotECNTransport
+ tos := iana.DiffServCS0 | iana.NotECNTransport
switch runtime.GOOS {
case "windows":
// IP_TOS option is supported on Windows 8 and beyond.