• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# coding: utf8
2% ProfinetIO DCP layer test campaign
3
4+ Syntax check
5= Import the ProfinetIO layer
6from scapy.contrib.pnio import *
7from scapy.contrib.pnio_dcp import *
8from scapy.config import conf
9import re
10old_conf_dissector = conf.debug_dissector
11conf.debug_dissector=True
12
13+ PNIO DCP PDU tests
14
15
16= DCP Identify All Request parsing
17
18p = Ether(b'\x01\x0e\xcf\x00\x00\x00\x01\x23\x45\x67\x89\xab\x88\x92\xfe\xfe' \
19    b'\x05\x00\x01\x00\x00\x01\x00\x01\x00\x04\xff\xff\x00\x00\x00\x00' \
20    b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
21    b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
22
23assert p[Ether].dst == '01:0e:cf:00:00:00'
24assert p[Ether].src == '01:23:45:67:89:ab'
25assert p[Ether].type == 0x8892
26assert p[ProfinetIO].frameID == 0xfefe
27assert p[ProfinetDCP].service_id == 0x05
28assert p[ProfinetDCP].service_type == 0x00
29assert p[ProfinetDCP].xid == 0x1000001
30assert p[ProfinetDCP].reserved == 0x01
31assert p[ProfinetDCP].dcp_data_length == 0x04
32assert p[ProfinetDCP].option == 0xff
33assert p[ProfinetDCP].sub_option == 0xff
34assert p[ProfinetDCP].dcp_block_length == 0x00
35
36
37= DCP Set Request parsing
38
39p = Ether(b'\x01\x23\x45\x67\x89\xac\x01\x23\x45\x67\x89\xab\x88\x92\xfe\xfd' \
40       b'\x04\x00\x00\x00\x00\x01\x00\x00\x00\x0c\x02\x02\x00\x08\x00\x01' \
41       b'\x64\x65\x76\x69\x63\x65\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
42       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
43
44assert p[Ether].dst == '01:23:45:67:89:ac'
45assert p[Ether].src == '01:23:45:67:89:ab'
46assert p[Ether].type == 0x8892
47assert p[ProfinetIO].frameID == 0xfefd
48assert p[ProfinetDCP].service_id == 0x04
49assert p[ProfinetDCP].service_type == 0x00
50assert p[ProfinetDCP].xid == 0x0000001
51assert p[ProfinetDCP].reserved == 0x00
52assert p[ProfinetDCP].dcp_data_length == 0x0c
53assert p[ProfinetDCP].option == 0x02
54assert p[ProfinetDCP].sub_option == 0x02
55assert p[ProfinetDCP].dcp_block_length == 0x08
56assert p[ProfinetDCP].block_qualifier ==  0x01
57
58
59= DCP Identify Response parsing
60
61p = Ether(b'\x94\x65\x9c\x51\x90\x7d\xac\x64\x17\x21\x35\xcf\x81\x00\x00\x00' \
62       b'\x88\x92\xfe\xff\x05\x01\x01\x00\x00\x01\x00\x00\x00\x4e\x02\x05' \
63       b'\x00\x04\x00\x00\x02\x07\x02\x01\x00\x09\x00\x00\x45\x54\x32\x30' \
64       b'\x30\x53\x50\x00\x02\x02\x00\x08\x00\x00\x64\x65\x76\x69\x63\x65' \
65       b'\x02\x03\x00\x06\x00\x00\x00\x2a\x03\x13\x02\x04\x00\x04\x00\x00' \
66       b'\x01\x00\x02\x07\x00\x04\x00\x00\x00\x01\x01\x02\x00\x0e\x00\x01' \
67       b'\xc0\xa8\x01\x0e\xff\xff\xff\x00\xc0\xa8\x01\x0e')
68
69# General
70assert p[ProfinetIO].frameID == 0xfeff
71assert p[ProfinetDCP].service_id == 0x05
72assert p[ProfinetDCP].service_type == 0x01
73assert p[ProfinetDCP].xid == 0x1000001
74assert p[ProfinetDCP].reserved == 0x00
75assert p[ProfinetDCP].dcp_data_length == 0x4e
76
77# - DCPDeviceOptionsBlock
78assert p[DCPDeviceOptionsBlock].option == 0x02
79assert p[DCPDeviceOptionsBlock].sub_option == 0x05
80assert p[DCPDeviceOptionsBlock].dcp_block_length == 0x04
81assert p[DCPDeviceOptionsBlock].block_info == 0x00
82
83# -- DeviceOption
84assert p[DeviceOption].option == 0x02
85assert p[DeviceOption].sub_option == 0x07
86
87# - DCPManufacturerSpecificBlock
88assert p[DCPManufacturerSpecificBlock].option == 0x02
89assert p[DCPManufacturerSpecificBlock].sub_option == 0x01
90assert p[DCPManufacturerSpecificBlock].dcp_block_length == 0x09
91assert p[DCPManufacturerSpecificBlock].block_info == 0x00
92assert p[DCPManufacturerSpecificBlock].device_vendor_value == b'ET200SP'
93
94# - DCPNameOfStationBlock
95assert p[DCPNameOfStationBlock].option == 0x02
96assert p[DCPNameOfStationBlock].sub_option == 0x02
97assert p[DCPNameOfStationBlock].dcp_block_length == 0x08
98assert p[DCPNameOfStationBlock].block_info == 0x00
99assert p[DCPNameOfStationBlock].name_of_station == b'device'
100
101# - DCPDeviceIDBlock
102assert p[DCPDeviceIDBlock].option == 0x02
103assert p[DCPDeviceIDBlock].sub_option == 0x03
104assert p[DCPDeviceIDBlock].dcp_block_length == 0x06
105assert p[DCPDeviceIDBlock].block_info == 0x00
106assert p[DCPDeviceIDBlock].vendor_id == 0x002a
107assert p[DCPDeviceIDBlock].device_id == 0x0313
108
109# - DCPDeviceRoleBlock
110assert p[DCPDeviceRoleBlock].option == 0x02
111assert p[DCPDeviceRoleBlock].sub_option == 0x04
112assert p[DCPDeviceRoleBlock].dcp_block_length == 0x04
113assert p[DCPDeviceRoleBlock].block_info == 0x00
114assert p[DCPDeviceRoleBlock].device_role_details == 0x01
115
116# - DCPDeviceInstanceBlock
117assert p[DCPDeviceInstanceBlock].option == 0x02
118assert p[DCPDeviceInstanceBlock].sub_option == 0x07
119assert p[DCPDeviceInstanceBlock].dcp_block_length == 0x04
120assert p[DCPDeviceInstanceBlock].block_info == 0x00
121assert p[DCPDeviceInstanceBlock].device_instance_high == 0x00
122assert p[DCPDeviceInstanceBlock].device_instance_low == 0x01
123
124# - DCPIPBlock
125assert p[DCPIPBlock].option == 0x01
126assert p[DCPIPBlock].sub_option == 0x02
127assert p[DCPIPBlock].dcp_block_length == 0x0e
128assert p[DCPIPBlock].block_info == 0x01
129assert p[DCPIPBlock].ip == "192.168.1.14"
130assert p[DCPIPBlock].netmask == "255.255.255.0"
131assert p[DCPIPBlock].gateway == "192.168.1.14"
132
133= DCP Identify Response parsing with new DCP packages (DCPOEMIDBlock, DCPDeviceInitiativeBlock)
134
135p = Ether(b'\x01\x0e\xcf\x00\x00\x00\x01\x23\x45\x67\x89\xab\x88\x92' \
136    b'\xfe\xff\x05\x01\x01\x00\x00\x01\x00\x00\x00\x7a\x02\x02\x00\x02\x00' \
137    b'\x00\x01\x02\x00\x0e\x00\x01\xc0\xa8\x01\x0b\xff\xff\xff\x00\x00\x00' \
138    b'\x00\x00\x02\x03\x00\x06\x00\x00\x01\x6a\x04\x00\x02\x05\x00\x16\x00' \
139    b'\x00\x01\x01\x01\x02\x02\x01\x02\x02\x02\x03\x02\x04\x02\x05\x02\x07' \
140    b'\x02\x08\x06\x01\x02\x04\x00\x04\x00\x00\x01\x00\x06\x01\x00\x04\x00' \
141    b'\x00\x00\x00\x02\x01\x00\x18\x00\x00\x31\x32\x33\x34\x20\x44\x44\x44'
142    b'\x20\x33\x58\x58\x32\x2d\x31\x32\x31\x2d\x30\x46\x44\x44\x02\x07\x00' \
143    b'\x04\x00\x00\x00\x01\x02\x08\x00\x06\x00\x00\x01\x1e\xff\xff')
144
145# - General
146assert p[Ether].dst == '01:0e:cf:00:00:00'
147assert p[Ether].src == '01:23:45:67:89:ab'
148assert p[Ether].type == 0x8892
149assert p[ProfinetIO].frameID == 0xFEFF
150assert p[ProfinetDCP].service_id == 0x05
151assert p[ProfinetDCP].service_type == 0x01
152assert p[ProfinetDCP].xid == 0x1000001
153assert p[ProfinetDCP].reserved == 0x00
154assert p[ProfinetDCP].dcp_data_length == 122
155assert list(map(lambda x: type(x), p[ProfinetDCP].dcp_blocks)) == [DCPNameOfStationBlock, DCPIPBlock, DCPDeviceIDBlock, DCPDeviceOptionsBlock, DCPDeviceRoleBlock, DCPDeviceInitiativeBlock, DCPManufacturerSpecificBlock, DCPDeviceInstanceBlock, DCPOEMIDBlock]
156
157# - DCPNameOfStationBlock
158assert p[DCPNameOfStationBlock].option == 0x02
159assert p[DCPNameOfStationBlock].sub_option == 0x02
160
161# - DCPIPBlock
162assert p[DCPIPBlock].option == 0x01
163assert p[DCPIPBlock].sub_option == 0x02
164assert p[DCPIPBlock].dcp_block_length == 0x0E
165assert p[DCPIPBlock].ip == '192.168.1.11'
166assert p[DCPIPBlock].netmask == '255.255.255.0'
167assert p[DCPIPBlock].gateway == '0.0.0.0'
168
169# - DCPDeviceInitiativeBlock
170assert p[DCPDeviceInitiativeBlock].option == 0x06
171assert p[DCPDeviceInitiativeBlock].sub_option == 0x01
172assert p[DCPDeviceInitiativeBlock].dcp_block_length == 0x04
173assert p[DCPDeviceInitiativeBlock].device_initiative == 0x0000
174
175# - DCPManufacturerSpecificBlock
176assert p[DCPManufacturerSpecificBlock].option == 0x02
177assert p[DCPManufacturerSpecificBlock].sub_option == 0x01
178assert p[DCPManufacturerSpecificBlock].device_vendor_value == b'1234 DDD 3XX2-121-0FDD'
179
180# - DCPOEMIDBlock
181assert p[DCPOEMIDBlock].option == 0x02
182assert p[DCPOEMIDBlock].sub_option == 0x08
183assert p[DCPOEMIDBlock].dcp_block_length == 0x06
184assert p[DCPOEMIDBlock].vendor_id == 0x011e
185assert p[DCPOEMIDBlock].device_id == 0xffff
186
187= DCP Set Request parsing
188
189p = Ether(b'\x94\x65\x9c\x51\x90\x7d\xac\x64\x17\x21\x35\xcf\x81\x00\x00\x00' \
190      b'\x88\x92\xfe\xfd\x04\x01\x00\x00\x00\x01\x00\x00\x00\x08\x05\x04' \
191      b'\x00\x03\x02\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
192      b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
193
194assert p[ProfinetIO].frameID == 0xfefd
195assert p[ProfinetDCP].service_id == 0x04
196assert p[ProfinetDCP].service_type == 0x01
197assert p[ProfinetDCP].xid == 0x0000001
198assert p[ProfinetDCP].reserved == 0x00
199assert p[ProfinetDCP].dcp_data_length == 0x08
200
201assert p[DCPControlBlock].option == 0x05
202assert p[DCPControlBlock].sub_option == 0x04
203assert p[DCPControlBlock].dcp_block_length == 0x03
204assert p[DCPControlBlock].response == 0x02
205assert p[DCPControlBlock].response_sub_option == 0x02
206assert p[DCPControlBlock].block_error == 0x00
207
208
209= DCP Set Full IP Suite Request parsing
210
211p = Ether(b'\x12\x34\x00\x78\x90\xab\xc8\x5b\x76\xe6\x89\xdf' \
212      b'\x88\x92\xfe\xfd\x04\x00\x00\x00\x00\x04\x00\x00' \
213      b'\x00\x28\x01\x03\x00\x1e\x00\x00\xc0\xa8\x01\xab' \
214      b'\xff\xff\xff\x00\xc0\xa8\x01\x01\x01\x02\x03\x04' \
215      b'\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00')
216
217assert p[ProfinetIO].frameID == 0xfefd
218assert p[ProfinetDCP].service_id == 0x04
219assert p[ProfinetDCP].service_type == 0x00
220assert p[ProfinetDCP].xid == 0x0000004
221assert p[ProfinetDCP].reserved == 0x00
222assert p[ProfinetDCP].dcp_data_length == 40
223assert p[ProfinetDCP].option == 0x01
224assert p[ProfinetDCP].sub_option == 0x03
225assert p[ProfinetDCP].ip == "192.168.1.171"
226assert p[ProfinetDCP].netmask == "255.255.255.0"
227assert p[ProfinetDCP].gateway == "192.168.1.1"
228assert p[ProfinetDCP].dnsaddr[0] == "1.2.3.4"
229assert p[ProfinetDCP].dnsaddr[1] == "5.6.7.8"
230assert p[ProfinetDCP].dnsaddr[2] == "0.0.0.0"
231assert p[ProfinetDCP].dnsaddr[3] == "0.0.0.0"
232
233
234= DCP Identify All Request crafting
235
236# dcp_data_length cannot be calculated automatically at this time
237p = ProfinetIO(frameID=DCP_IDENTIFY_REQUEST_FRAME_ID) / ProfinetDCP(service_id=DCP_SERVICE_ID_IDENTIFY, service_type=DCP_REQUEST, option=255, sub_option=255, dcp_data_length=4)
238
239assert p[ProfinetIO].frameID == 0xfefe
240assert p[ProfinetDCP].service_id == 0x05
241assert p[ProfinetDCP].service_type == 0x00
242assert p[ProfinetDCP].xid == 0x1000001
243assert p[ProfinetDCP].reserved == 0x00
244assert p[ProfinetDCP].dcp_data_length == 0x04
245assert p[ProfinetDCP].option == 0xff
246assert p[ProfinetDCP].sub_option == 0xff
247assert p[ProfinetDCP].dcp_block_length == 0x00
248
249
250= DCP Set Name Request with specified name crafting
251
252p = ProfinetIO(frameID=DCP_GET_SET_FRAME_ID) / ProfinetDCP ( service_id=DCP_SERVICE_ID_SET, service_type=DCP_REQUEST, option=2, sub_option=2, name_of_station="device", dcp_block_length=8, dcp_data_length=12)
253
254assert p[ProfinetIO].frameID == 0xfefd
255assert p[ProfinetDCP].service_id == 0x04
256assert p[ProfinetDCP].service_type == 0x00
257assert p[ProfinetDCP].xid == 0x1000001
258assert p[ProfinetDCP].reserved == 0x00
259assert p[ProfinetDCP].dcp_data_length == 0x0c
260assert p[ProfinetDCP].option == 0x02
261assert p[ProfinetDCP].sub_option == 0x02
262assert p[ProfinetDCP].dcp_block_length == 0x08
263assert p[ProfinetDCP].block_qualifier == 0x0001
264
265
266= DCP Identify Response crafting
267
268p = ProfinetIO(frameID=DCP_IDENTIFY_RESPONSE_FRAME_ID) / ProfinetDCP(service_id=DCP_SERVICE_ID_IDENTIFY, service_type=DCP_RESPONSE, dcp_data_length=12) / DCPNameOfStationBlock(name_of_station="device", dcp_block_length=8)
269
270assert p[ProfinetIO].frameID == 0xfeff
271assert p[ProfinetDCP].service_id == 0x05
272assert p[ProfinetDCP].service_type == 0x01
273assert p[ProfinetDCP].xid == 0x1000001
274assert p[ProfinetDCP].reserved == 0x00
275assert p[ProfinetDCP].dcp_data_length == 0x0c
276assert p[DCPNameOfStationBlock].option == 0x02
277assert p[DCPNameOfStationBlock].sub_option == 0x02
278assert p[DCPNameOfStationBlock].dcp_block_length == 0x08
279assert p[DCPNameOfStationBlock].block_info == 0x00
280assert p[DCPNameOfStationBlock].name_of_station == b'device'
281
282
283= DCP Set Full IP Suite Request crafting
284
285p = ProfinetIO(frameID=DCP_GET_SET_FRAME_ID) / ProfinetDCP(service_id=DCP_SERVICE_ID_SET, service_type=DCP_REQUEST, option=1, sub_option=3, ip='192.168.1.171', netmask='255.255.255.0', gateway='192.168.1.1', dnsaddr=['1.2.3.4', '5.6.7.8'], dcp_data_length=40, dcp_block_length=30)
286
287assert p[ProfinetIO].frameID == 0xfefd
288assert p[ProfinetDCP].service_id == 0x04
289assert p[ProfinetDCP].service_type == 0x00
290assert p[ProfinetDCP].xid == 0x1000001
291assert p[ProfinetDCP].reserved == 0x00
292assert p[ProfinetDCP].dcp_data_length == 40
293assert p[ProfinetDCP].option == 0x01
294assert p[ProfinetDCP].sub_option == 0x03
295assert p[ProfinetDCP].ip == "192.168.1.171"
296assert p[ProfinetDCP].netmask == "255.255.255.0"
297assert p[ProfinetDCP].gateway == "192.168.1.1"
298assert p[ProfinetDCP].dnsaddr[0] == "1.2.3.4"
299assert p[ProfinetDCP].dnsaddr[1] == "5.6.7.8"
300
301
302conf.debug_dissector = old_conf_dissector
303