blob: 398a52d34551cf2db25b378c360d5fa03fe20995 [file] [log] [blame]
Ting Xuce4b6452022-04-24 06:14:25 +00001# Copyright (c) 2022 Intel and/or its affiliates.
2# Licensed under the Apache License, Version 2.0 (the "License");
3# you may not use this file except in compliance with the License.
4# You may obtain a copy of the License at:
5#
6# http://www.apache.org/licenses/LICENSE-2.0
7#
8# Unless required by applicable law or agreed to in writing, software
9# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13
14from ProtocolHeaderAttribute import *
15from ProtocolHeaderField import *
16from InputFormat import *
17import ExpressionConverter
18import copy
19
20
21class ProtocolHeader:
22 def __init__(self, node):
23 self.fields = []
24 self.attributes = []
25 self.fieldDict = {}
26 self.attributeDict = {}
27 self.Buffer = []
28 self.Mask = []
29
30 self.node = node
31 for field in self.node.fields:
32 phf = ProtocolHeaderField(field.Size, field.DefaultValue, None, field)
33 self.fields.append(phf)
34 if field.Name != "reserved":
35 self.fieldDict[field.Name] = phf
36
37 for attr in self.node.attributes:
38 pha = ProtocolHeaderAttribute(attr.Size, attr.DefaultValue, attr)
39 self.attributes.append(pha)
40 self.attributeDict[attr.Name] = pha
41
42 def Name(self):
43 return self.node.Name
44
45 def Fields(self):
46 return self.fields
47
48 def Attributes(self):
49 return self.attributes
50
51 def setField(self, name, expression, auto):
52 if name == "reserved":
53 return False
54
55 if name not in self.fieldDict:
56 return False
57
58 field = self.fieldDict[name]
59
60 if field.UpdateValue(expression, auto):
61 field.UpdateSize()
62 return True
63
64 return False
65
66 def SetField(self, name, expression):
67 return self.setField(name, expression, False)
68
69 def SetFieldAuto(self, name, expression):
70 return self.setField(name, expression, True)
71
72 def SetAttribute(self, name, expression):
73 if name not in self.attributeDict:
74 return False
75 attr = self.attributeDict[name]
76
77 return attr.UpdateValue(expression)
78
79 def SetMask(self, name, expression):
80 if name not in self.fieldDict:
81 return False
82 field = self.fieldDict[name]
83
84 return field.UpdateMask(expression)
85
86 def resolveOptional(self, condition):
87 if condition == None:
88 return True
89
90 tokens = condition.split("|")
91
92 if len(tokens) > 1:
93 result = False
94
95 for token in tokens:
96 result |= self.resolveOptional(token)
97
98 return result
99
100 tokens = condition.split("&")
101
102 if len(tokens) > 1:
103 result = True
104
105 for token in tokens:
106 result &= self.resolveOptional(token)
107
108 return result
109
110 key = None
111 value = None
112
113 if "!=" in tokens[0]:
114 index = tokens[0].find("!=")
115 key = tokens[0][:index].strip()
116 value = tokens[0][index + 1 :].strip()
117 elif "=" in tokens[0]:
118 index = tokens[0].find("=")
119 key = tokens[0][:index].strip()
120 value = tokens[0][index + 1 :].strip()
121 else:
122 return False
123
124 if key not in self.fieldDict:
125 return False
126
127 f = self.fieldDict[key]
128 return ExpressionConverter.Equal(f.Value, value)
129
130 def resolveSize(self, exp):
131 shift = 0
132 key = exp
133
134 if "<<" in exp:
135 offset = exp.find("<<")
136 key = exp[0:offset].strip()
137 shift = int(exp[offset + 2 :].strip())
138
Ting Xu61762c72023-07-03 08:08:33 +0000139 if key in self.fieldDict:
Ting Xuce4b6452022-04-24 06:14:25 +0000140 field = self.fieldDict[key]
141 _, u16 = ExpressionConverter.ToNum(field.Value)
142 if u16:
143 return u16 << shift
144 else:
145 return 0
146
Ting Xu61762c72023-07-03 08:08:33 +0000147 if key in self.attributeDict:
Ting Xuce4b6452022-04-24 06:14:25 +0000148 attr = self.attributeDict[key]
149 _, u16 = ExpressionConverter.ToNum(attr.Value)
150 if u16:
151 return u16 << shift
152 else:
153 return 0
154
155 return 0
156
157 def Adjust(self):
158 autoIncreases = []
159 increaseHeaders = []
160
161 self.resolveAllSize()
162
163 for phf in self.fields:
164 if phf.Field.IsAutoIncrease:
165 autoIncreases.append(phf)
166 if phf.Field.IsIncreaseLength and self.resolveOptional(phf.Field.Optional):
167 increaseHeaders.append(phf)
168
169 for f1 in autoIncreases:
170 for f2 in increaseHeaders:
171 f1.UpdateValue(
172 ExpressionConverter.IncreaseValue(f1.Value, f2.Size >> 3), True
173 )
174
175 def resolveAllSize(self):
176 for phf in self.fields:
177 if phf.Field.Optional != None and not self.resolveOptional(
178 phf.Field.Optional
179 ):
180 size = 0
181 else:
182 if phf.Field.VariableSize != None:
183 size = self.resolveSize(phf.Field.VariableSize)
184 else:
185 size = phf.Field.Size
186 phf.Size = size
187
188 def GetSize(self):
189 size = 0
190
191 for field in self.fields:
192 size += field.Size
193
194 return size >> 3
195
196 def AppendAuto(self, size):
197 for phf in self.fields:
198 if not phf.Field.IsAutoIncrease:
199 continue
200
201 phf.UpdateValue(ExpressionConverter.IncreaseValue(phf.Value, size), True)
202
203 def getField(self, name):
Ting Xu61762c72023-07-03 08:08:33 +0000204 if name not in self.fieldDict:
Ting Xuce4b6452022-04-24 06:14:25 +0000205 return None
206 field = self.fieldDict[name]
207
208 return field.Value
209
210 def getAttribute(self, name):
Ting Xu61762c72023-07-03 08:08:33 +0000211 if name not in self.attributeDict:
Ting Xuce4b6452022-04-24 06:14:25 +0000212 return None
213
214 return self.attributeDict[name].Value
215
216 def GetValue(self, name):
217 result = self.getField(name)
218
219 if result == None:
220 return self.getAttribute(name)
221
222 return result
223
224 def appendNum(self, big, exp, size):
225 num = 0
226 if exp != None:
227 _, num = ExpressionConverter.ToNum(exp)
228 if num == None:
229 print("Invalid byte expression")
230 return None
231
232 # cut msb
233 num = num & ((1 << size) - 1)
234 big = big << size
235 big = big | num
236 return big
237
238 def appendUInt64(self, big, exp, size):
239 u64 = 0
240 if exp != None:
241 _, u64 = ExpressionConverter.ToNum(exp)
242 if not u64:
243 print("Invalid UInt32 expression")
244 return False
245
246 # cut msb
247 if size < 64:
248 u64 = u64 & ((1 << size) - 1)
249 big = big << size
250 big = big | u64
251 return big
252
253 def appendIPv4(self, big, exp):
254 ipv4 = bytes(4)
255 if exp != None:
256 _, ipv4 = ExpressionConverter.ToIPv4Address(exp)
257 if not ipv4:
258 print("Inavalid IPv4 Address")
259 return False
260
261 for i in range(len(ipv4)):
262 big = big << 8
263 big = big | ipv4[i]
264
265 return big
266
267 def appendIPv6(self, big, exp):
268 ipv6 = bytes(16)
269 if exp != None:
270 _, ipv6 = ExpressionConverter.ToIPv6Address(exp)
271 if not ipv6:
272 print("Inavalid IPv6 Address")
273 return False
274
275 for i in range(16):
276 big = big << 8
277 big = big | ipv6[i]
278
279 return big
280
281 def appendMAC(self, big, exp):
282 mac = bytes(6)
283 if exp != None:
284 _, mac = ExpressionConverter.ToMacAddress(exp)
285 if not mac:
286 print("Inavalid MAC Address")
287 return False
288
289 for i in range(6):
290 big = big << 8
291 big = big | mac[i]
292
293 return big
294
295 def appendByteArray(self, big, exp, size):
296 array = bytes(size >> 3)
297 if exp != None:
298 _, array = ExpressionConverter.ToByteArray(exp)
299 if not array:
300 print("Invalid byte array")
301 return False
302
303 for i in range(size >> 3):
304 big = big << 8
305 if i < len(array):
306 big = big | array[i]
307
308 return big
309
310 def append(self, big, phf):
311 bigVal = big["bigVal"]
312 bigMsk = big["bigMsk"]
313
314 if phf.Field.IsReserved:
315 bigVal <<= phf.Size
316 bigMsk <<= phf.Size
317 big.update(bigVal=bigVal, bigMsk=bigMsk)
318 return big, phf.Size
319
320 size = phf.Size
321
322 if (
323 phf.Field.Format == InputFormat.u8
324 or phf.Field.Format == InputFormat.u16
325 or phf.Field.Format == InputFormat.u32
326 ):
327 bigVal = self.appendNum(bigVal, phf.Value, size)
328 bigMsk = self.appendNum(bigMsk, phf.Mask, size)
329
330 elif phf.Field.Format == InputFormat.u64:
331 bigVal = self.appendUInt64(bigVal, phf.Value, size)
332 bigMsk = self.appendUInt64(bigMsk, phf.Mask, size)
333
334 elif phf.Field.Format == InputFormat.ipv4:
335 bigVal = self.appendIPv4(bigVal, phf.Value)
336 bigMsk = self.appendIPv4(bigMsk, phf.Mask)
337
338 elif phf.Field.Format == InputFormat.ipv6:
339 bigVal = self.appendIPv6(bigVal, phf.Value)
340 bigMsk = self.appendIPv6(bigMsk, phf.Mask)
341
342 elif phf.Field.Format == InputFormat.mac:
343 bigVal = self.appendMAC(bigVal, phf.Value)
344 bigMsk = self.appendMAC(bigMsk, phf.Mask)
345
346 elif phf.Field.Format == InputFormat.bytearray:
347 bigVal = self.appendByteArray(bigVal, phf.Value, size)
348 bigMsk = self.appendByteArray(bigMsk, phf.Mask, size)
349
350 else:
351 print("Invalid input format")
352
353 big.update(bigVal=bigVal, bigMsk=bigMsk)
354 return big, size
355
356 def Resolve(self):
357 big = {"bigVal": 0, "bigMsk": 0}
358 offset = 0
359
360 for phf in self.fields:
361 if phf.Size == 0:
362 continue
363
364 big, bits = self.append(big, phf)
365
366 offset += bits
367
368 byteList1 = []
369 byteList2 = []
370
371 bigVal = big["bigVal"]
372 bigMsk = big["bigMsk"]
373
374 while offset > 0:
375 byteList1.append(bigVal & 0xFF)
376 byteList2.append(bigMsk & 0xFF)
377 bigVal = bigVal >> 8
378 bigMsk = bigMsk >> 8
379 offset -= 8
380
381 byteList1.reverse()
382 byteList2.reverse()
383 buffer = copy.deepcopy(byteList1)
384 mask = copy.deepcopy(byteList2)
385
386 self.Buffer = buffer
387 self.Mask = mask