~ubuntu-branches/ubuntu/saucy/juju-core/saucy-proposed

« back to all changes in this revision

Viewing changes to src/code.google.com/p/go.net/ipv6/mockicmp_test.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-07-11 17:18:27 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20130711171827-vjqkg40r0dlf7ys2
Tags: 1.11.2-0ubuntu1
* New upstream release.
* Make juju-core the default juju (LP: #1190634):
  - d/control: Add virtual package juju -> juju-core.
  - d/juju-core.postinst.in: Bump priority of alternatives over that of
    python juju packages.
* Enable for all architectures (LP: #1172505):
  - d/control: Version BD on golang-go to >= 2:1.1.1 to ensure CGO
    support for non-x86 archs, make juju-core Arch: any.
  - d/README.source: Dropped - no longer required.
* d/watch: Updated for new upstream tarball naming.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 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
 
 
5
package ipv6_test
 
6
 
 
7
import (
 
8
        "code.google.com/p/go.net/ipv6"
 
9
        "errors"
 
10
)
 
11
 
 
12
// icmpMessage represents an ICMP message.
 
13
type icmpMessage struct {
 
14
        Type     ipv6.ICMPType   // type
 
15
        Code     int             // code
 
16
        Checksum int             // checksum
 
17
        Body     icmpMessageBody // body
 
18
}
 
19
 
 
20
// icmpMessageBody represents an ICMP message body.
 
21
type icmpMessageBody interface {
 
22
        Len() int
 
23
        Marshal() ([]byte, error)
 
24
}
 
25
 
 
26
// Marshal returns the binary enconding of the ICMP echo request or
 
27
// reply message m.
 
28
func (m *icmpMessage) Marshal() ([]byte, error) {
 
29
        b := []byte{byte(m.Type), byte(m.Code), 0, 0}
 
30
        if m.Body != nil && m.Body.Len() != 0 {
 
31
                mb, err := m.Body.Marshal()
 
32
                if err != nil {
 
33
                        return nil, err
 
34
                }
 
35
                b = append(b, mb...)
 
36
        }
 
37
        switch m.Type {
 
38
        case ipv6.ICMPTypeEchoRequest, ipv6.ICMPTypeEchoReply:
 
39
                return b, nil
 
40
        }
 
41
        csumcv := len(b) - 1 // checksum coverage
 
42
        s := uint32(0)
 
43
        for i := 0; i < csumcv; i += 2 {
 
44
                s += uint32(b[i+1])<<8 | uint32(b[i])
 
45
        }
 
46
        if csumcv&1 == 0 {
 
47
                s += uint32(b[csumcv])
 
48
        }
 
49
        s = s>>16 + s&0xffff
 
50
        s = s + s>>16
 
51
        // Place checksum back in header; using ^= avoids the
 
52
        // assumption the checksum bytes are zero.
 
53
        b[2] ^= byte(^s & 0xff)
 
54
        b[3] ^= byte(^s >> 8)
 
55
        return b, nil
 
56
}
 
57
 
 
58
// parseICMPMessage parses b as an ICMP message.
 
59
func parseICMPMessage(b []byte) (*icmpMessage, error) {
 
60
        msglen := len(b)
 
61
        if msglen < 4 {
 
62
                return nil, errors.New("message too short")
 
63
        }
 
64
        m := &icmpMessage{Type: ipv6.ICMPType(b[0]), Code: int(b[1]), Checksum: int(b[2])<<8 | int(b[3])}
 
65
        if msglen > 4 {
 
66
                var err error
 
67
                switch m.Type {
 
68
                case ipv6.ICMPTypeEchoRequest, ipv6.ICMPTypeEchoReply:
 
69
                        m.Body, err = parseICMPEcho(b[4:])
 
70
                        if err != nil {
 
71
                                return nil, err
 
72
                        }
 
73
                }
 
74
        }
 
75
        return m, nil
 
76
}
 
77
 
 
78
// imcpEcho represenets an ICMP echo request or reply message body.
 
79
type icmpEcho struct {
 
80
        ID   int    // identifier
 
81
        Seq  int    // sequence number
 
82
        Data []byte // data
 
83
}
 
84
 
 
85
func (p *icmpEcho) Len() int {
 
86
        if p == nil {
 
87
                return 0
 
88
        }
 
89
        return 4 + len(p.Data)
 
90
}
 
91
 
 
92
// Marshal returns the binary enconding of the ICMP echo request or
 
93
// reply message body p.
 
94
func (p *icmpEcho) Marshal() ([]byte, error) {
 
95
        b := make([]byte, 4+len(p.Data))
 
96
        b[0], b[1] = byte(p.ID>>8), byte(p.ID&0xff)
 
97
        b[2], b[3] = byte(p.Seq>>8), byte(p.Seq&0xff)
 
98
        copy(b[4:], p.Data)
 
99
        return b, nil
 
100
}
 
101
 
 
102
// parseICMPEcho parses b as an ICMP echo request or reply message
 
103
// body.
 
104
func parseICMPEcho(b []byte) (*icmpEcho, error) {
 
105
        bodylen := len(b)
 
106
        p := &icmpEcho{ID: int(b[0])<<8 | int(b[1]), Seq: int(b[2])<<8 | int(b[3])}
 
107
        if bodylen > 4 {
 
108
                p.Data = make([]byte, bodylen-4)
 
109
                copy(p.Data, b[4:])
 
110
        }
 
111
        return p, nil
 
112
}