icmp: add support for multi-part messages

ICMP extension structures allow a few existing ICMP error messages to
convey extra information for troubleshooting; especially the root cause
of why the original datagram could not be delivered.

This CL adds generic support for ICMP extension stuructures to
DstUnreach, TimeExceeded and ParamProb structs. Specific extensions such
as MPLS label-stack, interface and next-hop identification will be
inplemneted in separate followup CLs.

Change-Id: I90798c135bdf76b806e2dde2bdd57c2c11d7e7e9
diff --git a/icmp/dstunreach.go b/icmp/dstunreach.go
index 3f843cd..d1905a9 100644
--- a/icmp/dstunreach.go
+++ b/icmp/dstunreach.go
@@ -7,7 +7,8 @@
 // A DstUnreach represents an ICMP destination unreachable message
 // body.
 type DstUnreach struct {
-	Data []byte // data
+	Data       []byte      // data, known as original datagram field
+	Extensions []Extension // extensions
 }
 
 // Len implements the Len method of MessageBody interface.
diff --git a/icmp/extension.go b/icmp/extension.go
new file mode 100644
index 0000000..7575f02
--- /dev/null
+++ b/icmp/extension.go
@@ -0,0 +1,16 @@
+// Copyright 2015 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 icmp
+
+// An Extension represents an ICMP extension.
+type Extension interface {
+	// Len returns the length of ICMP extension.
+	Len() int
+
+	// Marshal returns the binary enconding of ICMP extension.
+	Marshal() ([]byte, error)
+}
+
+const extensionVersion = 2
diff --git a/icmp/message.go b/icmp/message.go
index 13398a0..4e6bec7 100644
--- a/icmp/message.go
+++ b/icmp/message.go
@@ -7,6 +7,7 @@
 // ICMPv4 and ICMPv6.
 //
 // ICMPv4 and ICMPv6 are defined in RFC 792 and RFC 4443.
+// Multi-part message support for ICMP is defined in RFC 4884.
 package icmp // import "golang.org/x/net/icmp"
 
 import (
diff --git a/icmp/paramprob.go b/icmp/paramprob.go
index ecf80ec..48ae601 100644
--- a/icmp/paramprob.go
+++ b/icmp/paramprob.go
@@ -8,8 +8,9 @@
 
 // A ParamProb represents an ICMP parameter problem message body.
 type ParamProb struct {
-	Pointer uintptr // offset within the data where the error was detected
-	Data    []byte  // data
+	Pointer    uintptr     // offset within the data where the error was detected
+	Data       []byte      // data, known as original datagram field
+	Extensions []Extension // extensions
 }
 
 // Len implements the Len method of MessageBody interface.
diff --git a/icmp/timeexceeded.go b/icmp/timeexceeded.go
index 0f0bb91..f61f431 100644
--- a/icmp/timeexceeded.go
+++ b/icmp/timeexceeded.go
@@ -6,7 +6,8 @@
 
 // A TimeExceeded represents an ICMP time exceeded message body.
 type TimeExceeded struct {
-	Data []byte // data
+	Data       []byte      // data, known as original datagram field
+	Extensions []Extension // extensions
 }
 
 // Len implements the Len method of MessageBody interface.