go.net/ipv4: drop DIffServ and ECN constants, add ICMPType

This CL removes DiffServ and ECN constants assigned by IANA because
for now we don't have an appropriate package to put those constants
as part of API. There were used for the type-of-service field of IPv4
header and the traffic class field of IPv6 header.

Also adds ICMPType for convenience, makes use of internal IANA
protocol number constants instead of syscall's to prevent churning of
package syscall in the near future.

R=dave
CC=golang-dev
https://golang.org/cl/9353045
diff --git a/ipv4/control_bsd.go b/ipv4/control_bsd.go
index 63cd6c6..cd9dc87 100644
--- a/ipv4/control_bsd.go
+++ b/ipv4/control_bsd.go
@@ -55,7 +55,7 @@
 	if opt.isset(FlagTTL) {
 		b := make([]byte, syscall.CmsgSpace(1))
 		cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-		cmsg.Level = syscall.IPPROTO_IP
+		cmsg.Level = ianaProtocolIP
 		cmsg.Type = syscall.IP_RECVTTL
 		cmsg.SetLen(syscall.CmsgLen(1))
 		oob = append(oob, b...)
@@ -63,7 +63,7 @@
 	if opt.isset(FlagDst) {
 		b := make([]byte, syscall.CmsgSpace(net.IPv4len))
 		cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-		cmsg.Level = syscall.IPPROTO_IP
+		cmsg.Level = ianaProtocolIP
 		cmsg.Type = syscall.IP_RECVDSTADDR
 		cmsg.SetLen(syscall.CmsgLen(net.IPv4len))
 		oob = append(oob, b...)
@@ -71,7 +71,7 @@
 	if opt.isset(FlagInterface) {
 		b := make([]byte, syscall.CmsgSpace(syscall.SizeofSockaddrDatalink))
 		cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-		cmsg.Level = syscall.IPPROTO_IP
+		cmsg.Level = ianaProtocolIP
 		cmsg.Type = syscall.IP_RECVIF
 		cmsg.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrDatalink))
 		oob = append(oob, b...)
@@ -89,7 +89,7 @@
 	}
 	cm := &ControlMessage{}
 	for _, m := range cmsgs {
-		if m.Header.Level != syscall.IPPROTO_IP {
+		if m.Header.Level != ianaProtocolIP {
 			continue
 		}
 		switch m.Header.Type {
diff --git a/ipv4/control_linux.go b/ipv4/control_linux.go
index 51b9a14..cf2dcf0 100644
--- a/ipv4/control_linux.go
+++ b/ipv4/control_linux.go
@@ -47,7 +47,7 @@
 	if opt.isset(FlagTTL) {
 		b := make([]byte, syscall.CmsgSpace(1))
 		cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-		cmsg.Level = syscall.IPPROTO_IP
+		cmsg.Level = ianaProtocolIP
 		cmsg.Type = syscall.IP_RECVTTL
 		cmsg.SetLen(syscall.CmsgLen(1))
 		oob = append(oob, b...)
@@ -55,7 +55,7 @@
 	if opt.isset(pktinfo) {
 		b := make([]byte, syscall.CmsgSpace(syscall.SizeofInet4Pktinfo))
 		cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-		cmsg.Level = syscall.IPPROTO_IP
+		cmsg.Level = ianaProtocolIP
 		cmsg.Type = syscall.IP_PKTINFO
 		cmsg.SetLen(syscall.CmsgLen(syscall.SizeofInet4Pktinfo))
 		oob = append(oob, b...)
@@ -73,7 +73,7 @@
 	}
 	cm := &ControlMessage{}
 	for _, m := range cmsgs {
-		if m.Header.Level != syscall.IPPROTO_IP {
+		if m.Header.Level != ianaProtocolIP {
 			continue
 		}
 		switch m.Header.Type {
@@ -105,7 +105,7 @@
 	if pion {
 		b := make([]byte, syscall.CmsgSpace(syscall.SizeofInet4Pktinfo))
 		cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-		cmsg.Level = syscall.IPPROTO_IP
+		cmsg.Level = ianaProtocolIP
 		cmsg.Type = syscall.IP_PKTINFO
 		cmsg.SetLen(syscall.CmsgLen(syscall.SizeofInet4Pktinfo))
 		data := b[syscall.CmsgLen(0):]
diff --git a/ipv4/doc.go b/ipv4/doc.go
index 05be70d..ffdb9ff 100644
--- a/ipv4/doc.go
+++ b/ipv4/doc.go
@@ -8,9 +8,7 @@
 // The package provides IP-level socket options that allow
 // manipulation of IPv4 facilities.  The IPv4 and basic host
 // requirements for IPv4 are defined in RFC 791, RFC 1112 and RFC
-// 1122.  A series of RFC 2474, RFC 2475, RFC 2597, RFC 2598 and RFC
-// 3168 describe how to use the type-of-service field in a DiffServ,
-// differentiated services environment.
+// 1122.
 //
 //
 // Unicasting
@@ -38,7 +36,7 @@
 // The outgoing packets will be labeled DiffServ assured forwarding
 // class 1 low drop precedence, as known as AF11 packets.
 //
-//			err := ipv4.NewConn(c).SetTOS(ipv4.DSCP_AF11)
+//			err := ipv4.NewConn(c).SetTOS(DiffServAF11)
 //			if err != nil {
 //				// error handling
 //			}
@@ -125,7 +123,7 @@
 //
 // The application can also send both unicast and multicast packets.
 //
-//		p.SetTOS(ipv4.DSCP_CS0)
+//		p.SetTOS(DiffServCS0)
 //		p.SetTTL(16)
 //		_, err = p.WriteTo(data, nil, src)
 //		if err != nil {
diff --git a/ipv4/example_test.go b/ipv4/example_test.go
index ac202d3..bd4dc67 100644
--- a/ipv4/example_test.go
+++ b/ipv4/example_test.go
@@ -23,7 +23,7 @@
 		}
 		go func(c net.Conn) {
 			defer c.Close()
-			err := ipv4.NewConn(c).SetTOS(ipv4.DSCP_AF11)
+			err := ipv4.NewConn(c).SetTOS(DiffServAF11)
 			if err != nil {
 				log.Fatal(err)
 			}
@@ -81,7 +81,7 @@
 				continue
 			}
 		}
-		p.SetTOS(ipv4.DSCP_CS7)
+		p.SetTOS(DiffServCS7)
 		p.SetTTL(16)
 		_, err = p.WriteTo(b[:n], nil, src)
 		if err != nil {
@@ -150,7 +150,7 @@
 	}
 	ifs = append(ifs, en1)
 
-	c, err := net.ListenPacket("ip4:89", "0.0.0.0")
+	c, err := net.ListenPacket("ip4:89", "0.0.0.0") // OSFP for IPv4
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -175,7 +175,7 @@
 	if err != nil {
 		log.Fatal(err)
 	}
-	r.SetTOS(ipv4.DSCP_CS6)
+	r.SetTOS(DiffServCS6)
 
 	parseOSPFHeader := func(b []byte) *OSPFHeader {
 		if len(b) < OSPFHeaderLen {
@@ -235,7 +235,7 @@
 	}
 	ifs = append(ifs, en1)
 
-	c, err := net.ListenPacket("ip4:89", "0.0.0.0")
+	c, err := net.ListenPacket("ip4:89", "0.0.0.0") // OSPF for IPv4
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -264,7 +264,7 @@
 	iph := &ipv4.Header{}
 	iph.Version = ipv4.Version
 	iph.Len = ipv4.HeaderLen
-	iph.TOS = ipv4.DSCP_CS6
+	iph.TOS = DiffServCS6
 	iph.TotalLen = ipv4.HeaderLen + len(ospf)
 	iph.TTL = 1
 	iph.Protocol = 89
diff --git a/ipv4/gen.go b/ipv4/gen.go
new file mode 100644
index 0000000..673065f
--- /dev/null
+++ b/ipv4/gen.go
@@ -0,0 +1,242 @@
+// 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 constatns and tables by
+// reading IANA protocol registries.
+//
+// Usage of this program:
+//	go run gen.go > iana.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/icmp-parameters",
+		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, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n")
+	fmt.Fprintf(&bb, "package ipv4\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 parseICMPv4Parameters(w io.Writer, r io.Reader) error {
+	dec := xml.NewDecoder(r)
+	var icp icmpv4Parameters
+	if err := dec.Decode(&icp); err != nil {
+		return err
+	}
+	prs := icp.escape(0)
+	fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated)
+	fmt.Fprintf(w, "const (\n")
+	for _, pr := range prs {
+		if pr.Descr == "" {
+			continue
+		}
+		fmt.Fprintf(w, "ICMPType%s ICMPType = %d", pr.Descr, pr.Value)
+		fmt.Fprintf(w, "// %s\n", pr.OrigDescr)
+	}
+	fmt.Fprintf(w, ")\n\n")
+	fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated)
+	fmt.Fprintf(w, "var icmpTypes = map[ICMPType]string{\n")
+	for _, pr := range prs {
+		if pr.Descr == "" {
+			continue
+		}
+		fmt.Fprintf(w, "%d: %q,\n", pr.Value, strings.ToLower(pr.OrigDescr))
+	}
+	fmt.Fprintf(w, "}\n")
+	return nil
+}
+
+type icmpv4Parameters struct {
+	XMLName    xml.Name              `xml:"registry"`
+	Title      string                `xml:"title"`
+	Updated    string                `xml:"updated"`
+	Registries []icmpv4ParamRegistry `xml:"registry"`
+}
+
+type icmpv4ParamRegistry struct {
+	Title   string              `xml:"title"`
+	Records []icmpv4ParamRecord `xml:"record"`
+}
+
+type icmpv4ParamRecord struct {
+	Value string `xml:"value"`
+	Descr string `xml:"description"`
+}
+
+type canonICMPv4ParamRecord struct {
+	OrigDescr string
+	Descr     string
+	Value     int
+}
+
+func (icp *icmpv4Parameters) escape(id int) []canonICMPv4ParamRecord {
+	prs := make([]canonICMPv4ParamRecord, len(icp.Registries[id].Records))
+	sr := strings.NewReplacer(
+		"Messages", "",
+		"Message", "",
+		"ICMP", "",
+		"+", "P",
+		"-", "",
+		"/", "",
+		".", "",
+		" ", "",
+	)
+	for i, pr := range icp.Registries[id].Records {
+		if strings.Contains(pr.Descr, "Reserved") ||
+			strings.Contains(pr.Descr, "Unassigned") ||
+			strings.Contains(pr.Descr, "Deprecated") ||
+			strings.Contains(pr.Descr, "Experiment") ||
+			strings.Contains(pr.Descr, "experiment") {
+			continue
+		}
+		ss := strings.Split(pr.Descr, "\n")
+		if len(ss) > 1 {
+			prs[i].Descr = strings.Join(ss, " ")
+		} else {
+			prs[i].Descr = ss[0]
+		}
+		s := strings.TrimSpace(prs[i].Descr)
+		prs[i].OrigDescr = s
+		prs[i].Descr = sr.Replace(s)
+		prs[i].Value, _ = strconv.Atoi(pr.Value)
+	}
+	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  []protocolRecord `xml:"registry>record"`
+}
+
+type protocolRecord struct {
+	Value string `xml:"value"`
+	Name  string `xml:"name"`
+	Descr string `xml:"description"`
+}
+
+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
new file mode 100644
index 0000000..cc35225
--- /dev/null
+++ b/ipv4/gentest.go
@@ -0,0 +1,196 @@
+// 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 gentv.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 []dscpRecord `xml:"registry>record"`
+	Records     []dscpRecord `xml:"registry>registry>record"`
+}
+
+type dscpRecord struct {
+	Name  string `xml:"name"`
+	Space string `xml:"space"`
+}
+
+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  []tosTCByteRecord `xml:"registry>record"`
+}
+
+type tosTCByteRecord struct {
+	Binary  string `xml:"binary"`
+	Keyword string `xml:"keyword"`
+}
+
+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/header.go b/ipv4/header.go
index 2e953fd..45bd27a 100644
--- a/ipv4/header.go
+++ b/ipv4/header.go
@@ -29,18 +29,6 @@
 //	http://tools.ietf.org/html/rfc1112
 // RFC 1122  Requirements for Internet Hosts
 //	http://tools.ietf.org/html/rfc1122
-// RFC 2474  Definition of the Differentiated Services Field (DS Field) in the IPv4 and IPv6 Headers
-//	http://tools.ietf.org/html/rfc2474
-// RFC 2475  An Architecture for Differentiated Services
-//	http://tools.ietf.org/html/rfc2475
-// RFC 2597  Assured Forwarding PHB Group
-//	http://tools.ietf.org/html/rfc2597
-// RFC 2598  An Expedited Forwarding PHB
-//	http://tools.ietf.org/html/rfc2598
-// RFC 3168  The Addition of Explicit Congestion Notification (ECN) to IP
-//	http://tools.ietf.org/html/rfc3168
-// RFC 3260  New Terminology and Clarifications for Diffserv
-//	http://tools.ietf.org/html/rfc3260
 
 const (
 	Version      = 4  // protocol version
@@ -48,39 +36,6 @@
 	maxHeaderLen = 60 // sensible default, revisit if later RFCs define new usage of version and header length fields
 )
 
-const (
-	// DiffServ class selector codepoints in RFC 2474.
-	DSCP_CS0 = 0x00 // best effort
-	DSCP_CS1 = 0x20 // class 1
-	DSCP_CS2 = 0x40 // class 2
-	DSCP_CS3 = 0x60 // class 3
-	DSCP_CS4 = 0x80 // class 4
-	DSCP_CS5 = 0xa0 // expedited forwarding
-	DSCP_CS6 = 0xc0 // subsume deprecated IP precedence, internet control (routing information update)
-	DSCP_CS7 = 0xe0 // subsume deprecated IP precedence, network control (link, neighbor liveliness check)
-
-	// DiffServ assured forwarding codepoints in RFC 2474, 2475, 2597 and 3260.
-	DSCP_AF11 = 0x28 // class 1 low drop precedence
-	DSCP_AF12 = 0x30 // class 1 medium drop precedence
-	DSCP_AF13 = 0x38 // class 1 high drop precedence
-	DSCP_AF21 = 0x48 // class 2 low drop precedence
-	DSCP_AF22 = 0x50 // class 2 medium drop precedence
-	DSCP_AF23 = 0x58 // class 2 high drop precedence
-	DSCP_AF31 = 0x68 // class 3 low drop precedence
-	DSCP_AF32 = 0x70 // class 3 medium drop precedence
-	DSCP_AF33 = 0x78 // class 3 high drop precedence
-	DSCP_AF41 = 0x88 // class 4 low drop precedence
-	DSCP_AF42 = 0x90 // class 4 medium drop precedence
-	DSCP_AF43 = 0x98 // class 4 high drop precedence
-	DSCP_EF   = 0xb8 // expedited forwarding
-
-	// ECN codepoints in RFC 3168.
-	ECN_NOTECT = 0x00 // not ECN-capable transport
-	ECN_ECT1   = 0x01 // ECN-capable transport, ECT(1)
-	ECN_ECT0   = 0x02 // ECN-capable transport, ECT(0)
-	ECN_CE     = 0x03 // congestion experienced
-)
-
 type headerField int
 
 const (
diff --git a/ipv4/iana.go b/ipv4/iana.go
new file mode 100644
index 0000000..254d019
--- /dev/null
+++ b/ipv4/iana.go
@@ -0,0 +1,179 @@
+// go run gen.go
+// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package ipv4
+
+// Internet Control Message Protocol (ICMP) Parameters, Updated: 2013-04-19
+const (
+	ICMPTypeEchoReply              ICMPType = 0  // Echo Reply
+	ICMPTypeDestinationUnreachable ICMPType = 3  // Destination Unreachable
+	ICMPTypeRedirect               ICMPType = 5  // Redirect
+	ICMPTypeEcho                   ICMPType = 8  // Echo
+	ICMPTypeRouterAdvertisement    ICMPType = 9  // Router Advertisement
+	ICMPTypeRouterSolicitation     ICMPType = 10 // Router Solicitation
+	ICMPTypeTimeExceeded           ICMPType = 11 // Time Exceeded
+	ICMPTypeParameterProblem       ICMPType = 12 // Parameter Problem
+	ICMPTypeTimestamp              ICMPType = 13 // Timestamp
+	ICMPTypeTimestampReply         ICMPType = 14 // Timestamp Reply
+	ICMPTypePhoturis               ICMPType = 40 // Photuris
+)
+
+// Internet Control Message Protocol (ICMP) Parameters, Updated: 2013-04-19
+var icmpTypes = map[ICMPType]string{
+	0:  "echo reply",
+	3:  "destination unreachable",
+	5:  "redirect",
+	8:  "echo",
+	9:  "router advertisement",
+	10: "router solicitation",
+	11: "time exceeded",
+	12: "parameter problem",
+	13: "timestamp",
+	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
new file mode 100644
index 0000000..276230d
--- /dev/null
+++ b/ipv4/iana_test.go
@@ -0,0 +1,38 @@
+// go run gentv.go
+// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package ipv4_test
+
+// Differentiated Services Field Codepoints, Updated: 2010-05-11
+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/icmp.go b/ipv4/icmp.go
new file mode 100644
index 0000000..d595967
--- /dev/null
+++ b/ipv4/icmp.go
@@ -0,0 +1,16 @@
+// 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.
+
+package ipv4
+
+// An ICMPType represents a type of ICMP message.
+type ICMPType int
+
+func (typ ICMPType) String() string {
+	s, ok := icmpTypes[typ]
+	if !ok {
+		return "<nil>"
+	}
+	return s
+}
diff --git a/ipv4/mockicmp_test.go b/ipv4/mockicmp_test.go
index 7b9ee06..b799197 100644
--- a/ipv4/mockicmp_test.go
+++ b/ipv4/mockicmp_test.go
@@ -5,22 +5,16 @@
 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")
 
-const (
-	icmpv4EchoRequest = 8
-	icmpv4EchoReply   = 0
-	icmpv6EchoRequest = 128
-	icmpv6EchoReply   = 129
-)
-
 // icmpMessage represents an ICMP message.
 type icmpMessage struct {
-	Type     int             // type
+	Type     ipv4.ICMPType   // type
 	Code     int             // code
 	Checksum int             // checksum
 	Body     icmpMessageBody // body
@@ -43,10 +37,6 @@
 		}
 		b = append(b, mb...)
 	}
-	switch m.Type {
-	case icmpv6EchoRequest, icmpv6EchoReply:
-		return b, nil
-	}
 	csumcv := len(b) - 1 // checksum coverage
 	s := uint32(0)
 	for i := 0; i < csumcv; i += 2 {
@@ -70,11 +60,11 @@
 	if msglen < 4 {
 		return nil, errors.New("message too short")
 	}
-	m := &icmpMessage{Type: int(b[0]), Code: int(b[1]), Checksum: int(b[2])<<8 | int(b[3])}
+	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 icmpv4EchoRequest, icmpv4EchoReply, icmpv6EchoRequest, icmpv6EchoReply:
+		case ipv4.ICMPTypeEcho, ipv4.ICMPTypeEchoReply:
 			m.Body, err = parseICMPEcho(b[4:])
 			if err != nil {
 				return nil, err
diff --git a/ipv4/multicast_test.go b/ipv4/multicast_test.go
index 307eea1..a12d242 100644
--- a/ipv4/multicast_test.go
+++ b/ipv4/multicast_test.go
@@ -85,7 +85,7 @@
 	cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
 	for i, toggle := range []bool{true, false, true} {
 		wb, err := (&icmpMessage{
-			Type: icmpv4EchoRequest, Code: 0,
+			Type: ipv4.ICMPTypeEcho, Code: 0,
 			Body: &icmpEcho{
 				ID: os.Getpid() & 0xffff, Seq: i + 1,
 				Data: []byte("HELLO-R-U-THERE"),
@@ -102,8 +102,8 @@
 		if err != nil {
 			t.Fatalf("parseICMPMessage failed: %v", err)
 		}
-		if m.Type != icmpv4EchoReply || m.Code != 0 {
-			t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, icmpv4EchoReply, 0)
+		if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 {
+			t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
 		}
 	}
 }
@@ -144,7 +144,7 @@
 	cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
 	for i, toggle := range []bool{true, false, true} {
 		wb, err := (&icmpMessage{
-			Type: icmpv4EchoRequest, Code: 0,
+			Type: ipv4.ICMPTypeEcho, Code: 0,
 			Body: &icmpEcho{
 				ID: os.Getpid() & 0xffff, Seq: i + 1,
 				Data: []byte("HELLO-R-U-THERE"),
@@ -161,8 +161,8 @@
 		if err != nil {
 			t.Fatalf("parseICMPMessage failed: %v", err)
 		}
-		if m.Type != icmpv4EchoReply || m.Code != 0 {
-			t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, icmpv4EchoReply, 0)
+		if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 {
+			t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
 		}
 	}
 }
diff --git a/ipv4/multicastsockopt_test.go b/ipv4/multicastsockopt_test.go
index e8a7691..009364d 100644
--- a/ipv4/multicastsockopt_test.go
+++ b/ipv4/multicastsockopt_test.go
@@ -33,8 +33,8 @@
 }
 
 var multicastSockoptTests = []multicastSockoptTest{
-	{ipv4.DSCP_CS0 | ipv4.ECN_NOTECT, 127, 128, false, net.IPv4(224, 0, 0, 249)}, // see RFC 4727
-	{ipv4.DSCP_AF11 | ipv4.ECN_NOTECT, 255, 254, true, net.IPv4(224, 0, 0, 250)}, // see RFC 4727
+	{DiffServCS0 | NotECNTransport, 127, 128, false, net.IPv4(224, 0, 0, 249)}, // see RFC 4727
+	{DiffServAF11 | NotECNTransport, 255, 254, true, net.IPv4(224, 0, 0, 250)}, // see RFC 4727
 }
 
 func TestUDPMulticastSockopt(t *testing.T) {
diff --git a/ipv4/sockopt_bsd.go b/ipv4/sockopt_bsd.go
index 46ab31c..040a196 100644
--- a/ipv4/sockopt_bsd.go
+++ b/ipv4/sockopt_bsd.go
@@ -13,7 +13,7 @@
 )
 
 func ipv4MulticastTTL(fd int) (int, error) {
-	v, err := syscall.GetsockoptByte(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_TTL)
+	v, err := syscall.GetsockoptByte(fd, ianaProtocolIP, syscall.IP_MULTICAST_TTL)
 	if err != nil {
 		return 0, os.NewSyscallError("getsockopt", err)
 	}
@@ -21,7 +21,7 @@
 }
 
 func setIPv4MulticastTTL(fd int, v int) error {
-	err := syscall.SetsockoptByte(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_TTL, byte(v))
+	err := syscall.SetsockoptByte(fd, ianaProtocolIP, syscall.IP_MULTICAST_TTL, byte(v))
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -29,7 +29,7 @@
 }
 
 func ipv4ReceiveDestinationAddress(fd int) (bool, error) {
-	v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_RECVDSTADDR)
+	v, err := syscall.GetsockoptInt(fd, ianaProtocolIP, syscall.IP_RECVDSTADDR)
 	if err != nil {
 		return false, os.NewSyscallError("getsockopt", err)
 	}
@@ -37,7 +37,7 @@
 }
 
 func setIPv4ReceiveDestinationAddress(fd int, v bool) error {
-	err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_RECVDSTADDR, boolint(v))
+	err := syscall.SetsockoptInt(fd, ianaProtocolIP, syscall.IP_RECVDSTADDR, boolint(v))
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -45,7 +45,7 @@
 }
 
 func ipv4ReceiveInterface(fd int) (bool, error) {
-	v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_RECVIF)
+	v, err := syscall.GetsockoptInt(fd, ianaProtocolIP, syscall.IP_RECVIF)
 	if err != nil {
 		return false, os.NewSyscallError("getsockopt", err)
 	}
@@ -53,7 +53,7 @@
 }
 
 func setIPv4ReceiveInterface(fd int, v bool) error {
-	err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_RECVIF, boolint(v))
+	err := syscall.SetsockoptInt(fd, ianaProtocolIP, syscall.IP_RECVIF, boolint(v))
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -61,7 +61,7 @@
 }
 
 func ipv4MulticastInterface(fd int) (*net.Interface, error) {
-	a, err := syscall.GetsockoptInet4Addr(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF)
+	a, err := syscall.GetsockoptInet4Addr(fd, ianaProtocolIP, syscall.IP_MULTICAST_IF)
 	if err != nil {
 		return nil, os.NewSyscallError("getsockopt", err)
 	}
@@ -75,7 +75,7 @@
 	}
 	var a [4]byte
 	copy(a[:], ip.To4())
-	err = syscall.SetsockoptInet4Addr(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF, a)
+	err = syscall.SetsockoptInet4Addr(fd, ianaProtocolIP, syscall.IP_MULTICAST_IF, a)
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -83,7 +83,7 @@
 }
 
 func ipv4MulticastLoopback(fd int) (bool, error) {
-	v, err := syscall.GetsockoptByte(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP)
+	v, err := syscall.GetsockoptByte(fd, ianaProtocolIP, syscall.IP_MULTICAST_LOOP)
 	if err != nil {
 		return false, os.NewSyscallError("getsockopt", err)
 	}
@@ -91,7 +91,7 @@
 }
 
 func setIPv4MulticastLoopback(fd int, v bool) error {
-	err := syscall.SetsockoptByte(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP, byte(boolint(v)))
+	err := syscall.SetsockoptByte(fd, ianaProtocolIP, syscall.IP_MULTICAST_LOOP, byte(boolint(v)))
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -103,7 +103,7 @@
 	if err := setSyscallIPMreq(mreq, ifi); err != nil {
 		return err
 	}
-	err := syscall.SetsockoptIPMreq(fd, syscall.IPPROTO_IP, syscall.IP_ADD_MEMBERSHIP, mreq)
+	err := syscall.SetsockoptIPMreq(fd, ianaProtocolIP, syscall.IP_ADD_MEMBERSHIP, mreq)
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -115,7 +115,7 @@
 	if err := setSyscallIPMreq(mreq, ifi); err != nil {
 		return err
 	}
-	err := syscall.SetsockoptIPMreq(fd, syscall.IPPROTO_IP, syscall.IP_DROP_MEMBERSHIP, mreq)
+	err := syscall.SetsockoptIPMreq(fd, ianaProtocolIP, syscall.IP_DROP_MEMBERSHIP, mreq)
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
diff --git a/ipv4/sockopt_freebsd.go b/ipv4/sockopt_freebsd.go
index 6bcd66f..8c4d2cb 100644
--- a/ipv4/sockopt_freebsd.go
+++ b/ipv4/sockopt_freebsd.go
@@ -10,7 +10,7 @@
 )
 
 func ipv4SendSourceAddress(fd int) (bool, error) {
-	v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_SENDSRCADDR)
+	v, err := syscall.GetsockoptInt(fd, ianaProtocolIP, syscall.IP_SENDSRCADDR)
 	if err != nil {
 		return false, os.NewSyscallError("getsockopt", err)
 	}
@@ -18,7 +18,7 @@
 }
 
 func setIPv4SendSourceAddress(fd int, v bool) error {
-	err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_SENDSRCADDR, boolint(v))
+	err := syscall.SetsockoptInt(fd, ianaProtocolIP, syscall.IP_SENDSRCADDR, boolint(v))
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
diff --git a/ipv4/sockopt_linux.go b/ipv4/sockopt_linux.go
index 8c0ca06..22f78c9 100644
--- a/ipv4/sockopt_linux.go
+++ b/ipv4/sockopt_linux.go
@@ -11,7 +11,7 @@
 )
 
 func ipv4ReceiveTOS(fd int) (bool, error) {
-	v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_RECVTOS)
+	v, err := syscall.GetsockoptInt(fd, ianaProtocolIP, syscall.IP_RECVTOS)
 	if err != nil {
 		return false, os.NewSyscallError("getsockopt", err)
 	}
@@ -19,7 +19,7 @@
 }
 
 func setIPv4ReceiveTOS(fd int, v bool) error {
-	err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_RECVTOS, boolint(v))
+	err := syscall.SetsockoptInt(fd, ianaProtocolIP, syscall.IP_RECVTOS, boolint(v))
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -27,7 +27,7 @@
 }
 
 func ipv4MulticastTTL(fd int) (int, error) {
-	v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_TTL)
+	v, err := syscall.GetsockoptInt(fd, ianaProtocolIP, syscall.IP_MULTICAST_TTL)
 	if err != nil {
 		return 0, os.NewSyscallError("getsockopt", err)
 	}
@@ -35,7 +35,7 @@
 }
 
 func setIPv4MulticastTTL(fd int, v int) error {
-	err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_TTL, v)
+	err := syscall.SetsockoptInt(fd, ianaProtocolIP, syscall.IP_MULTICAST_TTL, v)
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -43,7 +43,7 @@
 }
 
 func ipv4PacketInfo(fd int) (bool, error) {
-	v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_PKTINFO)
+	v, err := syscall.GetsockoptInt(fd, ianaProtocolIP, syscall.IP_PKTINFO)
 	if err != nil {
 		return false, os.NewSyscallError("getsockopt", err)
 	}
@@ -51,7 +51,7 @@
 }
 
 func setIPv4PacketInfo(fd int, v bool) error {
-	err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_PKTINFO, boolint(v))
+	err := syscall.SetsockoptInt(fd, ianaProtocolIP, syscall.IP_PKTINFO, boolint(v))
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -59,7 +59,7 @@
 }
 
 func ipv4MulticastInterface(fd int) (*net.Interface, error) {
-	mreqn, err := syscall.GetsockoptIPMreqn(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF)
+	mreqn, err := syscall.GetsockoptIPMreqn(fd, ianaProtocolIP, syscall.IP_MULTICAST_IF)
 	if err != nil {
 		return nil, os.NewSyscallError("getsockopt", err)
 	}
@@ -74,7 +74,7 @@
 	if ifi != nil {
 		mreqn.Ifindex = int32(ifi.Index)
 	}
-	err := syscall.SetsockoptIPMreqn(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF, mreqn)
+	err := syscall.SetsockoptIPMreqn(fd, ianaProtocolIP, syscall.IP_MULTICAST_IF, mreqn)
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -82,7 +82,7 @@
 }
 
 func ipv4MulticastLoopback(fd int) (bool, error) {
-	v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP)
+	v, err := syscall.GetsockoptInt(fd, ianaProtocolIP, syscall.IP_MULTICAST_LOOP)
 	if err != nil {
 		return false, os.NewSyscallError("getsockopt", err)
 	}
@@ -90,7 +90,7 @@
 }
 
 func setIPv4MulticastLoopback(fd int, v bool) error {
-	err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP, boolint(v))
+	err := syscall.SetsockoptInt(fd, ianaProtocolIP, syscall.IP_MULTICAST_LOOP, boolint(v))
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -102,7 +102,7 @@
 	if ifi != nil {
 		mreqn.Ifindex = int32(ifi.Index)
 	}
-	err := syscall.SetsockoptIPMreqn(fd, syscall.IPPROTO_IP, syscall.IP_ADD_MEMBERSHIP, mreqn)
+	err := syscall.SetsockoptIPMreqn(fd, ianaProtocolIP, syscall.IP_ADD_MEMBERSHIP, mreqn)
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -114,7 +114,7 @@
 	if ifi != nil {
 		mreqn.Ifindex = int32(ifi.Index)
 	}
-	err := syscall.SetsockoptIPMreqn(fd, syscall.IPPROTO_IP, syscall.IP_DROP_MEMBERSHIP, mreqn)
+	err := syscall.SetsockoptIPMreqn(fd, ianaProtocolIP, syscall.IP_DROP_MEMBERSHIP, mreqn)
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
diff --git a/ipv4/sockopt_unix.go b/ipv4/sockopt_unix.go
index ef000ec..f5c1092 100644
--- a/ipv4/sockopt_unix.go
+++ b/ipv4/sockopt_unix.go
@@ -12,7 +12,7 @@
 )
 
 func ipv4TOS(fd int) (int, error) {
-	v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_TOS)
+	v, err := syscall.GetsockoptInt(fd, ianaProtocolIP, syscall.IP_TOS)
 	if err != nil {
 		return 0, os.NewSyscallError("getsockopt", err)
 	}
@@ -20,7 +20,7 @@
 }
 
 func setIPv4TOS(fd int, v int) error {
-	err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_TOS, v)
+	err := syscall.SetsockoptInt(fd, ianaProtocolIP, syscall.IP_TOS, v)
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -28,7 +28,7 @@
 }
 
 func ipv4TTL(fd int) (int, error) {
-	v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_TTL)
+	v, err := syscall.GetsockoptInt(fd, ianaProtocolIP, syscall.IP_TTL)
 	if err != nil {
 		return 0, os.NewSyscallError("getsockopt", err)
 	}
@@ -36,7 +36,7 @@
 }
 
 func setIPv4TTL(fd int, v int) error {
-	err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_TTL, v)
+	err := syscall.SetsockoptInt(fd, ianaProtocolIP, syscall.IP_TTL, v)
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -44,7 +44,7 @@
 }
 
 func ipv4ReceiveTTL(fd int) (bool, error) {
-	v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_RECVTTL)
+	v, err := syscall.GetsockoptInt(fd, ianaProtocolIP, syscall.IP_RECVTTL)
 	if err != nil {
 		return false, os.NewSyscallError("getsockopt", err)
 	}
@@ -52,7 +52,7 @@
 }
 
 func setIPv4ReceiveTTL(fd int, v bool) error {
-	err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_RECVTTL, boolint(v))
+	err := syscall.SetsockoptInt(fd, ianaProtocolIP, syscall.IP_RECVTTL, boolint(v))
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -60,7 +60,7 @@
 }
 
 func ipv4HeaderPrepend(fd int) (bool, error) {
-	v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_HDRINCL)
+	v, err := syscall.GetsockoptInt(fd, ianaProtocolIP, syscall.IP_HDRINCL)
 	if err != nil {
 		return false, os.NewSyscallError("getsockopt", err)
 	}
@@ -68,7 +68,7 @@
 }
 
 func setIPv4HeaderPrepend(fd int, v bool) error {
-	err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_HDRINCL, boolint(v))
+	err := syscall.SetsockoptInt(fd, ianaProtocolIP, syscall.IP_HDRINCL, boolint(v))
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
diff --git a/ipv4/sockopt_windows.go b/ipv4/sockopt_windows.go
index b1e4edf..e84be74 100644
--- a/ipv4/sockopt_windows.go
+++ b/ipv4/sockopt_windows.go
@@ -17,7 +17,7 @@
 func ipv4TOS(fd syscall.Handle) (int, error) {
 	var v int32
 	l := int32(4)
-	err := syscall.Getsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.IP_TOS), (*byte)(unsafe.Pointer(&v)), &l)
+	err := syscall.Getsockopt(fd, ianaProtocolIP, syscall.IP_TOS, (*byte)(unsafe.Pointer(&v)), &l)
 	if err != nil {
 		return 0, os.NewSyscallError("getsockopt", err)
 	}
@@ -26,7 +26,7 @@
 
 func setIPv4TOS(fd syscall.Handle, v int) error {
 	vv := int32(v)
-	err := syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.IP_TOS), (*byte)(unsafe.Pointer(&vv)), 4)
+	err := syscall.Setsockopt(fd, ianaProtocolIP, syscall.IP_TOS, (*byte)(unsafe.Pointer(&vv)), 4)
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -36,7 +36,7 @@
 func ipv4TTL(fd syscall.Handle) (int, error) {
 	var v int32
 	l := int32(4)
-	err := syscall.Getsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.IP_TTL), (*byte)(unsafe.Pointer(&v)), &l)
+	err := syscall.Getsockopt(fd, ianaProtocolIP, syscall.IP_TTL, (*byte)(unsafe.Pointer(&v)), &l)
 	if err != nil {
 		return 0, os.NewSyscallError("getsockopt", err)
 	}
@@ -45,7 +45,7 @@
 
 func setIPv4TTL(fd syscall.Handle, v int) error {
 	vv := int32(v)
-	err := syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.IP_TTL), (*byte)(unsafe.Pointer(&vv)), 4)
+	err := syscall.Setsockopt(fd, ianaProtocolIP, syscall.IP_TTL, (*byte)(unsafe.Pointer(&vv)), 4)
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -55,7 +55,7 @@
 func ipv4MulticastTTL(fd syscall.Handle) (int, error) {
 	var v int32
 	l := int32(4)
-	err := syscall.Getsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.IP_MULTICAST_TTL), (*byte)(unsafe.Pointer(&v)), &l)
+	err := syscall.Getsockopt(fd, ianaProtocolIP, syscall.IP_MULTICAST_TTL, (*byte)(unsafe.Pointer(&v)), &l)
 	if err != nil {
 		return 0, os.NewSyscallError("getsockopt", err)
 	}
@@ -64,7 +64,7 @@
 
 func setIPv4MulticastTTL(fd syscall.Handle, v int) error {
 	vv := int32(v)
-	err := syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.IP_MULTICAST_TTL), (*byte)(unsafe.Pointer(&vv)), 4)
+	err := syscall.Setsockopt(fd, ianaProtocolIP, syscall.IP_MULTICAST_TTL, (*byte)(unsafe.Pointer(&vv)), 4)
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -114,7 +114,7 @@
 func ipv4MulticastInterface(fd syscall.Handle) (*net.Interface, error) {
 	var a [4]byte
 	l := int32(4)
-	err := syscall.Getsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.IP_MULTICAST_IF), (*byte)(unsafe.Pointer(&a[0])), &l)
+	err := syscall.Getsockopt(fd, ianaProtocolIP, syscall.IP_MULTICAST_IF, (*byte)(unsafe.Pointer(&a[0])), &l)
 	if err != nil {
 		return nil, os.NewSyscallError("getsockopt", err)
 	}
@@ -128,7 +128,7 @@
 	}
 	var a [4]byte
 	copy(a[:], ip.To4())
-	err = syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.IP_MULTICAST_IF), (*byte)(unsafe.Pointer(&a[0])), 4)
+	err = syscall.Setsockopt(fd, ianaProtocolIP, syscall.IP_MULTICAST_IF, (*byte)(unsafe.Pointer(&a[0])), 4)
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -138,7 +138,7 @@
 func ipv4MulticastLoopback(fd syscall.Handle) (bool, error) {
 	var v int32
 	l := int32(4)
-	err := syscall.Getsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.IP_MULTICAST_LOOP), (*byte)(unsafe.Pointer(&v)), &l)
+	err := syscall.Getsockopt(fd, ianaProtocolIP, syscall.IP_MULTICAST_LOOP, (*byte)(unsafe.Pointer(&v)), &l)
 	if err != nil {
 		return false, os.NewSyscallError("getsockopt", err)
 	}
@@ -147,7 +147,7 @@
 
 func setIPv4MulticastLoopback(fd syscall.Handle, v bool) error {
 	vv := int32(boolint(v))
-	err := syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.IP_MULTICAST_LOOP), (*byte)(unsafe.Pointer(&vv)), 4)
+	err := syscall.Setsockopt(fd, ianaProtocolIP, syscall.IP_MULTICAST_LOOP, (*byte)(unsafe.Pointer(&vv)), 4)
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -159,7 +159,7 @@
 	if err := setSyscallIPMreq(mreq, ifi); err != nil {
 		return err
 	}
-	err := syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.IP_ADD_MEMBERSHIP), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
+	err := syscall.Setsockopt(fd, ianaProtocolIP, syscall.IP_ADD_MEMBERSHIP, (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
@@ -171,7 +171,7 @@
 	if err := setSyscallIPMreq(mreq, ifi); err != nil {
 		return err
 	}
-	err := syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.IP_DROP_MEMBERSHIP), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
+	err := syscall.Setsockopt(fd, ianaProtocolIP, syscall.IP_DROP_MEMBERSHIP, (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
 	if err != nil {
 		return os.NewSyscallError("setsockopt", err)
 	}
diff --git a/ipv4/unicast_test.go b/ipv4/unicast_test.go
index c601ee1..5a0061e 100644
--- a/ipv4/unicast_test.go
+++ b/ipv4/unicast_test.go
@@ -53,7 +53,7 @@
 	cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
 	for i, toggle := range []bool{true, false, true} {
 		wb, err := (&icmpMessage{
-			Type: icmpv4EchoRequest, Code: 0,
+			Type: ipv4.ICMPTypeEcho, Code: 0,
 			Body: &icmpEcho{
 				ID: os.Getpid() & 0xffff, Seq: i + 1,
 				Data: []byte("HELLO-R-U-THERE"),
@@ -70,8 +70,8 @@
 		if err != nil {
 			t.Fatalf("parseICMPMessage failed: %v", err)
 		}
-		if m.Type != icmpv4EchoReply || m.Code != 0 {
-			t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, icmpv4EchoReply, 0)
+		if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 {
+			t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
 		}
 	}
 }
@@ -98,7 +98,7 @@
 	cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
 	for i, toggle := range []bool{true, false, true} {
 		wb, err := (&icmpMessage{
-			Type: icmpv4EchoRequest, Code: 0,
+			Type: ipv4.ICMPTypeEcho, Code: 0,
 			Body: &icmpEcho{
 				ID: os.Getpid() & 0xffff, Seq: i + 1,
 				Data: []byte("HELLO-R-U-THERE"),
@@ -115,8 +115,8 @@
 		if err != nil {
 			t.Fatalf("parseICMPMessage failed: %v", err)
 		}
-		if m.Type != icmpv4EchoReply || m.Code != 0 {
-			t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, icmpv4EchoReply, 0)
+		if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 {
+			t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
 		}
 	}
 }
diff --git a/ipv4/unicastsockopt_test.go b/ipv4/unicastsockopt_test.go
index ea9bb76..3816ab3 100644
--- a/ipv4/unicastsockopt_test.go
+++ b/ipv4/unicastsockopt_test.go
@@ -28,8 +28,8 @@
 }
 
 var unicastSockoptTests = []unicastSockoptTest{
-	{ipv4.DSCP_CS0 | ipv4.ECN_NOTECT, 127},
-	{ipv4.DSCP_AF11 | ipv4.ECN_NOTECT, 255},
+	{DiffServCS0 | NotECNTransport, 127},
+	{DiffServAF11 | NotECNTransport, 255},
 }
 
 func TestTCPUnicastSockopt(t *testing.T) {