]>
git.proxmox.com Git - mirror_ovs.git/blob - tests/flowgen.py
1 #! /usr/bin/env python3
3 # Copyright (c) 2009, 2010, 2011, 2012, 2015, 2017 Nicira, Inc.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at:
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
22 octets
= ea
.split(':')
23 assert len(octets
) == 6
24 return b
''.join([struct
.pack('B', int(octet
, 16)) for octet
in octets
])
31 flow
['DL_SRC'] = "00:02:e3:0f:80:a4"
32 flow
['DL_DST'] = "00:1a:92:40:ac:05"
35 flow
['NW_SRC'] = '0.0.0.0'
36 flow
['NW_DST'] = '0.0.0.0'
39 if 'DL_VLAN' in attrs
:
40 flow
['DL_VLAN'] = {'none': 0xffff,
42 'nonzero': 0x0123}[attrs
['DL_VLAN']]
44 flow
['DL_VLAN'] = 0xffff # OFP_VLAN_NONE
45 if attrs
['DL_HEADER'] == '802.2':
46 flow
['DL_TYPE'] = 0x5ff # OFP_DL_TYPE_NOT_ETH_TYPE
47 elif attrs
['DL_TYPE'] == 'ip':
48 flow
['DL_TYPE'] = 0x0800 # ETH_TYPE_IP
49 flow
['NW_SRC'] = '10.0.2.15'
50 flow
['NW_DST'] = '192.168.1.20'
52 if attrs
['TP_PROTO'] == 'other':
54 elif attrs
['TP_PROTO'] in ('TCP', 'TCP+options'):
55 flow
['NW_PROTO'] = 6 # IPPROTO_TCP
58 elif attrs
['TP_PROTO'] == 'UDP':
59 flow
['NW_PROTO'] = 17 # IPPROTO_UDP
62 elif attrs
['TP_PROTO'] == 'ICMP':
63 flow
['NW_PROTO'] = 1 # IPPROTO_ICMP
64 flow
['TP_SRC'] = 8 # echo request
65 flow
['TP_DST'] = 0 # code
68 if attrs
['IP_FRAGMENT'] not in ('no', 'first'):
69 flow
['TP_SRC'] = flow
['TP_DST'] = 0
70 elif attrs
['DL_TYPE'] == 'non-ip':
71 flow
['DL_TYPE'] = 0x5678
77 wildcards
= 1 << 5 |
1 << 6 |
1 << 7 |
32 << 8 |
32 << 14 |
1 << 21
79 packet
+= pack_ethaddr(flow
['DL_DST'])
80 packet
+= pack_ethaddr(flow
['DL_SRC'])
81 if flow
['DL_VLAN'] != 0xffff:
82 packet
+= struct
.pack('>HH', 0x8100, flow
['DL_VLAN'])
84 if attrs
['DL_HEADER'].startswith('802.2'):
85 packet
+= struct
.pack('>H', 0)
86 if attrs
['DL_HEADER'] == '802.2':
87 packet
+= struct
.pack('BBB', 0x42, 0x42, 0x03) # LLC for 802.1D STP
89 if attrs
['DL_HEADER'] == '802.2+SNAP':
90 packet
+= struct
.pack('BBB', 0xaa, 0xaa, 0x03) # LLC for SNAP
91 packet
+= struct
.pack('BBB', 0, 0, 0) # SNAP OUI
92 packet
+= struct
.pack('>H', flow
['DL_TYPE'])
93 if attrs
['DL_TYPE'] == 'ip':
94 ip
= struct
.pack('>BBHHHBBHLL',
95 (4 << 4) |
5, # version, hdrlen
96 flow
['NW_TOS'], # type of service
97 0, # total length, filled in later
101 flow
['NW_PROTO'], # protocol
105 wildcards
&= ~
(1 << 5 |
63 << 8 |
63 << 14 |
1 << 21)
106 if attrs
['IP_OPTIONS'] == 'yes':
107 ip
= struct
.pack('B', (4 << 4) |
8) + ip
[1:]
108 ip
+= struct
.pack('>BBHHHBBBx',
117 if attrs
['IP_FRAGMENT'] != 'no':
118 frag_map
= {'first': 0x2000, # more frags, ofs 0
119 'middle': 0x2111, # more frags, ofs 0x888
120 'last': 0x0222} # last frag, ofs 0x1110
122 + struct
.pack('>H', frag_map
[attrs
['IP_FRAGMENT']])
124 if attrs
['IP_FRAGMENT'] in ('no', 'first'):
125 if attrs
['TP_PROTO'].startswith('TCP'):
126 tcp
= struct
.pack('>HHLLHHHH',
127 flow
['TP_SRC'], # source port
128 flow
['TP_DST'], # dest port
131 (5 << 12) |
0x02 |
0x10,
135 12893) # urgent pointer
136 if attrs
['TP_PROTO'] == 'TCP+options':
138 + struct
.pack('H', (6 << 12) |
0x02 |
0x10)
140 tcp
+= struct
.pack('>BBH', 2, 4, 1975) # MSS option
143 wildcards
&= ~
(1 << 6 |
1 << 7)
144 elif attrs
['TP_PROTO'] == 'UDP':
146 udp
= struct
.pack('>HHHH',
150 while len(udp
) < udp_len
:
151 udp
+= struct
.pack('B', udp_len
)
153 wildcards
&= ~
(1 << 6 |
1 << 7)
154 elif attrs
['TP_PROTO'] == 'ICMP':
155 ip
+= struct
.pack('>BBHHH',
160 931) # sequence number
161 wildcards
&= ~
(1 << 6 |
1 << 7)
162 elif attrs
['TP_PROTO'] == 'other':
163 ip
+= b
'other header'
166 ip
= ip
[:2] + struct
.pack('>H', len(ip
)) + ip
[4:]
168 if attrs
['DL_HEADER'].startswith('802.2'):
169 packet_len
= len(packet
)
170 if flow
['DL_VLAN'] != 0xffff:
172 packet
= (packet
[:len_ofs
]
173 + struct
.pack('>H', packet_len
)
174 + packet
[len_ofs
+ 2:])
176 print(' '.join(['%s=%s' for k
, v
in attrs
.items()]))
177 print(' '.join(['%s=%s' for k
, v
in flow
.items()]))
180 flows
.write(struct
.pack('>LH',
181 wildcards
, # wildcards
183 flows
.write(pack_ethaddr(flow
['DL_SRC']))
184 flows
.write(pack_ethaddr(flow
['DL_DST']))
185 flows
.write(struct
.pack('>HBxHBBxx',
191 flows
.write(socket
.inet_aton(flow
['NW_SRC']))
192 flows
.write(socket
.inet_aton(flow
['NW_DST']))
193 flows
.write(struct
.pack('>HH', flow
['TP_SRC'], flow
['TP_DST']))
195 packets
.write(struct
.pack('>LLLL',
196 0, # timestamp seconds
197 0, # timestamp microseconds
198 len(packet
), # bytes saved
199 len(packet
))) # total length
200 packets
.write(packet
)
203 flows
= open('flows', 'wb')
204 packets
= open('pcap', 'wb')
206 # Print pcap file header.
207 packets
.write(struct
.pack('>LHHLLLL',
208 0xa1b2c3d4, # magic number
211 0, # time zone offset
212 0, # time stamp accuracy
216 output({'DL_HEADER': '802.2'})
218 for dl_header
in ('802.2+SNAP', 'Ethernet'):
219 a
= {'DL_HEADER': dl_header
}
220 for dl_vlan
in ('none', 'zero', 'nonzero'):
222 b
['DL_VLAN'] = dl_vlan
226 c
['DL_TYPE'] = 'non-ip'
229 for ip_options
in ('no', 'yes'):
232 c
['IP_OPTIONS'] = ip_options
233 for ip_fragment
in ('no', 'first', 'middle', 'last'):
235 d
['IP_FRAGMENT'] = ip_fragment
236 for tp_proto
in ('TCP', 'TCP+options', 'UDP', 'ICMP', 'other'):
238 e
['TP_PROTO'] = tp_proto