1 // Copyright 2012 Google, Inc. All rights reserved.
2 // Copyright 2009-2011 Andreas Krennmair. All rights reserved.
4 // Use of this source code is governed by a BSD-style license
5 // that can be found in the LICENSE file in the root of the source
13 "github.com/google/gopacket"
16 // UDP is the layer for UDP headers.
19 SrcPort, DstPort UDPPort
26 // LayerType returns gopacket.LayerTypeUDP
27 func (u *UDP) LayerType() gopacket.LayerType { return LayerTypeUDP }
29 func (udp *UDP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
30 udp.SrcPort = UDPPort(binary.BigEndian.Uint16(data[0:2]))
32 udp.DstPort = UDPPort(binary.BigEndian.Uint16(data[2:4]))
34 udp.Length = binary.BigEndian.Uint16(data[4:6])
35 udp.Checksum = binary.BigEndian.Uint16(data[6:8])
36 udp.BaseLayer = BaseLayer{Contents: data[:8]}
39 hlen := int(udp.Length)
44 udp.Payload = data[8:hlen]
45 case udp.Length == 0: // Jumbogram, use entire rest of data
46 udp.Payload = data[8:]
48 return fmt.Errorf("UDP packet too small: %d bytes", udp.Length)
53 // SerializeTo writes the serialized form of this layer into the
54 // SerializationBuffer, implementing gopacket.SerializableLayer.
55 // See the docs for gopacket.SerializableLayer for more info.
56 func (u *UDP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
60 if _, ok := u.pseudoheader.(*IPv6); ok {
61 if len(payload)+8 > 65535 {
65 bytes, err := b.PrependBytes(8)
69 binary.BigEndian.PutUint16(bytes, uint16(u.SrcPort))
70 binary.BigEndian.PutUint16(bytes[2:], uint16(u.DstPort))
75 u.Length = uint16(len(payload)) + 8
78 binary.BigEndian.PutUint16(bytes[4:], u.Length)
79 if opts.ComputeChecksums {
80 // zero out checksum bytes
83 csum, err := u.computeChecksum(b.Bytes(), IPProtocolUDP)
89 binary.BigEndian.PutUint16(bytes[6:], u.Checksum)
93 func (u *UDP) CanDecode() gopacket.LayerClass {
97 // NextLayerType use the destination port to select the
98 // right next decoder. It tries first to decode via the
99 // destination port, then the source port.
100 func (u *UDP) NextLayerType() gopacket.LayerType {
101 if lt := u.DstPort.LayerType(); lt != gopacket.LayerTypePayload {
104 return u.SrcPort.LayerType()
107 func decodeUDP(data []byte, p gopacket.PacketBuilder) error {
109 err := udp.DecodeFromBytes(data, p)
111 p.SetTransportLayer(udp)
115 return p.NextDecoder(udp.NextLayerType())
118 func (u *UDP) TransportFlow() gopacket.Flow {
119 return gopacket.NewFlow(EndpointUDPPort, u.sPort, u.dPort)