A field that builds and dissects DHCP options. The internal value is a list of tuples with the format [("option_name", ), ...] Where expected names and values can be found using `DHCPOptions`
| 414 | |
| 415 | |
| 416 | class DHCPOptionsField(StrField): |
| 417 | """ |
| 418 | A field that builds and dissects DHCP options. |
| 419 | The internal value is a list of tuples with the format |
| 420 | [("option_name", <option_value>), ...] |
| 421 | Where expected names and values can be found using `DHCPOptions` |
| 422 | """ |
| 423 | islist = 1 |
| 424 | |
| 425 | def i2repr(self, pkt, x): |
| 426 | s = [] |
| 427 | for v in x: |
| 428 | if isinstance(v, tuple) and len(v) >= 2: |
| 429 | if v[0] in DHCPRevOptions and isinstance(DHCPRevOptions[v[0]][1], Field): # noqa: E501 |
| 430 | f = DHCPRevOptions[v[0]][1] |
| 431 | vv = ",".join(f.i2repr(pkt, val) for val in v[1:]) |
| 432 | else: |
| 433 | vv = ",".join(repr(val) for val in v[1:]) |
| 434 | s.append("%s=%s" % (v[0], vv)) |
| 435 | else: |
| 436 | s.append(sane(v)) |
| 437 | return "[%s]" % (" ".join(s)) |
| 438 | |
| 439 | def getfield(self, pkt, s): |
| 440 | return b"", self.m2i(pkt, s) |
| 441 | |
| 442 | def m2i(self, pkt, x): |
| 443 | opt = [] |
| 444 | while x: |
| 445 | o = orb(x[0]) |
| 446 | if o == 255: |
| 447 | opt.append("end") |
| 448 | x = x[1:] |
| 449 | continue |
| 450 | if o == 0: |
| 451 | opt.append("pad") |
| 452 | x = x[1:] |
| 453 | continue |
| 454 | if len(x) < 2 or len(x) < orb(x[1]) + 2: |
| 455 | opt.append(x) |
| 456 | break |
| 457 | elif o in DHCPOptions: |
| 458 | f = DHCPOptions[o] |
| 459 | |
| 460 | if isinstance(f, str): |
| 461 | olen = orb(x[1]) |
| 462 | opt.append((f, x[2:olen + 2])) |
| 463 | x = x[olen + 2:] |
| 464 | else: |
| 465 | olen = orb(x[1]) |
| 466 | lval = [f.name] |
| 467 | |
| 468 | if olen == 0: |
| 469 | try: |
| 470 | _, val = f.getfield(pkt, b'') |
| 471 | except Exception: |
| 472 | opt.append(x) |
| 473 | break |
no outgoing calls
no test coverage detected
searching dependent graphs…