...
1
2
3
4
5 package icmp
6
7 import (
8 "encoding/binary"
9
10 "golang.org/x/net/internal/iana"
11 "golang.org/x/net/ipv4"
12 )
13
14
15 type ParamProb struct {
16 Pointer uintptr
17 Data []byte
18 Extensions []Extension
19 }
20
21
22 func (p *ParamProb) Len(proto int) int {
23 if p == nil {
24 return 0
25 }
26 l, _ := multipartMessageBodyDataLen(proto, true, p.Data, p.Extensions)
27 return l
28 }
29
30
31 func (p *ParamProb) Marshal(proto int) ([]byte, error) {
32 switch proto {
33 case iana.ProtocolICMP:
34 if !validExtensions(ipv4.ICMPTypeParameterProblem, p.Extensions) {
35 return nil, errInvalidExtension
36 }
37 b, err := marshalMultipartMessageBody(proto, true, p.Data, p.Extensions)
38 if err != nil {
39 return nil, err
40 }
41 b[0] = byte(p.Pointer)
42 return b, nil
43 case iana.ProtocolIPv6ICMP:
44 b := make([]byte, p.Len(proto))
45 binary.BigEndian.PutUint32(b[:4], uint32(p.Pointer))
46 copy(b[4:], p.Data)
47 return b, nil
48 default:
49 return nil, errInvalidProtocol
50 }
51 }
52
53
54 func parseParamProb(proto int, typ Type, b []byte) (MessageBody, error) {
55 if len(b) < 4 {
56 return nil, errMessageTooShort
57 }
58 p := &ParamProb{}
59 if proto == iana.ProtocolIPv6ICMP {
60 p.Pointer = uintptr(binary.BigEndian.Uint32(b[:4]))
61 p.Data = make([]byte, len(b)-4)
62 copy(p.Data, b[4:])
63 return p, nil
64 }
65 p.Pointer = uintptr(b[0])
66 var err error
67 p.Data, p.Extensions, err = parseMultipartMessageBody(proto, typ, b)
68 if err != nil {
69 return nil, err
70 }
71 return p, nil
72 }
73
View as plain text