1// Copyright 2014 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 5package icmp 6 7import ( 8 "golang.org/x/net/internal/iana" 9 "golang.org/x/net/ipv4" 10 "golang.org/x/net/ipv6" 11) 12 13// A DstUnreach represents an ICMP destination unreachable message 14// body. 15type DstUnreach struct { 16 Data []byte // data, known as original datagram field 17 Extensions []Extension // extensions 18} 19 20// Len implements the Len method of MessageBody interface. 21func (p *DstUnreach) Len(proto int) int { 22 if p == nil { 23 return 0 24 } 25 l, _ := multipartMessageBodyDataLen(proto, true, p.Data, p.Extensions) 26 return l 27} 28 29// Marshal implements the Marshal method of MessageBody interface. 30func (p *DstUnreach) Marshal(proto int) ([]byte, error) { 31 var typ Type 32 switch proto { 33 case iana.ProtocolICMP: 34 typ = ipv4.ICMPTypeDestinationUnreachable 35 case iana.ProtocolIPv6ICMP: 36 typ = ipv6.ICMPTypeDestinationUnreachable 37 default: 38 return nil, errInvalidProtocol 39 } 40 if !validExtensions(typ, p.Extensions) { 41 return nil, errInvalidExtension 42 } 43 return marshalMultipartMessageBody(proto, true, p.Data, p.Extensions) 44} 45 46// parseDstUnreach parses b as an ICMP destination unreachable message 47// body. 48func parseDstUnreach(proto int, typ Type, b []byte) (MessageBody, error) { 49 if len(b) < 4 { 50 return nil, errMessageTooShort 51 } 52 p := &DstUnreach{} 53 var err error 54 p.Data, p.Extensions, err = parseMultipartMessageBody(proto, typ, b) 55 if err != nil { 56 return nil, err 57 } 58 return p, nil 59} 60