added support for string type
[govpp.git] / vendor / github.com / google / gopacket / afpacket / options.go
1 // Copyright 2012 Google, Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the LICENSE file in the root of the source
5 // tree.
6
7 // +build linux
8
9 package afpacket
10
11 import (
12         "errors"
13         "fmt"
14         "time"
15 )
16
17 // #include <linux/if_packet.h>
18 // #include <sys/socket.h>
19 import "C"
20
21 // OptTPacketVersion is the version of TPacket to use.
22 // It can be passed into NewTPacket.
23 type OptTPacketVersion int
24
25 // String returns a string representation of the version, generally of the form V#.
26 func (t OptTPacketVersion) String() string {
27         switch t {
28         case TPacketVersion1:
29                 return "V1"
30         case TPacketVersion2:
31                 return "V2"
32         case TPacketVersion3:
33                 return "V3"
34         case TPacketVersionHighestAvailable:
35                 return "HighestAvailable"
36         }
37         return "InvalidVersion"
38 }
39
40 // OptSocketType is the socket type used to open the TPacket socket.
41 type OptSocketType int
42
43 func (t OptSocketType) String() string {
44         switch t {
45         case SocketRaw:
46                 return "SOCK_RAW"
47         case SocketDgram:
48                 return "SOCK_DGRAM"
49         }
50         return "UnknownSocketType"
51 }
52
53 // TPacket version numbers for use with NewHandle.
54 const (
55         // TPacketVersionHighestAvailable tells NewHandle to use the highest available version of tpacket the kernel has available.
56         // This is the default, should a version number not be given in NewHandle's options.
57         TPacketVersionHighestAvailable = OptTPacketVersion(-1)
58         TPacketVersion1                = OptTPacketVersion(C.TPACKET_V1)
59         TPacketVersion2                = OptTPacketVersion(C.TPACKET_V2)
60         TPacketVersion3                = OptTPacketVersion(C.TPACKET_V3)
61         tpacketVersionMax              = TPacketVersion3
62         tpacketVersionMin              = -1
63         // SocketRaw is the default socket type.  It returns packet data
64         // including the link layer (ethernet headers, etc).
65         SocketRaw = OptSocketType(C.SOCK_RAW)
66         // SocketDgram strips off the link layer when reading packets, and adds
67         // the link layer back automatically on packet writes (coming soon...)
68         SocketDgram = OptSocketType(C.SOCK_DGRAM)
69 )
70
71 // OptInterface is the specific interface to bind to.
72 // It can be passed into NewTPacket.
73 type OptInterface string
74
75 // OptFrameSize is TPacket's tp_frame_size
76 // It can be passed into NewTPacket.
77 type OptFrameSize int
78
79 // OptBlockSize is TPacket's tp_block_size
80 // It can be passed into NewTPacket.
81 type OptBlockSize int
82
83 // OptNumBlocks is TPacket's tp_block_nr
84 // It can be passed into NewTPacket.
85 type OptNumBlocks int
86
87 // OptBlockTimeout is TPacket v3's tp_retire_blk_tov.  Note that it has only millisecond granularity, so must be >= 1 ms.
88 // It can be passed into NewTPacket.
89 type OptBlockTimeout time.Duration
90
91 // OptPollTimeout is the number of milliseconds that poll() should block waiting  for a file
92 // descriptor to become ready. Specifying a negative value in  timeā€out means an infinite timeout.
93 type OptPollTimeout time.Duration
94
95 // Default constants used by options.
96 const (
97         DefaultFrameSize    = 4096                   // Default value for OptFrameSize.
98         DefaultBlockSize    = DefaultFrameSize * 128 // Default value for OptBlockSize.
99         DefaultNumBlocks    = 128                    // Default value for OptNumBlocks.
100         DefaultBlockTimeout = 64 * time.Millisecond  // Default value for OptBlockTimeout.
101         DefaultPollTimeout  = -1 * time.Millisecond  // Default value for OptPollTimeout. This blocks forever.
102 )
103
104 type options struct {
105         frameSize      int
106         framesPerBlock int
107         blockSize      int
108         numBlocks      int
109         blockTimeout   time.Duration
110         pollTimeout    time.Duration
111         version        OptTPacketVersion
112         socktype       OptSocketType
113         iface          string
114 }
115
116 var defaultOpts = options{
117         frameSize:    DefaultFrameSize,
118         blockSize:    DefaultBlockSize,
119         numBlocks:    DefaultNumBlocks,
120         blockTimeout: DefaultBlockTimeout,
121         pollTimeout:  DefaultPollTimeout,
122         version:      TPacketVersionHighestAvailable,
123         socktype:     SocketRaw,
124 }
125
126 func parseOptions(opts ...interface{}) (ret options, err error) {
127         ret = defaultOpts
128         for _, opt := range opts {
129                 switch v := opt.(type) {
130                 case OptFrameSize:
131                         ret.frameSize = int(v)
132                 case OptBlockSize:
133                         ret.blockSize = int(v)
134                 case OptNumBlocks:
135                         ret.numBlocks = int(v)
136                 case OptBlockTimeout:
137                         ret.blockTimeout = time.Duration(v)
138                 case OptPollTimeout:
139                         ret.pollTimeout = time.Duration(v)
140                 case OptTPacketVersion:
141                         ret.version = v
142                 case OptInterface:
143                         ret.iface = string(v)
144                 case OptSocketType:
145                         ret.socktype = v
146                 default:
147                         err = errors.New("unknown type in options")
148                         return
149                 }
150         }
151         if err = ret.check(); err != nil {
152                 return
153         }
154         ret.framesPerBlock = ret.blockSize / ret.frameSize
155         return
156 }
157 func (o options) check() error {
158         switch {
159         case o.blockSize%pageSize != 0:
160                 return fmt.Errorf("block size %d must be divisible by page size %d", o.blockSize, pageSize)
161         case o.blockSize%o.frameSize != 0:
162                 return fmt.Errorf("block size %d must be divisible by frame size %d", o.blockSize, o.frameSize)
163         case o.numBlocks < 1:
164                 return fmt.Errorf("num blocks %d must be >= 1", o.numBlocks)
165         case o.blockTimeout < time.Millisecond:
166                 return fmt.Errorf("block timeout %v must be > %v", o.blockTimeout, time.Millisecond)
167         case o.version < tpacketVersionMin || o.version > tpacketVersionMax:
168                 return fmt.Errorf("tpacket version %v is invalid", o.version)
169         }
170         return nil
171 }