API Reference
This section provides references for the primary classes in the pydhcp package.
DHCPMessage
pydhcp.packet.DHCPMessage
dataclass
Bases: _MessageDisplay
A DHCPv4 message (RFC 2131 s2): the fixed BOOTP header, then options.
The fields, decode/encode, to_mapping/from_mapping, client_id and
the display helpers are inherited from the layers in pydhcp.packet; the
dataclass __init__, __repr__ and __eq__ are the base layer's, and
report this class.
Source code in src/pydhcp/packet/_message.py
12 13 14 15 16 17 18 19 | |
MAGIC_COOKIE = (1669485411).to_bytes(4, 'big')
class-attribute
The first four octets of the 'options' field of the DHCP message decimal values: 99, 130, 83 and 99
MIN_LEGAL_SIZE = _const.DHCP_MIN_LEGAL_PACKET_SIZE - _const.UDP_MIN_PACKET_SIZE
class-attribute
instance-attribute
Smallest DHCP message every implementation must be able to handle: 548.
RFC 2131 s2: 576 octets is the minimum IP datagram an IP host must be prepared to accept, and a DHCP client "MUST be prepared to receive DHCP messages with an 'options' field of at least length 312 octets". Those are the same statement -- the arithmetic closes exactly:
576 - 20 (IPv4) - 8 (UDP) = 548 this message
548 - 236 (fixed header, op..file) = 312 the options field
So this is a floor on capability, not on any particular packet, which is
why nothing enforces it: decode() deliberately accepts shorter messages
(241 octets and up), and plenty of real senders emit them. The floor pydhcp
applies to what it sends is a different and smaller number,
BOOTP_MIN_PACKET_SIZE (300).
broadcast
property
Whether the broadcast bit of flags is set (RFC 2131 s2).
The reserved bits are carried in flags as they were received.
chaddr = chaddr
instance-attribute
Client hardware address.
ciaddr = _typed('ciaddr', _ipaddress.IPv4Address, ciaddr)
instance-attribute
Client IP address; only filled in if client is in BOUND, RENEW or REBINDING state and can respond to ARP requests.
file = file
instance-attribute
Boot file name, null terminated string; "generic" name or null in DHCPDISCOVER, fully qualified directory-path name in DHCPOFFER.
flags = _typed('flags', _enum.DHCPFlags, flags)
instance-attribute
Only use for the BROADCAST flag in clients
giaddr = _typed('giaddr', _ipaddress.IPv4Address, giaddr)
instance-attribute
Relay agent IP address, used in booting via a relay agent.
hlen = hlen
instance-attribute
Hardware address length
hops = hops
instance-attribute
Client sets to zero, optionally used by relay agents when booting via a relay agent.
htype = _typed('htype', _enum.HardwareAddressType, htype)
instance-attribute
Hardware address type, see ARP section in "Assigned Numbers" RFC
message_type
property
The DHCP message type (option 53), or None when there is none to read.
None for a message with no option 53 and for one whose payload is not
a message type this package knows (the wrong length, or an unassigned
number); the option's octets are still there to forward.
op = _typed('op', _enum.DHCPOpcode, op)
instance-attribute
Message op code / message type
options = DHCPOptions() if options is None else options
instance-attribute
Optional parameters field.
secs = secs if isinstance(secs, _dt.timedelta) else _dt.timedelta(seconds=_typed('secs', int, secs))
instance-attribute
Filled in by client, seconds elapsed since client began address acquisition or renewal process.
siaddr = _typed('siaddr', _ipaddress.IPv4Address, siaddr)
instance-attribute
IP address of next server to use in bootstrap; returned in DHCPOFFER, DHCPACK by server.
sname = sname
instance-attribute
Optional server host name, null terminated string.
xid = xid
instance-attribute
Transaction ID, a random number chosen by the client, used by the client and server to associate messages and responses between a client and a server.
yiaddr = _typed('yiaddr', _ipaddress.IPv4Address, yiaddr)
instance-attribute
'your' (client) IP address.
__contains__(__key)
Whether the message carries option __key (a code or DHCPOptionCode).
Source code in src/pydhcp/packet/_display.py
122 123 124 | |
__init__(op, *, htype=_enum.HardwareAddressType.ETHERNET, hlen=None, hops=0, xid=0, secs=_dt.timedelta(0), flags=_enum.DHCPFlags.UNICAST, ciaddr=_const.UNSPECIFIED_ADDRESS, yiaddr=_const.UNSPECIFIED_ADDRESS, siaddr=_const.UNSPECIFIED_ADDRESS, giaddr=_const.UNSPECIFIED_ADDRESS, chaddr=b'', sname='', file='', options=None)
A message with every header field but op defaulted.
hlen is the length of chaddr when left out, and must equal it when
given: the header's hardware address length is the length of the address
in the same header, so a message that says otherwise is refused here and
by encode. (decode reads whatever hlen the sender wrote, and the
address is that many octets, so a received message always agrees.) A
fresh option bag is made when options is not given. op, htype and
flags may be given as their numbers, the addresses as anything
IPv4Address takes and secs as seconds: each is stored as its type, so
a method reading op.name or secs.total_seconds() later cannot fail.
Source code in src/pydhcp/packet/_fields.py
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | |
decode(data)
classmethod
Parse one wire message.
Liberal on receive, deliberately: there is no minimum size (a 241-octet
message -- fixed header, magic cookie, END -- decodes), an htype with no
IANA name is kept as an unnamed member rather than rewritten, hlen = 0 is
accepted (RFC 4390 requires it for IPoIB), and sname/file text that is
not valid UTF-8 is preserved octet for octet. A relay must forward what it
received. RFC 2132 s9.3 overload is honoured: options packed into file
and sname are read back and the fields take their literal values from
options 67/66. A missing END marker is accepted, in the options field and
in an overloaded field alike (RFC 2131 s4.1 requires one; a message
without it keeps what arrived). Constructs cls, so
a subclass decodes to itself.
Raises:
| Type | Description |
|---|---|
DHCPDecodeError
|
shorter than the fixed header or magic cookie, a
wrong magic cookie, |
Source code in src/pydhcp/packet/_decode.py
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | |
encode(max_packetsize=_const.DHCP_MIN_LEGAL_PACKET_SIZE)
Serialize the message, fitting it into max_packetsize octets.
max_packetsize is the whole IP datagram, not the DHCP message, so
the options field gets what is left after a fixed overhead:
max_options_field_size = max_packetsize - 268
268 = 20 (IPv4) + 8 (UDP) + 236 (fixed header) + 4 (magic cookie)
The default, DHCP_MIN_LEGAL_PACKET_SIZE (576), is RFC 2131 s2's
minimum datagram and leaves 308 octets for options. 269 is the floor
-- 268 of overhead plus the one octet the END marker needs -- and
anything below it raises ValueError, including an explicit 0: a
caller passing 0 has a wrong belief worth reporting, and encoding to
another size instead would hide it. 576 is not a lower bound: RFC 2132
s9.10's 576 minimum constrains what a client may advertise in option 57,
and encode(280) is a legitimate call.
The options are written in one pass when they fit the options field. When
they do not, sname and file carry some (RFC 2131 s4.1, RFC 3396; see
_layout): option 53 and option 52 stay first in the options field, an
occupied name moves into option 66 or 67, and a name too long for its
field travels that way too. A message needs at least 275 for any
overload, since the options field then holds options 53 and 52.
The result is padded up to BOOTP_MIN_PACKET_SIZE (300) with PAD octets
after END, never past max_packetsize less the 28 octets of IPv4 and UDP
header.
Raises:
| Type | Description |
|---|---|
ValueError
|
|
OverflowError
|
the options, with the names that move into options 66 and 67, do not fit the three fields. The message names the option that did not fit and how many octets short the room is. |
DHCPValueError
|
a name cannot travel as an option because option 66 or 67 already holds other octets. |
Source code in src/pydhcp/packet/_encode.py
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | |
from_hex(text)
classmethod
Decode a message written as hexadecimal text.
Spaces, tabs, line ends and colons between the digits are ignored, so
01:01:06:00 and a hexdump's lines read the same. ValueError for
anything else that is not a hexadecimal digit or for an odd number of
digits; DHCPDecodeError when the octets are not a message.
Source code in src/pydhcp/packet/_mapping.py
154 155 156 157 158 159 160 161 162 163 | |
from_mapping(data, *, codemap=None)
classmethod
Build a message from a mapping in the shape to_mapping produces.
Only op is required: a header field left out (or options) takes the
constructor's default -- 0.0.0.0 for an address, 0 for a number, an
empty chaddr, hlen its length. options is read by
DHCPOptions.from_mapping with codemap, so to_mapping ->
from_mapping round-trips exactly when codemap is the one the options
were named with (the default is DHCPOptionCode). sname and file
take text, null (empty), bytes or the hex form. A MAC written unquoted
in YAML (read as a sexagesimal integer) is refused with a message naming
the cause. Constructs cls.
Raises:
| Type | Description |
|---|---|
TypeError
|
|
ValueError
|
|
Source code in src/pydhcp/packet/_mapping.py
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | |
from_text(text, format, *, codemap=None)
classmethod
Build a message from a document to_text (or the capture command) wrote.
pydhcp.packet.structured.loads then from_mapping, with the same
codemap and the same errors.
Source code in src/pydhcp/packet/_mapping.py
139 140 141 142 143 144 145 146 147 148 149 150 151 152 | |
get_client_id(func=None)
Stable identity for this client, used to key leases.
Option 61 when present, else the hardware type and address. Raises
NoClientIdentityError when the message carries neither: hlen may legally
be 0 (RFC 4390 requires exactly that for IPoIB, which supplies option 61
instead): falling back to the hardware-type octet alone would give one
identifier, "01", to every such client, so two of them would take over
each other's lease and a RELEASE from either would free both.
Source code in src/pydhcp/packet/_display.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | |
log(src, dst, level)
Log the packet at level.
Never raises and never does work the level does not call for: callers on the receive and send paths invoke this before handling or sending, so a failure here would silently cost a packet its handler or its reply.
Source code in src/pydhcp/packet/_display.py
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | |
log_str(src, dst)
summary() under a one-line header naming the op, XID, source and destination.
Source code in src/pydhcp/packet/_display.py
115 116 117 118 119 120 | |
summary(codemap=None)
A human-readable multi-line summary: header fields, then each option.
What log/log_str and the CLI's --format summary print. Text fields go
through pydhcp._nvt.display, so it is always safe for a terminal. codemap
names the options; it defaults to the message's own.
Source code in src/pydhcp/packet/_display.py
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | |
to_mapping()
The message as a plain dict: header fields, then options.
The basis of the JSON/YAML/TOML/INI helpers, and byte-exact: options
is DHCPOptions.to_mapping's form, and sname and file are text, or
{HEX_VALUE_KEY: "..."} when they are not UTF-8. Integers are plain int.
Source code in src/pydhcp/packet/_mapping.py
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | |
to_text(format)
The message as a document in format: "json", "yaml", "toml" or "ini".
to_mapping written out by pydhcp.packet.structured.dumps; a format
that is not one of the four raises ValueError.
Source code in src/pydhcp/packet/_mapping.py
131 132 133 134 135 136 137 | |
DHCPOptions
pydhcp.options.DHCPOptions
Bases: MutableMapping[int, bytearray]
The option bag: a mutable mapping of option code to raw payload.
Two members deliberately do not mean what MutableMapping says they mean,
and both type: ignore[override]s below mark exactly that:
get()decodes;[]does not.options[53]isbytearray(b'\x05'),options.get(53)isDHCPMessageType.DHCPACK. Everything the ABC supplies --values(),pop(),setdefault(),popitem(), anddict(options)-- routes through__getitem__, so all of it yields rawbytearrays like[], not decoded values likeget(). Reach forget(code, decode=False)when you want the bytes and you want to say so.items()returns alist, not a view. The decoded form has to buildDHCPOptionpairs, so there is nothing to keep a live view of; onlyitems(decoded=False)is the ABC'sItemsView.
This asymmetry is the API, not drift: get(..., decode=...) is the
documented surface every caller uses, and making it return raw bytes to
satisfy the ABC would trade a real API for a formal one. It is pinned by
tests/test_options.py::test_get_decodes_and_getitem_does_not, which fails
if anyone "fixes" it the other way.
Equality is on the raw payloads. Two bags are equal when they hold the
same codes with the same octets, in any order (a mapping has none to keep),
whatever their code maps; nothing is decoded, so comparing never raises on
a malformed payload and octets that read alike are still different. A bag
is unequal to anything that is not a DHCPOptions, a dict of its own
items included.
Source code in src/pydhcp/options/__init__.py
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | |
__setitem__(__key, __value)
Store an option, building the payload before it is visible.
- Atomic. The payload is built in a scratch buffer and stored only on success, so a codec that raises part-way leaves the previous value, or no key. A zero-length option is legal on the wire (RFC 4039's RAPID_COMMIT), so a half-built one would encode and send cleanly as an option meaning something else.
- Non-aliasing. A
bytearrayargument is copied, never kept: the caller's later writes to their buffer do not reach the stored option.
Assigning an existing key keeps its position; the options order is
wire-visible. The key is checked first (_check_code).
Source code in src/pydhcp/options/__init__.py
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | |
append(option)
Add option's octets after those already stored under its code.
All or nothing: the payload is built first, so an option that is refused leaves the bag as it was, a code that was absent still absent.
Source code in src/pydhcp/options/__init__.py
374 375 376 377 378 379 380 381 382 383 384 385 | |
copy(*options, **overrides)
Return an independent copy sharing no mutable state with self.
The codemap is preserved and every payload is copied into a fresh
bytearray, so mutating either container (or a payload handed out by
get(..., decode=False)) cannot write through to the other. Arguments
are then merged into the copy as update() merges them; self is
left as it was, whether or not the merge is refused.
Source code in src/pydhcp/options/__init__.py
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | |
decode(data, *, codemap=None)
classmethod
Parse a TLV options buffer into a new bag.
Liberal on receive: PAD octets are skipped, parsing stops at END, and a truncated option keeps what arrived (logged at DEBUG and counted by a listener). Octets after END are ignored. A repeated code is joined (RFC 3396).
Source code in src/pydhcp/options/__init__.py
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | |
from_mapping(data, *, codemap=None)
classmethod
A bag from what to_mapping wrote; None is an empty one.
A key is a name in codemap or a number; a value is what its codec takes,
octets only as {"hex": ...} or as hex text for an opaque option.
Source code in src/pydhcp/options/__init__.py
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | |
partial_encode(maxsize, word_size=1)
Encode up to maxsize octets, returning the bytes and the leftovers.
An option that does not fit whole is split into instances of its code
(RFC 3396), and what is not written comes back as a bag of its own.
word_size pads the END marker out to a multiple of that many octets,
so the options field finishes on a word boundary: at 4, END is
ff 00 00 00 rather than a bare ff. It also reserves that much room
rather than one octet when deciding what still fits. DHCP itself needs
no alignment; the padding is for a caller filling a word-aligned buffer.
Source code in src/pydhcp/options/__init__.py
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | |
retain(codes)
Keep only the options whose code is in codes; the order of the rest is kept.
Source code in src/pydhcp/options/__init__.py
268 269 270 271 272 | |
setdefault(key, default=None)
The raw payload under key; default is stored first when absent.
Source code in src/pydhcp/options/__init__.py
418 419 420 421 422 | |
to_mapping()
The options as plain data: the code's name (its number when it has
none) to the value's to_json() form, in order.
Byte-exact: an option whose readable form would load back as other
octets is {"hex": "..."}, which every option takes.
Source code in src/pydhcp/options/__init__.py
239 240 241 242 243 244 245 246 247 248 | |
update(*options, **overrides)
Merge each of options in order, then each keyword; the last write wins.
A positional is a mapping of code to value (another bag's raw payloads
are copied, not decoded) or an iterable of (code, value) pairs; a
keyword names an option in this bag's codemap, in any letter case
(update(defaults, ROUTER="10.0.0.1")). Every value is stored as
options[code] = value stores it. All or nothing: a refused code,
name or value leaves the bag as it was.
Source code in src/pydhcp/options/__init__.py
227 228 229 230 231 232 233 234 235 236 237 | |
DHCPOptionCode
The standard IANA option-code registry: an IntEnum whose members carry, in their own
docstrings, the RFC text that defines each option. Codes without a member resolve to an
opaque pseudo-member (get_type() returns Bytes, label() reports UNKNOWN) rather
than raising, so an unknown code never costs a client its lease.
pydhcp.options.DHCPOptionCode
Bases: OptionCodeEnum
The IANA DHCPv4 option codes, each member documented with its RFC text.
Source code in src/pydhcp/options/_codes.py
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 | |
ALL_SUBNETS_ARE_LOCAL = 27
class-attribute
instance-attribute
This option specifies whether or not the client may assume that all subnets of the IP network to which the client is connected use the same MTU as the subnet of that network to which the client is directly connected. A value of 1 indicates that all subnets share the same MTU. A value of 0 means that the client should assume that some subnets of the directly connected network may have smaller MTUs.
The code for this option is 27, and its length is 1.
ALL_VPNS = 254
class-attribute
instance-attribute
All VPNs option
ARP_TIMEOUT = 35
class-attribute
instance-attribute
This option specifies the timeout in seconds for ARP cache entries. The time is specified as a 32-bit unsigned integer.
The code for this option is 35, and its length is 4.
ASSOCIATED_IP = 92
class-attribute
instance-attribute
AUTHENTICATION = 90
class-attribute
instance-attribute
AUTO_CONFIG = 116
class-attribute
instance-attribute
BASE_TIME = 152
class-attribute
instance-attribute
BCMCS_DOMAIN_NAME_LIST = 88
class-attribute
instance-attribute
BCMCS_IPV4_ADDRESS = 89
class-attribute
instance-attribute
BOOTFILE_NAME = 67
class-attribute
instance-attribute
This option is used to identify a bootfile when the 'file' field in the DHCP header has been used for DHCP options.
The code for this option is 67, and its minimum length is 1.
BOOT_FILE_SIZE = 13
class-attribute
instance-attribute
This option specifies the length in 512-octet blocks of the default boot image for the client. The file length is specified as an unsigned 16-bit integer.
The code for this option is 13, and its length is 2.
BROADCAST_ADDRESS = 28
class-attribute
instance-attribute
This option specifies the broadcast address in use on the client's subnet. Legal values for broadcast addresses are specified in section 3.2.1.3 of [4].
The code for this option is 28, and its length is 4.
CAPWAP_AC_V4 = 138
class-attribute
instance-attribute
CCC = 122
class-attribute
instance-attribute
CLASSLESS_STATIC_ROUTE = 121
class-attribute
instance-attribute
CLIENT_FQDN = 81
class-attribute
instance-attribute
CLIENT_IDENTIFIER = 61
class-attribute
instance-attribute
This option is used by DHCP clients to specify their unique identifier. DHCP servers use this value to index their database of address bindings. This value is expected to be unique for all clients in an administrative domain.
Identifiers SHOULD be treated as opaque objects by DHCP servers.
The client identifier MAY consist of type-value pairs similar to the 'htype'/'chaddr' fields defined in [3]. For instance, it MAY consist of a hardware type and hardware address. In this case the type field SHOULD be one of the ARP hardware types defined in STD2 [22]. A hardware type of 0 (zero) should be used when the value field contains an identifier other than a hardware address (e.g. a fully qualified domain name).
For correct identification of clients, each client's client- identifier MUST be unique among the client-identifiers used on the subnet to which the client is attached. Vendors and system administrators are responsible for choosing client-identifiers that meet this requirement for uniqueness.
The code for this option is 61, and its minimum length is 2.
CLIENT_LAST_TRANSACTION_TIME = 91
class-attribute
instance-attribute
CLIENT_NDI = 94
class-attribute
instance-attribute
CLIENT_SYSTEM_ARCHITECTURE = 93
class-attribute
instance-attribute
CONFIGURATION_FILE = 209
class-attribute
instance-attribute
COOKIE_SERVER = 8
class-attribute
instance-attribute
The cookie server option specifies a list of RFC 865 [9] cookie servers available to the client. Servers SHOULD be listed in order of preference.
The code for the log server option is 8. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
DATA_SOURCE = 157
class-attribute
instance-attribute
DHCP4_OVER_DHCP6_SOURCE_ADDRESS = 109
class-attribute
instance-attribute
DHCP_CAPTIVE_PORTAL = 114
class-attribute
instance-attribute
DHCP_MESSAGE = 56
class-attribute
instance-attribute
This option is used by a DHCP server to provide an error message to a DHCP client in a DHCPNAK message in the event of a failure. A client may use this option in a DHCPDECLINE message to indicate the why the client declined the offered parameters. The message consists of n octets of NVT ASCII text, which the client may display on an available output device.
The code for this option is 56 and its minimum length is 1.
DHCP_MESSAGE_TYPE = 53
class-attribute
instance-attribute
This option is used to convey the type of the DHCP message. The code for this option is 53, and its length is 1. Legal values for this option are:
Value Message Type
----- ------------
1 DHCPDISCOVER
2 DHCPOFFER
3 DHCPREQUEST
4 DHCPDECLINE
5 DHCPACK
6 DHCPNAK
7 DHCPRELEASE
8 DHCPINFORM
DHCP_STATE = 156
class-attribute
instance-attribute
DIRECTORY_AGENT = 78
class-attribute
instance-attribute
DNS = 6
class-attribute
instance-attribute
The domain name server option specifies a list of Domain Name System (STD 13, RFC 1035 [8]) name servers available to the client. Servers SHOULD be listed in order of preference.
The code for the domain name server option is 6. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
DOMAIN_NAME = 15
class-attribute
instance-attribute
This option specifies the domain name that client should use when resolving hostnames via the Domain Name System.
The code for this option is 15. Its minimum length is 1.
DOMAIN_SEARCH = 119
class-attribute
instance-attribute
END = 255
class-attribute
instance-attribute
The end option marks the end of valid information in the vendor field. Subsequent octets should be filled with pad options.
The code for the end option is 255, and its length is 1 octet.
ETHERBOOT = 175
class-attribute
instance-attribute
ETHERNET_ENCAPSULATION = 36
class-attribute
instance-attribute
This option specifies whether or not the client should use Ethernet Version 2 (RFC 894 [15]) or IEEE 802.3 (RFC 1042 [16]) encapsulation if the interface is an Ethernet. A value of 0 indicates that the client should use RFC 894 encapsulation. A value of 1 means that the client should use RFC 1042 encapsulation.
The code for this option is 36, and its length is 1.
EXTENSION_FILE = 18
class-attribute
instance-attribute
A string to specify a file, retrievable via TFTP, which contains information which can be interpreted in the same way as the 64-octet vendor-extension field within the BOOTP response, with the following exceptions: - the length of the file is unconstrained; - all references to Tag 18 (i.e., instances of the BOOTP Extensions Path field) within the file are ignored.
The code for this option is 18. Its minimum length is 1.
FINGER_SERVER = 73
class-attribute
instance-attribute
The Finger server option specifies a list of Finger available to the client. Servers SHOULD be listed in order of preference.
The code for the Finger server option is 73. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
FORCERENEW_NONCE_CAPABLE = 145
class-attribute
instance-attribute
GEOCONF = 123
class-attribute
instance-attribute
GEOCONF_CIVIC = 99
class-attribute
instance-attribute
GEOLOC = 144
class-attribute
instance-attribute
GRD = 212
class-attribute
instance-attribute
An alias of SIXRD: DHCPOptionCode(212).name is SIXRD.
HOME_AGENT_ADDRESSES = 68
class-attribute
instance-attribute
This option specifies a list of IP addresses indicating mobile IP home agents available to the client. Agents SHOULD be listed in order of preference.
The code for this option is 68. Its minimum length is 0 (indicating no home agents are available) and the length MUST be a multiple of 4. It is expected that the usual length will be four octets, containing a single home agent's address.
HOSTNAME = 12
class-attribute
instance-attribute
This option specifies the name of the client. The name may or may not be qualified with the local domain name (see section 3.17 for the preferred way to retrieve the domain name). See RFC 1035 for character set restrictions.
The code for this option is 12, and its minimum length is 1.
IEN116_NAMESERVER = 5
class-attribute
instance-attribute
The name server option specifies a list of IEN 116 [7] name servers available to the client. Servers SHOULD be listed in order of preference.
The code for the name server option is 5. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
IMPRESS_SERVER = 10
class-attribute
instance-attribute
The Impress server option specifies a list of Imagen Impress servers available to the client. Servers SHOULD be listed in order of preference.
The code for the Impress server option is 10. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
INTERFACE_MTU = 26
class-attribute
instance-attribute
This option specifies the MTU to use on this interface. The MTU is specified as a 16-bit unsigned integer. The minimum legal value for the MTU is 68.
The code for this option is 26, and its length is 2.
IPV4_ADDRESS_ANDSF = 142
class-attribute
instance-attribute
IPV4_ADDRESS_MOS = 139
class-attribute
instance-attribute
IPV4_FQDN_MOS = 140
class-attribute
instance-attribute
IPV6_ONLY = 108
class-attribute
instance-attribute
IP_ADDRESS_LEASE_TIME = 51
class-attribute
instance-attribute
This option is used in a client request (DHCPDISCOVER or DHCPREQUEST) to allow the client to request a lease time for the IP address. In a server reply (DHCPOFFER), a DHCP server uses this option to specify the lease time it is willing to offer.
The time is in units of seconds, and is specified as a 32-bit unsigned integer.
The code for this option is 51, and its length is 4.
IP_FORWARDING = 19
class-attribute
instance-attribute
This option specifies whether the client should configure its IP layer for packet forwarding. A value of 0 means disable IP forwarding, and a value of 1 means enable IP forwarding.
The code for this option is 19, and its length is 1.
IP_TELEPHONE = 176
class-attribute
instance-attribute
IP_TTL = 23
class-attribute
instance-attribute
This option specifies the default time-to-live that the client should use on outgoing datagrams. The TTL is specified as an octet with a value between 1 and 255.
The code for this option is 23, and its length is 1.
IRC_SERVER = 74
class-attribute
instance-attribute
The IRC server option specifies a list of IRC available to the client. Servers SHOULD be listed in order of preference.
The code for the IRC server option is 74. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
ISNS = 83
class-attribute
instance-attribute
LDAP = 95
class-attribute
instance-attribute
IANA currently lists option 95 as unassigned/reclaimed per RFC 3679.
Interoperability with a standards-conformant peer should not be assumed.
LEGACY_CCC = 177
class-attribute
instance-attribute
This option was historically used for PacketCable/CableHome CCC (Client Configuration for CableHome), later superseded by option 122 (CCC). IANA's registry separately lists 177 under a tentative 2005 Etherboot assignment as well; do not conflate the two.
LOG_SERVER = 7
class-attribute
instance-attribute
The log server option specifies a list of MIT-LCS UDP log servers available to the client. Servers SHOULD be listed in order of preference.
The code for the log server option is 7. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
LPR_SERVER = 9
class-attribute
instance-attribute
The LPR server option specifies a list of RFC 1179 [10] line printer servers available to the client. Servers SHOULD be listed in order of preference.
The code for the LPR server option is 9. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
MASK_DISCOVERY = 29
class-attribute
instance-attribute
This option specifies whether or not the client should perform subnet mask discovery using ICMP. A value of 0 indicates that the client should not perform mask discovery. A value of 1 means that the client should perform mask discovery.
The code for this option is 29, and its length is 1.
MASK_SUPPLIER = 30
class-attribute
instance-attribute
This option specifies whether or not the client should respond to subnet mask requests using ICMP. A value of 0 indicates that the client should not respond. A value of 1 means that the client should respond.
The code for this option is 30, and its length is 1.
MAXIMUM_DHCP_MESSAGE_SIZE = 57
class-attribute
instance-attribute
This option specifies the maximum length DHCP message that it is willing to accept. The length is specified as an unsigned 16-bit integer. A client may use the maximum DHCP message size option in DHCPDISCOVER or DHCPREQUEST messages, but should not use the option in DHCPDECLINE messages.
The code for this option is 57, and its length is 2. The minimum legal value is 576 octets.
MAX_DATAGRAM_REASSEMBLY_SIZE = 22
class-attribute
instance-attribute
This option specifies the maximum size datagram that the client should be prepared to reassemble. The size is specified as a 16-bit unsigned integer. The minimum value legal value is 576.
The code for this option is 22, and its length is 2.
MERIT_DUMP_FILE = 14
class-attribute
instance-attribute
This option specifies the path-name of a file to which the client's core image should be dumped in the event the client crashes. The path is formatted as a character string consisting of characters from the NVT ASCII character set.
The code for this option is 14. Its minimum length is 1.
MSFT_CLASSLESS_STATIC_ROUTE = 249
class-attribute
instance-attribute
MTU_PLATEAU = 25
class-attribute
instance-attribute
This option specifies a table of MTU sizes to use when performing Path MTU Discovery as defined in RFC 1191. The table is formatted as a list of 16-bit unsigned integers, ordered from smallest to largest. The minimum MTU value cannot be smaller than 68.
The code for this option is 25. Its minimum length is 2, and the length MUST be a multiple of 2.
MTU_TIMEOUT = 24
class-attribute
instance-attribute
This option specifies the timeout (in seconds) to use when aging Path MTU values discovered by the mechanism defined in RFC 1191 [12]. The timeout is specified as a 32-bit unsigned integer.
The code for this option is 24, and its length is 4.
MUD_URL_V4 = 161
class-attribute
instance-attribute
NAME_SERVICE_SEARCH = 117
class-attribute
instance-attribute
NBDD_SERVERS = 45
class-attribute
instance-attribute
The NetBIOS datagram distribution server (NBDD) option specifies a list of RFC 1001/1002 NBDD servers listed in order of preference. The code for this option is 45. The minimum length of the option is 4 octets, and the length must always be a multiple of 4.
NBNS_SERVERS = 44
class-attribute
instance-attribute
The NetBIOS name server (NBNS) option specifies a list of RFC 1001/1002 [19] [20] NBNS name servers listed in order of preference.
The code for this option is 44. The minimum length of the option is 4 octets, and the length must always be a multiple of 4.
NDS_CONTEXT = 87
class-attribute
instance-attribute
NDS_SERVERS = 85
class-attribute
instance-attribute
NDS_TREE_NAME = 86
class-attribute
instance-attribute
NETBIOS_NODE_TYPE = 46
class-attribute
instance-attribute
The NetBIOS node type option allows NetBIOS over TCP/IP clients which are configurable to be configured as described in RFC 1001/1002. The value is specified as a single octet which identifies the client type as follows:
Value Node Type
----- ---------
0x1 B-node
0x2 P-node
0x4 M-node
0x8 H-node
In the above chart, the notation '0x' indicates a number in base-16 (hexadecimal).
The code for this option is 46. The length of this option is always 1.
NETBIOS_SCOPE = 47
class-attribute
instance-attribute
The NetBIOS scope option specifies the NetBIOS over TCP/IP scope parameter for the client as specified in RFC 1001/1002. See [19], [20], and [8] for character-set restrictions.
The code for this option is 47. The minimum length of this option is 1.
NETINFO_ADDRESS = 112
class-attribute
instance-attribute
NETINFO_TAG = 113
class-attribute
instance-attribute
NETWARE_DOMAIN = 62
class-attribute
instance-attribute
NETWARE_OPTION = 63
class-attribute
instance-attribute
NIS_DOMAIN = 40
class-attribute
instance-attribute
This option specifies the name of the client's NIS [17] domain. The domain is formatted as a character string consisting of characters from the NVT ASCII character set.
The code for this option is 40. Its minimum length is 1.
NIS_PLUS_DOMAIN = 64
class-attribute
instance-attribute
This option specifies the name of the client's NIS+ [17] domain. The domain is formatted as a character string consisting of characters from the NVT ASCII character set.
The code for this option is 64. Its minimum length is 1.
NIS_PLUS_SERVERS = 65
class-attribute
instance-attribute
This option specifies a list of IP addresses indicating NIS+ servers available to the client. Servers SHOULD be listed in order of preference.
The code for this option is 65. Its minimum length is 4, and the length MUST be a multiple of 4.
NIS_SERVERS = 41
class-attribute
instance-attribute
This option specifies a list of IP addresses indicating NIS servers available to the client. Servers SHOULD be listed in order of preference.
The code for this option is 41. Its minimum length is 4, and the length MUST be a multiple of 4.
NNTP_SERVER = 71
class-attribute
instance-attribute
The NNTP server option specifies a list of NNTP available to the client. Servers SHOULD be listed in order of preference.
The code for the NNTP server option is 71. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
NON_LOCAL_SOURCE_ROUTING = 20
class-attribute
instance-attribute
This option specifies whether the client should configure its IP layer to allow forwarding of datagrams with non-local source routes (see Section 3.3.5 of [4] for a discussion of this topic). A value of 0 means disallow forwarding of such datagrams, and a value of 1 means allow forwarding.
The code for this option is 20, and its length is 1.
NTP_SERVERS = 42
class-attribute
instance-attribute
This option specifies a list of IP addresses indicating NTP [18] servers available to the client. Servers SHOULD be listed in order of preference.
The code for this option is 42. Its minimum length is 4, and the length MUST be a multiple of 4.
OPTION_OVERLOAD = 52
class-attribute
instance-attribute
This option is used to indicate that the DHCP 'sname' or 'file' fields are being overloaded by using them to carry DHCP options. A DHCP server inserts this option if the returned parameters will exceed the usual space allotted for options.
If this option is present, the client interprets the specified additional fields after it concludes interpretation of the standard option fields.
The code for this option is 52, and its length is 1. Legal values for this option are:
Value Meaning
----- --------
1 the 'file' field is used to hold options
2 the 'sname' field is used to hold options
3 both fields are used to hold options
PAD = 0
class-attribute
instance-attribute
The pad option can be used to cause subsequent fields to align on word boundaries.
The code for the pad option is 0, and its length is 1 octet.
PANA_AGENT = 136
class-attribute
instance-attribute
PARAMETER_REQUEST_LIST = 55
class-attribute
instance-attribute
This option is used by a DHCP client to request values for specified configuration parameters. The list of requested parameters is specified as n octets, where each octet is a valid DHCP option code as defined in this document.
The client MAY list the options in order of preference. The DHCP server is not required to return the options in the requested order, but MUST try to insert the requested options in the order requested by the client.
The code for this option is 55. Its minimum length is 1.
PATH_PREFIX = 210
class-attribute
instance-attribute
PCODE = 100
class-attribute
instance-attribute
POLICY_FILTER = 21
class-attribute
instance-attribute
This option specifies policy filters for non-local source routing. The filters consist of a list of IP addresses and masks which specify destination/mask pairs with which to filter incoming source routes.
Any source routed datagram whose next-hop address does not match one of the filters should be discarded by the client.
The code for this option is 21. The minimum length of this option is 8, and the length MUST be a multiple of 8.
POP3_SERVER = 70
class-attribute
instance-attribute
The POP3 server option specifies a list of POP3 available to the client. Servers SHOULD be listed in order of preference.
The code for the POP3 server option is 70. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
PXE_LINUX_MAGIC = 208
class-attribute
instance-attribute
magic string = F1:00:74:7E
PXE_VENDOR_SPECIFIC_1 = 128
class-attribute
instance-attribute
VENDOR SPECIFIC 128-135
PXE_VENDOR_SPECIFIC_2 = 129
class-attribute
instance-attribute
PXE_VENDOR_SPECIFIC_3 = 130
class-attribute
instance-attribute
PXE_VENDOR_SPECIFIC_4 = 131
class-attribute
instance-attribute
PXE_VENDOR_SPECIFIC_5 = 132
class-attribute
instance-attribute
PXE_VENDOR_SPECIFIC_6 = 133
class-attribute
instance-attribute
PXE_VENDOR_SPECIFIC_7 = 134
class-attribute
instance-attribute
PXE_VENDOR_SPECIFIC_8 = 135
class-attribute
instance-attribute
QUERY_END_TIME = 155
class-attribute
instance-attribute
QUERY_START_TIME = 154
class-attribute
instance-attribute
RAPID_COMMIT = 80
class-attribute
instance-attribute
RDNSS_SELECTION = 146
class-attribute
instance-attribute
REBINDING_TIME = 59
class-attribute
instance-attribute
This option specifies the time interval from address assignment until the client transitions to the REBINDING state.
The value is in units of seconds, and is specified as a 32-bit unsigned integer.
The code for this option is 59, and its length is 4.
REBOOT_TIME = 211
class-attribute
instance-attribute
RELAY_AGENT_INFORMATION = 82
class-attribute
instance-attribute
RENEWAL_TIME = 58
class-attribute
instance-attribute
This option specifies the time interval from address assignment until the client transitions to the RENEWING state.
The value is in units of seconds, and is specified as a 32-bit unsigned integer.
The code for this option is 58, and its length is 4.
REQUESTED_IP = 50
class-attribute
instance-attribute
This option is used in a client request (DHCPDISCOVER) to allow the client to request that a particular IP address be assigned.
The code for this option is 50, and its length is 4.
RFC868_TIMESERVER = 4
class-attribute
instance-attribute
The time server option specifies a list of RFC 868 time servers available to the client. Servers SHOULD be listed in order of preference.
The code for the time server option is 4. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
RLP_SERVER = 11
class-attribute
instance-attribute
his option specifies a list of RFC 887 [11] Resource Location servers available to the client. Servers SHOULD be listed in order of preference.
The code for this option is 11. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
ROOT_PATH = 17
class-attribute
instance-attribute
This option specifies the path-name that contains the client's root disk. The path is formatted as a character string consisting of characters from the NVT ASCII character set.
The code for this option is 17. Its minimum length is 1.
ROUTER = 3
class-attribute
instance-attribute
The router option specifies a list of IP addresses for routers on the client's subnet. Routers SHOULD be listed in order of preference.
The code for the router option is 3. The minimum length for the router option is 4 octets, and the length MUST always be a multiple of 4.
ROUTER_DISCOVERY = 31
class-attribute
instance-attribute
This option specifies whether or not the client should solicit routers using the Router Discovery mechanism defined in RFC 1256 [13]. A value of 0 indicates that the client should not perform router discovery. A value of 1 means that the client should perform router discovery.
The code for this option is 31, and its length is 1.
ROUTER_SOLICITATION_ADDRESS = 32
class-attribute
instance-attribute
This option specifies the address to which the client should transmit router solicitation requests.
The code for this option is 32, and its length is 4.
SERVER_IDENTIFIER = 54
class-attribute
instance-attribute
This option is used in DHCPOFFER and DHCPREQUEST messages, and may optionally be included in the DHCPACK and DHCPNAK messages. DHCP servers include this option in the DHCPOFFER in order to allow the client to distinguish between lease offers. DHCP clients use the contents of the 'server identifier' field as the destination address for any DHCP messages unicast to the DHCP server. DHCP clients also indicate which of several lease offers is being accepted by including this option in a DHCPREQUEST message.
The identifier is the IP address of the selected server.
The code for this option is 54, and its length is 4.
SERVICE_SCOPE = 79
class-attribute
instance-attribute
SIP_SERVERS = 120
class-attribute
instance-attribute
SIP_UA_CONFIG_SERVICE_DOMAINS = 141
class-attribute
instance-attribute
SIXRD = 212
class-attribute
instance-attribute
IANA option 212, OPTION_6RD (RFC 5969).
SMTP_SERVER = 69
class-attribute
instance-attribute
The SMTP server option specifies a list of SMTP servers available to the client. Servers SHOULD be listed in order of preference.
The code for the SMTP server option is 69. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
START_TIME_OF_STATE = 153
class-attribute
instance-attribute
STATIC_ROUTE = 33
class-attribute
instance-attribute
This option specifies a list of static routes that the client should install in its routing cache. If multiple routes to the same destination are specified, they are listed in descending order of priority.
The routes consist of a list of IP address pairs. The first address is the destination address, and the second address is the router for the destination.
The default route (0.0.0.0) is an illegal destination for a static route. See section 3.5 for information about the router option.
The code for this option is 33. The minimum length of this option is 8, and the length MUST be a multiple of 8.
STATUS_CODE = 151
class-attribute
instance-attribute
STDA_SERVER = 76
class-attribute
instance-attribute
The StreetTalk Directory Assistance (STDA) server option specifies a list of STDA servers available to the client. Servers SHOULD be listed in order of preference.
The code for the StreetTalk Directory Assistance server option is 76. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
STREETTALK_SERVER = 75
class-attribute
instance-attribute
The StreetTalk server option specifies a list of StreetTalk servers available to the client. Servers SHOULD be listed in order of preference.
The code for the StreetTalk server option is 75. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
SUBNET_ALLOCATION = 220
class-attribute
instance-attribute
SUBNET_MASK = 1
class-attribute
instance-attribute
The subnet mask option specifies the client's subnet mask as per RFC 950. If both the subnet mask and the router option are specified in a DHCP reply, the subnet mask option MUST be first.
The code for the subnet mask option is 1, and its length is 4 octets.
SUBNET_SELECTION_OPTION = 118
class-attribute
instance-attribute
SWAP_SERVER = 16
class-attribute
instance-attribute
This specifies the IP address of the client's swap server.
The code for this option is 16 and its length is 4.
TCODE = 101
class-attribute
instance-attribute
TCP_DEFAULT_TTL = 37
class-attribute
instance-attribute
This option specifies the default TTL that the client should use when sending TCP segments. The value is represented as an 8-bit unsigned integer. The minimum value is 1.
The code for this option is 37, and its length is 1.
TCP_KEEPALIVE_GARBAGE = 39
class-attribute
instance-attribute
This option specifies the whether or not the client should send TCP keepalive messages with a octet of garbage for compatibility with older implementations. A value of 0 indicates that a garbage octet should not be sent. A value of 1 indicates that a garbage octet should be sent.
The code for this option is 39, and its length is 1.
TCP_KEEPALIVE_INTERVAL = 38
class-attribute
instance-attribute
This option specifies the interval (in seconds) that the client TCP should wait before sending a keepalive message on a TCP connection. The time is specified as a 32-bit unsigned integer. A value of zero indicates that the client should not generate keepalive messages on connections unless specifically requested by an application.
The code for this option is 38, and its length is 4.
TFTP_SERVER = 66
class-attribute
instance-attribute
This option is used to identify a TFTP server when the 'sname' field in the DHCP header has been used for DHCP options.
The code for this option is 66, and its minimum length is 1.
TFTP_SERVER_ADDRESS = 150
class-attribute
instance-attribute
Can replace siaddr and also provide multiple addresses instead of just one. Only IP Address
May also be use by ETHERBOOT
GRUB configuration path name
TIME_OFFSET = 2
class-attribute
instance-attribute
The time offset field specifies the offset of the client's subnet in seconds from Coordinated Universal Time (UTC). The offset is expressed as a two's complement 32-bit integer. A positive offset indicates a location east of the zero meridian and a negative offset indicates a location west of the zero meridian.
The code for the time offset option is 2, and its length is 4 octets.
TRAILER_ENCAPSULATION = 34
class-attribute
instance-attribute
This option specifies whether or not the client should negotiate the use of trailers (RFC 893 [14]) when using the ARP protocol. A value of 0 indicates that the client should not attempt to use trailers. A value of 1 means that the client should attempt to use trailers.
The code for this option is 34, and its length is 1.
USERAUTH = 98
class-attribute
instance-attribute
USER_CLASS = 77
class-attribute
instance-attribute
UUID = 97
class-attribute
instance-attribute
V4_ACCESS_DOMAIN = 213
class-attribute
instance-attribute
V4_DNR = 162
class-attribute
instance-attribute
V4_DOTS_ADDRESS = 148
class-attribute
instance-attribute
V4_DOTS_RI = 147
class-attribute
instance-attribute
V4_LOST = 137
class-attribute
instance-attribute
V4_PCP_SERVER = 158
class-attribute
instance-attribute
V4_PORTPARAMS = 159
class-attribute
instance-attribute
V4_SZTP_REDIRECT = 143
class-attribute
instance-attribute
VENDOR_CLASS_IDENTIFIER = 60
class-attribute
instance-attribute
This option is used by DHCP clients to optionally identify the vendor type and configuration of a DHCP client. The information is a string of n octets, interpreted by servers. Vendors may choose to define specific vendor class identifiers to convey particular configuration or other identification information about a client. For example, the identifier may encode the client's hardware configuration. Servers not equipped to interpret the class-specific information sent by a client MUST ignore it (although it may be reported). Servers that
respond SHOULD only use option 43 to return the vendor-specific information to the client.
The code for this option is 60, and its minimum length is 1.
VENDOR_SPECIFIC_INFORMATION = 43
class-attribute
instance-attribute
This option is used by clients and servers to exchange vendor- specific information. The information is an opaque object of n octets, presumably interpreted by vendor-specific code on the clients and servers. The definition of this information is vendor specific. The vendor is indicated in the vendor class identifier option. Servers not equipped to interpret the vendor-specific information sent by a client MUST ignore it (although it may be reported). Clients which do not receive desired vendor-specific information SHOULD make an attempt to operate without it, although they may do so (and announce they are doing so) in a degraded mode.
If a vendor potentially encodes more than one item of information in this option, then the vendor SHOULD encode the option using "Encapsulated vendor-specific options" as described below:
The Encapsulated vendor-specific options field SHOULD be encoded as a sequence of code/length/value fields of identical syntax to the DHCP options field with the following exceptions:
1) There SHOULD NOT be a "magic cookie" field in the encapsulated vendor-specific extensions field.
2) Codes other than 0 or 255 MAY be redefined by the vendor within the encapsulated vendor-specific extensions field, but SHOULD conform to the tag-length-value syntax defined in section 2.
3) Code 255 (END), if present, signifies the end of the encapsulated vendor extensions, not the end of the vendor extensions field. If no code 255 is present, then the end of the enclosing vendor-specific information field is taken as the end of the encapsulated vendor-specific extensions field.
The code for this option is 43 and its minimum length is 1.
VI_VENDOR_CLASS = 124
class-attribute
instance-attribute
VI_VENDOR_SPECIFIC_INFORMATION = 125
class-attribute
instance-attribute
VSS = 221
class-attribute
instance-attribute
WPAD = 252
class-attribute
instance-attribute
WWW_SERVER = 72
class-attribute
instance-attribute
The WWW server option specifies a list of WWW available to the client. Servers SHOULD be listed in order of preference.
The code for the WWW server option is 72. The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.
X_WINDOW_FONT_SERVER = 48
class-attribute
instance-attribute
This option specifies a list of X Window System [21] Font servers available to the client. Servers SHOULD be listed in order of preference.
The code for this option is 48. The minimum length of this option is 4 octets, and the length MUST be a multiple of 4.
X_WINDOW_MANAGER = 49
class-attribute
instance-attribute
This option specifies a list of IP addresses of systems that are running the X Window System Display Manager and are available to the client.
Addresses SHOULD be listed in order of preference.
The code for the this option is 49. The minimum length of this option is 4, and the length MUST be a multiple of 4.
BaseDHCPOptionCode
The base any custom code map subclasses; pass one to DHCPOptions(codemap=...) to
serve a private or vendor option space instead of the IANA registry above.
pydhcp.options.BaseDHCPOptionCode
The base class of a code enum: the defaults of OptionCode.
A subclass that is an int or has an int value (an IntEnum) needs only
to override get_type and label for the codes it names.
Source code in src/pydhcp/options/_codes.py
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | |
__int__()
The option code as a byte value.
A subclass that carries neither a value (the enum case) nor an
integer identity of its own has no option code, and raises. Zero is
not a neutral answer: it is PAD, the wire padding marker, so such a
code would silently address option 0 and be stored, encoded and
emitted as a PAD TLV.
Source code in src/pydhcp/options/_codes.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | |
__repr__()
Source code in src/pydhcp/options/_codes.py
86 87 88 | |
__str__()
Source code in src/pydhcp/options/_codes.py
90 91 | |
decode(code, value)
classmethod
Source code in src/pydhcp/options/_codes.py
98 99 100 101 | |
from_code(code)
classmethod
Source code in src/pydhcp/options/_codes.py
54 55 56 | |
get_type()
Source code in src/pydhcp/options/_codes.py
48 49 | |
label()
Source code in src/pydhcp/options/_codes.py
51 52 | |
normalize(code, value)
classmethod
Source code in src/pydhcp/options/_codes.py
93 94 95 96 | |
resolve(name)
classmethod
The code name names: a number, option-<n>, or a member name in
any case with - and _ alike (bootfile-name). ValueError for text
that is none of these; see pydhcp/options/AGENTS.md.
Source code in src/pydhcp/options/_codes.py
58 59 60 61 62 63 | |
to_json()
Source code in src/pydhcp/options/_codes.py
83 84 | |
DHCPOption
pydhcp.options.DHCPOption
Bases: NamedTuple
Source code in src/pydhcp/options/_codes.py
104 105 106 | |
code
instance-attribute
value
instance-attribute
Option Types
pydhcp.options
BaseFixedLengthInteger
Bases: DHCPOptionType, int
Source code in src/pydhcp/options/_codecs/_scalar.py
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | |
to_json()
A plain int, not this subclass.
The base to_json returns self, and self is a U16/U32. JSON
tolerates an int subclass; YAML refuses to represent it and TOML writes
something it cannot read back, so a packet carrying any integer option
-- which is most real packets, via option 57 or 51 -- could not survive
a round trip through either.
Source code in src/pydhcp/options/_codecs/_scalar.py
354 355 356 357 358 359 360 361 362 363 | |
Boolean
Bases: DHCPOptionType, int
Boolean option encoded as a single octet.
Source code in src/pydhcp/options/_codecs/_scalar.py
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | |
Bytes
Bases: DHCPOptionType, _TextForm, bytes
Opaque byte payload: built from bytes, written as hex text.
Source code in src/pydhcp/options/_codecs/_scalar.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | |
from_json(data)
classmethod
Hex text, as to_json writes it; bytes-like as the constructor takes it.
The constructor itself refuses text, so a str assigned to an opaque
option is never silently read as hex.
Source code in src/pydhcp/options/_codecs/_scalar.py
67 68 69 70 71 72 73 74 | |
parse(text)
classmethod
Build from hex text; spaces and colons between octets are ignored.
Raises DHCPValueError for anything that is not whole hex octets.
Source code in src/pydhcp/options/_codecs/_scalar.py
35 36 37 38 39 40 41 42 43 44 45 | |
CCCAPBackoffRetry
Bases: CCCASBackoffRetry
CCC sub-option 5 AP-REQ/AP-REP backoff and retry tuple.
Source code in src/pydhcp/options/_codecs/_ccc.py
254 255 | |
CCCASBackoffRetry
Bases: _Record
CCC sub-option 4 AS-REQ/AS-REP backoff and retry tuple.
Source code in src/pydhcp/options/_codecs/_ccc.py
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | |
CCCKDCServerAddressList
Bases: List[IPv4AddressOption]
CCC sub-option 10 KDC server address list.
Source code in src/pydhcp/options/_codecs/_ccc.py
304 305 | |
CCCKerberosRealmName
Bases: _CCCDomainText
CCC Kerberos realm payload without DNS compression.
Source code in src/pydhcp/options/_codecs/_ccc.py
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | |
CCCOption
Bases: RecordList[CCCSubOption]
CCC option container preserving unknown sub-options.
Source code in src/pydhcp/options/_codecs/_ccc.py
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 | |
CCCPrimaryDHCPServerAddress
Bases: IPv4AddressOption
CCC sub-option 1 primary DHCP server address.
Source code in src/pydhcp/options/_codecs/_ccc.py
198 199 | |
CCCProvisioningServerAddress
Bases: _Record
CCC sub-option 3 tagged union for IPv4 address or FQDN.
Source code in src/pydhcp/options/_codecs/_ccc.py
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | |
CCCProvisioningServerFQDN
Bases: _CCCDomainText
CCC provisioning server FQDN payload without DNS compression.
Source code in src/pydhcp/options/_codecs/_ccc.py
65 66 | |
CCCProvisioningTimer
Bases: U8
CCC sub-option 8 provisioning timer value.
Source code in src/pydhcp/options/_codecs/_ccc.py
262 263 | |
CCCSecondaryDHCPServerAddress
Bases: IPv4AddressOption
CCC sub-option 2 secondary DHCP server address.
Source code in src/pydhcp/options/_codecs/_ccc.py
202 203 | |
CCCSecurityTicketControl
Bases: DHCPOptionType, int
CCC sub-option 9 security ticket control mask.
Source code in src/pydhcp/options/_codecs/_ccc.py
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | |
CCCSubOption
Bases: _Record
Typed CCC sub-option record.
Source code in src/pydhcp/options/_codecs/_ccc.py
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | |
CCCTicketGrantingServerUtilization
Bases: Boolean
CCC sub-option 7 ticket-granting server utilization toggle.
Source code in src/pydhcp/options/_codecs/_ccc.py
258 259 | |
ClasslessRoute
Bases: _Record, _TextForm
RFC 3442 classless static route entry.
Accepts either ClasslessRoute(gateway, network) or a single
(gateway, network) pair / existing instance, so that the option's list
container can normalize routes coming from JSON, YAML or a config file.
Source code in src/pydhcp/options/_codecs/_addresses.py
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | |
parse(text)
classmethod
Build from "10.0.0.0/8 via 192.0.2.1", the text str() produces.
Raises DHCPValueError for anything else, host bits set in the network
included.
Source code in src/pydhcp/options/_codecs/_addresses.py
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | |
ClientArchitecture
Bases: DHCPOptionType, IntEnum
One entry of option 93: the IANA "Processor Architecture Types" registry.
RFC 4578 s2.1 started the list; IANA's registry, which RFC 5970 shares with DHCPv6, corrects it (7 is x64 UEFI and 9 is EBC) and extends it. A number the registry does not name is an unnamed member carrying it, never refused.
Source code in src/pydhcp/options/_codecs/_pxe.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | |
_missing_(value)
classmethod
An unnamed member for a number the registry does not name (0 to 65535).
Source code in src/pydhcp/options/_codecs/_pxe.py
70 71 72 73 74 75 76 77 78 79 80 81 82 83 | |
is_http()
Whether this is one of the registry's "boot from http" architectures.
Source code in src/pydhcp/options/_codecs/_pxe.py
101 102 103 | |
label()
The member's name, or ARCH_<n> for a number that has none.
Source code in src/pydhcp/options/_codecs/_pxe.py
109 110 111 | |
to_json()
The member's name, or the number when it has none.
Source code in src/pydhcp/options/_codecs/_pxe.py
105 106 107 | |
ClientFQDN
Bases: _Record, _TextForm
RFC 4702 Client FQDN: flags, RCODE1, RCODE2, then the name.
With the E bit the name is a fully qualified name (RFC 1035 labels and the
terminating zero-length label), a partial name (the labels without the
terminator) or empty (RFC 4702 s2.3). partial says which: it is true for
a partial name and for an empty field, false for a qualified name and for
the root (a lone terminator), so what is decoded is encoded to the octets
it came from. The four reserved flag bits are ignored on receive and may
not be set on send (s2.1).
Registering this as a plain String lost data silently rather than loudly:
String splits at the first NUL, so the form every Windows client sends
(00 00 00 then the name) decoded to the empty string, and a server reading
it for DDNS saw no name at all. Emitting was the mirror image -- the first
three characters of the name were read by the client as Flags/RCODE1/RCODE2.
Source code in src/pydhcp/options/_codecs/_fqdn.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | |
encoded
property
Whether the name is carried in DNS wire format (the E bit).
__str__()
The name; with [flags=0x05 rcode1=0 rcode2=0 partial] after it when those are set.
Source code in src/pydhcp/options/_codecs/_fqdn.py
102 103 104 105 106 107 108 109 | |
_read_wire_name(field)
staticmethod
The name of an E-bit field and whether it is partial (RFC 4702 s2.3).
Source code in src/pydhcp/options/_codecs/_fqdn.py
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | |
parse(text)
classmethod
Build from the name, or from the text str() produces when flags are set.
Raises DHCPValueError for a bracketed part that is malformed or that
sets a reserved flag bit.
Source code in src/pydhcp/options/_codecs/_fqdn.py
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | |
ClientIdentifier
Bases: Bytes
RFC 2132 client identifier.
Source code in src/pydhcp/options/_codecs/_scalar.py
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 | |
ClientMachineID
Bases: _Record
Option 97 (RFC 4578 s2.3): a type octet, then the machine identifier.
Type 0, the only one defined, is a 16-octet GUID, which uuid reads in the
order the octets arrived. Any other type or length is kept as received;
sending a type 0 that is not 16 octets raises DHCPValueError.
Source code in src/pydhcp/options/_codecs/_pxe.py
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | |
uuid
property
The GUID as a uuid.UUID, or None when this is not a 16-octet type 0.
from_json(data)
classmethod
What to_json writes, or the hex text of a document written while
this option had no codec of its own.
Source code in src/pydhcp/options/_codecs/_pxe.py
227 228 229 230 231 232 233 | |
from_uuid(value)
classmethod
A type 0 identifier holding value's 16 octets.
Source code in src/pydhcp/options/_codecs/_pxe.py
196 197 198 199 | |
ClientNDI
Bases: _Record
Option 94 (RFC 4578 s2.2): the network interface type and its revision.
Type 1 is UNDI, the only one defined; major and minor are its revision
(ClientNDI(1, 3, 16) is UNDI 3.16).
Source code in src/pydhcp/options/_codecs/_pxe.py
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | |
from_json(data)
classmethod
What to_json writes, or the hex text of a document written while
this option had no codec of its own.
Source code in src/pydhcp/options/_codecs/_pxe.py
163 164 165 166 167 168 169 | |
DHCPOptionCodes
Bases: List[_C]
List of option codes used by parameter-request-list style options.
Source code in src/pydhcp/options/_codecs/_lists.py
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | |
DHCPOptionType
The base class of the option payload codecs: the defaults of OptionCodec.
A subclass implements unpack_from and pack_into (and its constructor),
may set fixed_size, and may override to_json and display_text. unpack
and pack are built on those: unpack refuses a payload of the wrong size
or with octets left over, and pack collects what pack_into writes. The
pair should round-trip the same Python value.
Source code in src/pydhcp/options/_codecs/_base.py
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | |
display_text()
The text the message display and the capture formats show for this value.
Source code in src/pydhcp/options/_codecs/_base.py
108 109 110 | |
from_json(data)
classmethod
The value to_json wrote: cls(data), and an enum also by member name.
A codec whose constructor does not take its own to_json form overrides
this (Bytes reads hex text here, and only here).
Source code in src/pydhcp/options/_codecs/_base.py
95 96 97 98 99 100 101 102 103 104 105 106 | |
DomainList
Bases: _NormalizedList[str]
RFC 1035 domain-name list with compression support.
Normalizes like List[T] does, and for the same reason. With no
__init__ this inherited list's, where a str argument is an
iterable of characters: DomainList("corp") was ["c", "o", "r", "p"]
and options[119] = "corp" silently offered the client four
single-letter search domains. A bare name is one entry; pass a list for
several.
Source code in src/pydhcp/options/_codecs/_domains.py
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | |
unpack_from(option)
classmethod
Decode a compressed search list (RFC 1035 s4.1.4, RFC 3397 s3).
Bounded as read_names says. A last name that ends, between labels,
without a root label or a whole pointer is discarded (RFC 3397 s3), and
the names before it are kept.
Source code in src/pydhcp/options/_codecs/_domains.py
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | |
DomainName
Bases: DHCPOptionType, str
A single uncompressed RFC 1035 name, as an option payload.
Options 147 (RFC 8973 s5.2) and 213 (RFC 5986 s3.2) carry a label sequence,
not dotted text. Registered as String they decoded to the raw label bytes
rather than to example.com, and emitted dotted text that a conforming
receiver cannot parse.
Source code in src/pydhcp/options/_codecs/_domains.py
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | |
EncapsulatedOptions
Bases: RecordList[TLVOption]
TLV container for building vendor-specific sub-option payloads.
Source code in src/pydhcp/options/_codecs/_vendor.py
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | |
Flag
Bases: DHCPOptionType
Zero-length presence option.
Some options carry their whole meaning in being present at all -- RFC 4039's Rapid Commit is "Code 80, Len 0". Encoding such an option as a one-octet Boolean both rejects conformant packets on decode and emits a malformed option on encode.
Source code in src/pydhcp/options/_codecs/_scalar.py
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | |
I32
Bases: FixedLengthInteger
Signed 32-bit integer.
Source code in src/pydhcp/options/_codecs/_scalar.py
407 408 409 410 411 | |
I8
Bases: FixedLengthInteger
Signed 8-bit integer.
Source code in src/pydhcp/options/_codecs/_scalar.py
414 415 416 417 418 | |
IPXEBusID
Bases: _Record
BUS_ID: the bus type octet, then what that bus identifies the NIC by.
For PCI (type 1) that is the vendor and device, two big-endian octets each,
which vendor and device read; any other bus is kept as its octets.
Source code in src/pydhcp/options/_ipxe.py
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | |
device
property
The PCI device ID, or None for another bus.
vendor
property
The PCI vendor ID, or None for another bus.
IPXEOption
Bases: OptionCodeEnum
The sub-options of option 175, named as iPXE's DHCP_EB_* constants are.
Source code in src/pydhcp/options/_ipxe.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | |
is_feature()
Whether this sub-option is one of iPXE's feature flags (0x10 to 0x29).
Source code in src/pydhcp/options/_ipxe.py
71 72 73 | |
IPXEOptions
Bases: EncapsulatedOptions
Option 175: iPXE's sub-options, kept as the octets they arrived as.
get reads one by its IPXEOption codec; to_json writes [name, value]
pairs a document can hold, and reading takes them back. A sub-option is built
from (code, value) where the code is a number or a name IPXEOption.resolve
reads and the value octets, a codec value, or what its codec's from_json takes.
Source code in src/pydhcp/options/_ipxe.py
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | |
_item_text(option)
One sub-option as the message display shows it: HTTPS=U8(1).
Source code in src/pydhcp/options/_ipxe.py
267 268 269 270 271 | |
features()
The feature flags present, in the order they were sent.
Source code in src/pydhcp/options/_ipxe.py
236 237 238 239 240 241 242 243 | |
from_json(data)
classmethod
What to_json writes, or the hex text of a document written while
this option had no codec of its own.
Source code in src/pydhcp/options/_ipxe.py
259 260 261 262 263 264 265 | |
get(code, default=None)
The first sub-option code names, decoded by its codec, or default.
Octets its codec refuses come back as Bytes, never as an error.
Source code in src/pydhcp/options/_ipxe.py
225 226 227 228 229 230 231 232 233 234 | |
IPXEVersion
Bases: _Record
VERSION: iPXE's major, minor and patch numbers, one octet each.
Source code in src/pydhcp/options/_ipxe.py
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | |
IPv4AddressOption
Bases: DHCPOptionType, IPv4Address
A single IPv4 address carried in network byte order.
Source code in src/pydhcp/options/_codecs/_addresses.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | |
LenientUserClass
Bases: UserClass
Option 77 in either form a client sends: RFC 3004's or one flat string.
RFC 3004 prefixes each class with its length; iPXE, and DHCP servers that predate the RFC, treat the option as one string. A payload is read as RFC 3004 when its length octets account for every octet and no class is empty, and as one class otherwise. That can misread only flat text of 33 octets or more whose first octet, and each length it leads to, land exactly on the end. Written back, the classes are always RFC 3004 framed.
Source code in src/pydhcp/options/_codecs/_vendor.py
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | |
List
Bases: _NormalizedList[_T]
Typed DHCP option list container.
Source code in src/pydhcp/options/_codecs/_lists.py
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | |
from_json(data)
classmethod
Each item read back by its own codec's from_json, as to_json wrote it.
Source code in src/pydhcp/options/_codecs/_lists.py
69 70 71 72 73 74 75 | |
item_type()
classmethod
The codec of each item: IPv4AddressOption for List[IPv4AddressOption].
A subclass of a subscripted list answers its base's; List itself,
unsubscripted, has none and raises TypeError.
Source code in src/pydhcp/options/_codecs/_lists.py
30 31 32 33 34 35 36 37 38 39 40 | |
MoSFQDNList
Bases: RecordList[MoSFQDNRecord]
RFC 5678 MoS option carrying FQDN sub-options.
Source code in src/pydhcp/options/_codecs/_mos.py
221 222 | |
MoSFQDNRecord
Bases: _MoSFQDNSubOption
RFC 5678 MoS sub-option record carrying FQDN label sequences.
Source code in src/pydhcp/options/_codecs/_mos.py
213 214 | |
MoSIPv4AddressList
Bases: RecordList[MoSIPv4AddressRecord]
RFC 5678 MoS option carrying IPv4 address sub-options.
Source code in src/pydhcp/options/_codecs/_mos.py
217 218 | |
MoSIPv4AddressRecord
Bases: _MoSIPv4AddressSubOption
RFC 5678 MoS sub-option record carrying IPv4 addresses.
Source code in src/pydhcp/options/_codecs/_mos.py
209 210 | |
OctetString
Bases: String
Text that is the whole payload: no NUL terminator, no truncation.
RFC 2132 s9.13 defines option 60 as "a string of n octets" -- not a
NUL-terminated NVT string. String partitions at the first NUL, so a vendor
class identifier that is binary, as embedded and CPE firmware sends, decoded
to the empty string and lost everything a server might have matched on.
Octets that are not valid UTF-8 are preserved, as in String.
Source code in src/pydhcp/options/_codecs/_scalar.py
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | |
OptionCode
Bases: Protocol
What a code enum a DHCPOptions bag resolves option codes with provides.
A member names an option and knows its codec (get_type) and its name
(label), and converts to the octet it is sent as (int()); the class
builds a member from a number (from_code) and builds or decodes a whole
option (normalize, decode). BaseDHCPOptionCode is the base class with
the defaults for these; DHCPOptionCode is the IANA registry.
Source code in src/pydhcp/options/_codes.py
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | |
OptionCodeEnum
Bases: BaseDHCPOptionCode, IntEnum
The base of an option-code enum: a member per named code, the rest unnamed.
Each subclass has its own codec table and its own unnamed members, so one enum's registrations and lookups never reach another's.
Source code in src/pydhcp/options/_codes.py
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | |
_missing_(value)
classmethod
Return an opaque pseudo-member for any byte value without one.
Only 163 of codes 0-255 are members of DHCPOptionCode, and RFC 3942
reserves 224-254 for site-specific use, so raising for the rest means a
client sending any of them gets no service at all: the receive path
resolves every option code before the packet reaches a handler. Such
codes carry no known structure, so get_type() returns Bytes and
label() reports "UNKNOWN" -- which is what the shipped API header
documents.
Source code in src/pydhcp/options/_codes.py
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | |
register_type(optiontype)
Bind optiontype as this code's codec in this enum, permanently.
The built-in registry is loaded with this module, so a registration made after import is always the later write.
Source code in src/pydhcp/options/_codes.py
162 163 164 165 166 167 168 169 170 171 172 173 | |
OptionCodec
Bases: Protocol
What an option payload codec is: a value that reads and writes its octets.
A codec is built from one value (Codec(value)), reads itself from the
octets of an option (unpack, unpack_from), writes itself back (pack,
pack_into) and renders itself for a structured document (to_json) and
for the message display (display_text). DHCPOptionType is the base class
that supplies everything but unpack_from, pack_into and the
constructor; subclassing it is the way to get a codec the registry accepts.
isinstance(x, OptionCodec) checks that the methods exist, not their
signatures.
Source code in src/pydhcp/options/_codecs/_base.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | |
display_text()
The text the message display shows for the value.
Source code in src/pydhcp/options/_codecs/_base.py
61 62 63 | |
fixed_size()
classmethod
The payload length every value has, or None when it varies.
Source code in src/pydhcp/options/_codecs/_base.py
44 45 46 47 | |
pack()
The octets of the payload.
Source code in src/pydhcp/options/_codecs/_base.py
49 50 51 | |
pack_into(buffer)
Append the octets of the payload to buffer; how many were written.
Source code in src/pydhcp/options/_codecs/_base.py
53 54 55 | |
to_json()
The value as plain data for a JSON, YAML, TOML or INI document.
Source code in src/pydhcp/options/_codecs/_base.py
57 58 59 | |
unpack(data)
classmethod
The value held by all of data; DHCPDecodeError if it is not one.
Source code in src/pydhcp/options/_codecs/_base.py
30 31 32 33 34 35 | |
unpack_from(option)
classmethod
The value at the start of option, and how many octets it took.
Source code in src/pydhcp/options/_codecs/_base.py
37 38 39 40 41 42 | |
OptionOverload
Bases: DHCPOptionType, IntFlag
RFC 2132 option-overload selector.
Source code in src/pydhcp/options/_codecs/_scalar.py
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 | |
PCPServerList
Bases: _NormalizedList[tuple[str, ...]]
RFC 7291 s4 PCP servers: one or more length-prefixed address lists.
Each entry is a List-Length octet giving the octet count, then that many
octets of IPv4 addresses; separate entries are separate PCP servers. An
entry is stored as a tuple of address texts, so it cannot be changed past
the checks append makes: replace the entry instead.
Registered as a flat List[IPv4AddressOption] the length octet was read as
address data, so a conformant option raised and an emitted one carried no
length octet at all.
Source code in src/pydhcp/options/_codecs/_servers.py
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 | |
_item_text(entry)
staticmethod
One entry as its addresses in brackets, the way a list of them reads.
Source code in src/pydhcp/options/_codecs/_servers.py
366 367 368 369 | |
PolicyFilter
Bases: _IPv4PairList
List of IPv4 destination/mask pairs for policy filtering.
Source code in src/pydhcp/options/_codecs/_addresses.py
190 191 | |
RDNSSSelection
Bases: _Record
RFC 6731 RDNSS selection payload.
Source code in src/pydhcp/options/_codecs/_servers.py
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | |
RecordList
Bases: List[_T]
Typed list of two-field records, normalized from (first, second) pairs.
Five containers repeated List's whole shape around a record type that
takes two constructor arguments -- the MoS options, the two RFC 3925 VI*
options, option 82's encapsulated TLVs and the CCC option. They differ from
List in exactly one place: a record is itself a two-element sequence, so
List.__init__'s rule that a tuple argument is a sequence of items would
split one (code, value) record into two items. Here only a list spells
"several records"; a tuple is one record.
Subclass a subscripted form (class X(RecordList[SomeRecord])) rather than
setting a _RECORD_TYPE attribute -- _args_[0] is the same information and
unpack_from/_normalize already read it.
Source code in src/pydhcp/options/_codecs/_lists.py
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | |
from_json(data)
classmethod
The [first, second] pairs to_json wrote, each normalized as a record.
Source code in src/pydhcp/options/_codecs/_lists.py
109 110 111 112 | |
RelayAgentInformation
Bases: EncapsulatedOptions
RFC 3046 relay-agent sub-options.
Plain code, length, value tuples: RFC 3046 s2.0 defines no pad sub-option and no terminating 255, so 0 and 255 are sub-option codes like any other.
Source code in src/pydhcp/options/_codecs/_vendor.py
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | |
SIPServers
Bases: _Record
RFC 3361 SIP servers: an encoding octet, then names or addresses.
Encoding 0 is a list of RFC 1035 names, encoding 1 a list of IPv4 addresses. Registered as a bare address list, a conformant option could not be decoded at all, and an emitted one would have no encoding octet -- so a SIP phone would read the first address octet as the encoding and reject the option.
Source code in src/pydhcp/options/_codecs/_servers.py
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | |
StaticRoute
Bases: _IPv4PairList
List of IPv4 destination/router pairs for static routing.
Source code in src/pydhcp/options/_codecs/_addresses.py
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | |
unpack_from(option)
classmethod
Read the pairs as they came, a 0.0.0.0 destination included.
RFC 2132 s5.8 forbids that destination: a sender is refused it
(append, pack_into) and a receiver keeps the route a peer sent.
Source code in src/pydhcp/options/_codecs/_addresses.py
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | |
StatusCode
Bases: _Record, _TextForm
RFC 6926 s6.2.2 status: one code octet, then an optional UTF-8 message.
Registered as a bare U8 the message made the option the wrong size, so a
DHCPLEASEQUERY reply carrying one could not be decoded at all.
Source code in src/pydhcp/options/_codecs/_servers.py
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | |
parse(text)
classmethod
Build from "<code>" or "<code> <message>", the text str() produces.
The message is everything after the first space. Raises DHCPValueError
for a code that is not a number in 0-255.
Source code in src/pydhcp/options/_codecs/_servers.py
255 256 257 258 259 260 261 262 263 264 265 266 267 | |
String
Bases: DHCPOptionType, str
RFC 2132 NVT-ASCII string, not null-terminated on the wire.
A value read from the wire ends at the first NUL octet, so a trailing NUL
and everything after an embedded one are dropped (RFC 2132 s2 asks a
receiver to delete trailing NULs; OctetString keeps every octet).
Octets that are not valid UTF-8 are preserved rather than replaced, so a
hostname or boot filename in another encoding survives a decode/encode round
trip intact; to_json renders the display form. See pydhcp._nvt.
Source code in src/pydhcp/options/_codecs/_scalar.py
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | |
__new__(value='')
Text, or octets read as text; anything else is a TypeError.
None is not an empty string: an option with nothing to say is deleted
from the bag, not stored.
Source code in src/pydhcp/options/_codecs/_scalar.py
160 161 162 163 164 165 166 167 168 169 170 171 172 | |
U16
Bases: FixedLengthInteger
Unsigned 16-bit integer.
Source code in src/pydhcp/options/_codecs/_scalar.py
393 394 395 396 397 | |
U32
Bases: FixedLengthInteger
Unsigned 32-bit integer.
Source code in src/pydhcp/options/_codecs/_scalar.py
400 401 402 403 404 | |
U8
Bases: FixedLengthInteger
Unsigned 8-bit integer.
Source code in src/pydhcp/options/_codecs/_scalar.py
386 387 388 389 390 | |
URIList
Bases: _NormalizedList[str]
List of UTF-8 URIs encoded as repeated U16-length-prefixed entries.
Source code in src/pydhcp/options/_codecs/_scalar.py
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | |
UncompressedDomainList
Bases: DomainList
A domain-name list for the options that forbid DNS name compression.
RFC 3397's search list (option 119) is compressed on purpose. Two other
options carrying a name list are not, and both were registered as plain
DomainList, so pydhcp emitted a 0xC0 pointer into payloads whose own
RFCs forbid one:
- option 88, BCMCS controller domain names -- RFC 4280 §4.6: "The domain names MUST be concatenated and encoded using the technique described in Section 3.3 of [RFC1035]. DNS name compression MUST NOT be used."
- option 146, RDNSS selection -- RFC 6731 §4.3 defers to RFC 3315 §8: "A domain name, or list of domain names, in DHCP MUST NOT be stored in compressed form, as described in section 4.1.4 of RFC 1035."
Compressed, ["a.example.com", "b.example.com"] would encode as
01 61 07 example 03 com 00 01 62 c0 02 for option 88 -- the second name
ending in a pointer a conforming receiver is not required to follow.
Encode only. Decoding stays DomainList's: a pointer that arrives
resolves unambiguously inside the option, and the receive path in this
package is deliberately liberal, so refusing one would turn a readable
packet from a non-conforming peer into a decode failure. The RFCs
constrain what is sent, and that is what this encoder constrains.
Source code in src/pydhcp/options/_codecs/_domains.py
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | |
UserClass
Bases: _LengthPrefixedOpaqueList
RFC 3004 user-class opaque byte list.
Source code in src/pydhcp/options/_codecs/_vendor.py
88 89 90 91 92 93 94 | |
VIVendorClass
Bases: RecordList[VIVendorClassRecord]
RFC 3925 vendor-identifying vendor class records.
Source code in src/pydhcp/options/_codecs/_vendor.py
344 345 | |
VIVendorSpecificInformation
Bases: RecordList[VIVendorSpecificInformationRecord]
RFC 3925 vendor-identifying vendor-specific information records.
Source code in src/pydhcp/options/_codecs/_vendor.py
284 285 | |
VendorSpecificInformation
Bases: Bytes
Opaque vendor-specific payload for option 43.
Source code in src/pydhcp/options/_codecs/_vendor.py
203 204 | |
DHCPServer
pydhcp.server.DHCPServer
Bases: _ServerCore, DHCPListener
A DHCP server: a DHCPListener that allocates leases and sends the RFC 2131 replies.
Override any method or constant here: the handle_* hooks, acquire_lease,
release_lease, get_inform_options, get_lease_seconds and the lease-policy
constants. They run on the receive thread.
Source code in src/pydhcp/server/_sync.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | |
bound_addresses
property
The addresses this listener is currently bound to.
Empty before bind() and once the sockets are closed. Asking the socket
rather than repeating the listen list is the point: binding port 0 gives
an ephemeral port that only the socket knows, which is how a test or a
tool discovers where to send.
acquire_lease(client_id, server_id, msg, *, commit=True)
Return a lease for a client message.
This is the extension point for address pools, reservations, policy checks and custom response options. It is an ordinary method of this server, called on the server itself from the handler thread (the one worker thread on the async server), so an attribute it keeps -- the next free host, a cache -- is the server's own.
commit says what kind of call this is. False: the server is deciding
what to offer or whether to ACK (RFC 2131 s4.3.1 makes DHCPDISCOVER a
probe), so the call must not extend an existing binding or add state
that a client declining the offer would leave behind. True: the answer
is being committed. A DHCPDISCOVER makes one call with commit=False; a
DHCPREQUEST makes two, commit=False to decide and then commit=True
if it is ACKed. An override honours commit itself, including in what
it does to self.lease_backend, which is the real backend on both
calls.
The base implementation is intentionally small. A client with a record
gets it back: on commit=False as it stands, on commit=True an
offered lease committed (LeaseBackend.commit) and a bound one renewed.
Only a DHCPDISCOVER makes a record: from a client with none it holds
the address in REQUESTED_IP (or ciaddr) as an offer for
OFFER_HOLD_SECONDS on commit=False, and allocates it on
commit=True. A DHCPREQUEST from a client with no record gets None.
A message whose giaddr is outside the served network gets None:
the stock allocator has the one network to give.
Source code in src/pydhcp/server/_policy.py
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | |
bind()
Open the sockets the specification names; does nothing once they are open.
Raises what the bind raised, leaving none open, and RuntimeError once
the listener is closed.
Source code in src/pydhcp/listener/_core.py
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | |
close()
Shut down and release every socket, as DHCPListener.close.
A lease backend the server was given is not closed: it is the caller's. One the server created itself is closed here.
Source code in src/pydhcp/server/_sync.py
43 44 45 46 47 48 49 50 | |
get_inform_options(server_id, msg)
Return configuration options for DHCPINFORM responses.
DHCPINFORM does not allocate an address. Override this method when clients should receive site-specific options without touching lease allocation.
Source code in src/pydhcp/server/_policy.py
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 | |
get_lease_seconds(msg)
Lease length to grant for msg, applying this server's policy.
RFC 2131 s4.3.1 lets the server honour a client's requested lease time only "if acceptable to local policy" -- a MAY, so there has to be a policy. There was none: the requested value went straight through, and any client could hold an address for 136 years by asking for one.
RFC 2132 s3.3 also makes 0xFFFFFFFF mean infinity, not 4294967295 seconds. Taken literally it became a finite expiry in 2162, and the reply then advertised 4294967294 -- a different number than the client asked for, one second short of the sentinel.
Override this, or set the class attributes, to change the policy.
Source code in src/pydhcp/server/_policy.py
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | |
handle_decline(msg, context)
Handle DHCPDECLINE: quarantine the address it names, and release the sender's own.
RFC 2131 s4.3.3: "The server MUST mark the network address as not
available", whoever sent it. A DECLINE naming an address outside the
served network, this host's own, or another server in option 54 changes
nothing and is counted in declines_ignored; the quarantine is bounded
(MAX_DECLINED_ADDRESSES). A record is released only when it is the
sender's own, for the declined address. DECLINE_REQUIRES_LEASE marks
only an address the sender holds, as a binding or an outstanding offer.
Source code in src/pydhcp/server/_handlers.py
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | |
handle_discover(msg, context)
Handle DHCPDISCOVER by offering a lease returned from acquire_lease.
Source code in src/pydhcp/server/_handlers.py
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | |
handle_inform(msg, context)
Handle DHCPINFORM without requiring address allocation.
Source code in src/pydhcp/server/_handlers.py
427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 | |
handle_release(msg, context)
Handle DHCPRELEASE, but only for the address the client actually holds.
Source code in src/pydhcp/server/_handlers.py
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 | |
handle_request(msg, context)
Handle DHCPREQUEST by ACKing or NAKing the lease returned from acquire_lease.
RFC 2131 s4.3.2 and Table 4 tell the four shapes apart, and each is
answered from the record acquire_lease returns for the client:
- SELECTING (option 54 names this server): a lease for the address asked for is ACKed; a request this server cannot satisfy is NAKed (s3.1 step 4), never left unanswered.
- INIT-REBOOT (option 50, no option 54,
ciaddr0), RENEWING (ciaddr, unicast to this server) and REBINDING (ciaddr, broadcast): a lease for the address is ACKed, a lease for another address is NAKed, and no lease at all is silence, because the client may belong to another server on the same wire.
Source code in src/pydhcp/server/_handlers.py
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 | |
is_quarantined(ip, *, now=None)
Whether ip is out of the pool after a DHCPDECLINE.
The server asks this of every lease a hook returns, so an
acquire_lease override does not have to. now is time.monotonic()
seconds; omitted, the driver's reading is used.
Source code in src/pydhcp/server/_policy.py
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 | |
lookup_lease(client_id)
The lease this server holds for client_id, in either state, or None.
What a DHCPDECLINE, a DHCPRELEASE and a REQUEST naming another server
ask to learn what the sender holds. The default reads lease_backend;
a server that keeps its leases elsewhere overrides this one method.
Source code in src/pydhcp/server/_policy.py
439 440 441 442 443 444 445 446 | |
quarantine_address(ip, *, now=None)
Stop offering ip for DECLINE_QUARANTINE_SECONDS.
RFC 2131 4.3.3: a DHCPDECLINE says the client found the address already in use, so the server MUST NOT hand it out again. Releasing the binding alone left it first in line to be offered to the next client, which would collide with whatever is really using it.
The map holds at most MAX_DECLINED_ADDRESSES. At the bound the entries
that have run out are dropped first; if none has, a new address is
refused and counted in quarantines_refused, because evicting the
oldest would let a flood of reports push a genuine one out. An address
already held is renewed for a full quarantine.
now is time.monotonic() seconds; omitted, the driver's reading is
used, so an override that takes only ip keeps working.
Source code in src/pydhcp/server/_policy.py
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | |
release_lease(client_id, server_id, msg)
Release any lease associated with client_id; True if one went away.
Override this method when lease release needs to update an external store
or emit custom audit records. Quarantining a declined address is handled
by quarantine_address, which handle_decline calls before this.
Counting is the caller's job, not this method's, because only the caller knows why: an orderly DHCPRELEASE, a DHCPDECLINE reporting an address conflict, and a reclaim after the client chose another server are three different events that all arrive here.
Source code in src/pydhcp/server/_policy.py
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 | |
serve_forever()
Bind, then receive on the calling thread until shutdown().
Raises what bind() raised, and RuntimeError when already serving or
closed. The sockets stay open on return: close() releases them.
Source code in src/pydhcp/listener/_sync.py
91 92 93 94 95 96 97 98 99 100 101 102 | |
shutdown()
Ask the receive loop to end. Returns at once, from any thread and from a handler.
Source code in src/pydhcp/listener/_sync.py
128 129 130 131 132 133 134 | |
start()
Bind, then receive on a new daemon thread.
Binding happens here, on the caller's thread, so an address that cannot
be bound raises what bind() raised and leaves the listener unstarted
and nothing bound. Raises RuntimeError when already serving or closed.
Source code in src/pydhcp/listener/_sync.py
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | |
wait_closed(timeout=None)
Block until the receive loop has ended; False if timeout seconds passed first.
Raises RuntimeError on the receive thread, which would wait for itself.
Source code in src/pydhcp/listener/_sync.py
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | |
DHCPClient
pydhcp.client.DHCPClient
Bases: _ClientCore, DHCPListener
Small DHCPv4 packet client for tests and troubleshooting.
The base client builds and sends DHCP client messages, then queues matching
replies. It does not configure operating-system network interfaces. Its
receive thread must be running (start()) for an exchange to hear a reply.
Source code in src/pydhcp/client/_sync.py
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | |
bound_addresses
property
The addresses this listener is currently bound to.
Empty before bind() and once the sockets are closed. Asking the socket
rather than repeating the listen list is the point: binding port 0 gives
an ephemeral port that only the socket knows, which is how a test or a
tool discovers where to send.
bind()
Open the sockets the specification names; does nothing once they are open.
Raises what the bind raised, leaving none open, and RuntimeError once
the listener is closed.
Source code in src/pydhcp/listener/_core.py
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | |
close()
Shut down, wait for the receive loop, then release every socket. Final.
Called on the receive thread itself (from a handler) it shuts down and returns: the loop releases the sockets as it ends. Repeatable.
Source code in src/pydhcp/listener/_sync.py
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | |
discover_offer(chaddr, *, timeout=2.0, retries=2, deadline=None, destination=BROADCAST_DESTINATION, port=_SERVER_PORT, xid=None, client_identifier=None, parameter_request_list=None, broadcast=True)
Broadcast DHCPDISCOVER and return the first usable DHCPOFFER.
timeout is the initial retransmission interval, not a fixed one:
each retransmission waits about twice as long as the last, jittered, up
to RETRANSMIT_MAX_INTERVAL (RFC 2131 s4.1). With the defaults the
whole call is bounded at roughly 2+4+8 seconds rather than 3x2;
deadline bounds it outright, in seconds.
An OFFER is usable when it offers an address and names its server;
others are ignored. Raises DHCPTimeoutError when none arrives.
Source code in src/pydhcp/client/_sync.py
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | |
dora(chaddr, *, timeout=2.0, retries=2, deadline=None, destination=BROADCAST_DESTINATION, port=_SERVER_PORT, xid=None, client_identifier=None, parameter_request_list=None, broadcast=True)
Run a full DISCOVER/OFFER/REQUEST/ACK exchange and return the DHCPACK.
timeout is the initial retransmission interval for each half of the
exchange -- see discover_offer; deadline bounds the two halves
together. Raises DHCPTimeoutError when no usable OFFER or ACK arrives
(an ACK is usable when it comes from the server the REQUEST selected) and
DHCPRefusedError when the server answers the REQUEST with a DHCPNAK.
Source code in src/pydhcp/client/_sync.py
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | |
on_reply(msg, context)
Hook called after a BOOTREPLY is accepted and queued.
Source code in src/pydhcp/client/_core.py
417 418 | |
serve_forever()
Bind, then receive on the calling thread until shutdown().
Raises what bind() raised, and RuntimeError when already serving or
closed. The sockets stay open on return: close() releases them.
Source code in src/pydhcp/listener/_sync.py
91 92 93 94 95 96 97 98 99 100 101 102 | |
shutdown()
Ask the receive loop to end. Returns at once, from any thread and from a handler.
Source code in src/pydhcp/listener/_sync.py
128 129 130 131 132 133 134 | |
start()
Bind, then receive on a new daemon thread.
Binding happens here, on the caller's thread, so an address that cannot
be bound raises what bind() raised and leaves the listener unstarted
and nothing bound. Raises RuntimeError when already serving or closed.
Source code in src/pydhcp/listener/_sync.py
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | |
wait_closed(timeout=None)
Block until the receive loop has ended; False if timeout seconds passed first.
Raises RuntimeError on the receive thread, which would wait for itself.
Source code in src/pydhcp/listener/_sync.py
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | |
AsyncDHCPClient
pydhcp.client.AsyncDHCPClient
Bases: _ClientCore, AsyncDHCPListener
DHCPClient on an event loop: the same messages, matching and backoff.
discover_offer, dora and send are coroutines taking the same keywords
as the synchronous client's. The receive tasks must be running (start() or
serve_forever()) for an exchange to hear a reply. handle() and
on_reply() run on the event loop, not on a worker thread, so on_reply
must not block. Any number of exchanges may be pending at once, each on its
own transaction and client.
Source code in src/pydhcp/client/_asyncio.py
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | |
bound_addresses
property
The addresses this listener is currently bound to.
Empty before bind() and once the sockets are closed. Asking the socket
rather than repeating the listen list is the point: binding port 0 gives
an ephemeral port that only the socket knows, which is how a test or a
tool discovers where to send.
aclose()
async
Shut down, wait for serving to end, then release every socket. Final and repeatable.
Source code in src/pydhcp/listener/_asyncio.py
350 351 352 353 354 | |
bind()
Open the sockets the specification names; does nothing once they are open.
Raises what the bind raised, leaving none open, and RuntimeError once
the listener is closed.
Source code in src/pydhcp/listener/_core.py
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | |
discover_offer(chaddr, *, timeout=2.0, retries=2, deadline=None, destination=BROADCAST_DESTINATION, port=_SERVER_PORT, xid=None, client_identifier=None, parameter_request_list=None, broadcast=True)
async
Broadcast DHCPDISCOVER and return the first usable DHCPOFFER.
timeout, deadline and what raises are as in
DHCPClient.discover_offer. Cancelling the call abandons the exchange.
Source code in src/pydhcp/client/_asyncio.py
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | |
dora(chaddr, *, timeout=2.0, retries=2, deadline=None, destination=BROADCAST_DESTINATION, port=_SERVER_PORT, xid=None, client_identifier=None, parameter_request_list=None, broadcast=True)
async
Run a full DISCOVER/OFFER/REQUEST/ACK exchange and return the DHCPACK.
Raises what DHCPClient.dora raises.
Source code in src/pydhcp/client/_asyncio.py
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | |
next_reply(timeout=None)
async
The oldest queued reply, waiting up to timeout seconds; None if none came.
Source code in src/pydhcp/client/_asyncio.py
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 | |
on_reply(msg, context)
Hook called after a BOOTREPLY is accepted and queued.
Source code in src/pydhcp/client/_core.py
417 418 | |
serve_forever()
async
Bind, then receive in the calling task until shutdown().
Raises what bind() raised, and RuntimeError when already serving or
closed. The sockets stay open on return: aclose() releases them.
Source code in src/pydhcp/listener/_asyncio.py
231 232 233 234 235 236 237 238 239 240 241 242 243 | |
shutdown()
Ask serving to end. Returns at once, from any thread and from a handler.
Nothing is closed here: the receive tasks end on the event loop's next
turn and aclose() releases the sockets. A no-op when nothing serves.
Source code in src/pydhcp/listener/_asyncio.py
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | |
start()
async
Bind, then receive in background tasks, and return once receiving.
Raises what bind() raised, and RuntimeError when already serving or
closed; nothing is left open or running in either case.
Source code in src/pydhcp/listener/_asyncio.py
217 218 219 220 221 222 223 224 225 226 227 228 229 | |
wait_closed(timeout=None)
async
Wait until serving has ended; False if timeout seconds passed first.
Source code in src/pydhcp/listener/_asyncio.py
337 338 339 340 341 342 343 344 345 346 347 348 | |
DHCPRelay
pydhcp.relay.DHCPRelay
Bases: _RelayCore, DHCPListener
RFC 1542 / RFC 2131 4.1 / RFC 3046 DHCP relay agent on a receive thread.
Forwards client requests to the configured upstream servers and their
replies back; see _RelayCore for the rules.
Source code in src/pydhcp/relay/_sync.py
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | |
AsyncDHCPServer
pydhcp.server.AsyncDHCPServer
Bases: _ServerCore, AsyncDHCPListener
A DHCP server on an event loop.
The same rules and hooks as DHCPServer; the hooks are ordinary blocking
methods and run on the one worker thread the listener hands datagrams to,
never on the loop.
Source code in src/pydhcp/server/_asyncio.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | |
bound_addresses
property
The addresses this listener is currently bound to.
Empty before bind() and once the sockets are closed. Asking the socket
rather than repeating the listen list is the point: binding port 0 gives
an ephemeral port that only the socket knows, which is how a test or a
tool discovers where to send.
aclose()
async
Shut down, wait for serving to end, then release every socket. Final and repeatable.
Source code in src/pydhcp/listener/_asyncio.py
350 351 352 353 354 | |
acquire_lease(client_id, server_id, msg, *, commit=True)
Return a lease for a client message.
This is the extension point for address pools, reservations, policy checks and custom response options. It is an ordinary method of this server, called on the server itself from the handler thread (the one worker thread on the async server), so an attribute it keeps -- the next free host, a cache -- is the server's own.
commit says what kind of call this is. False: the server is deciding
what to offer or whether to ACK (RFC 2131 s4.3.1 makes DHCPDISCOVER a
probe), so the call must not extend an existing binding or add state
that a client declining the offer would leave behind. True: the answer
is being committed. A DHCPDISCOVER makes one call with commit=False; a
DHCPREQUEST makes two, commit=False to decide and then commit=True
if it is ACKed. An override honours commit itself, including in what
it does to self.lease_backend, which is the real backend on both
calls.
The base implementation is intentionally small. A client with a record
gets it back: on commit=False as it stands, on commit=True an
offered lease committed (LeaseBackend.commit) and a bound one renewed.
Only a DHCPDISCOVER makes a record: from a client with none it holds
the address in REQUESTED_IP (or ciaddr) as an offer for
OFFER_HOLD_SECONDS on commit=False, and allocates it on
commit=True. A DHCPREQUEST from a client with no record gets None.
A message whose giaddr is outside the served network gets None:
the stock allocator has the one network to give.
Source code in src/pydhcp/server/_policy.py
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | |
bind()
Open the sockets the specification names; does nothing once they are open.
Raises what the bind raised, leaving none open, and RuntimeError once
the listener is closed.
Source code in src/pydhcp/listener/_core.py
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | |
get_inform_options(server_id, msg)
Return configuration options for DHCPINFORM responses.
DHCPINFORM does not allocate an address. Override this method when clients should receive site-specific options without touching lease allocation.
Source code in src/pydhcp/server/_policy.py
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 | |
get_lease_seconds(msg)
Lease length to grant for msg, applying this server's policy.
RFC 2131 s4.3.1 lets the server honour a client's requested lease time only "if acceptable to local policy" -- a MAY, so there has to be a policy. There was none: the requested value went straight through, and any client could hold an address for 136 years by asking for one.
RFC 2132 s3.3 also makes 0xFFFFFFFF mean infinity, not 4294967295 seconds. Taken literally it became a finite expiry in 2162, and the reply then advertised 4294967294 -- a different number than the client asked for, one second short of the sentinel.
Override this, or set the class attributes, to change the policy.
Source code in src/pydhcp/server/_policy.py
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | |
handle_decline(msg, context)
Handle DHCPDECLINE: quarantine the address it names, and release the sender's own.
RFC 2131 s4.3.3: "The server MUST mark the network address as not
available", whoever sent it. A DECLINE naming an address outside the
served network, this host's own, or another server in option 54 changes
nothing and is counted in declines_ignored; the quarantine is bounded
(MAX_DECLINED_ADDRESSES). A record is released only when it is the
sender's own, for the declined address. DECLINE_REQUIRES_LEASE marks
only an address the sender holds, as a binding or an outstanding offer.
Source code in src/pydhcp/server/_handlers.py
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | |
handle_discover(msg, context)
Handle DHCPDISCOVER by offering a lease returned from acquire_lease.
Source code in src/pydhcp/server/_handlers.py
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | |
handle_inform(msg, context)
Handle DHCPINFORM without requiring address allocation.
Source code in src/pydhcp/server/_handlers.py
427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 | |
handle_release(msg, context)
Handle DHCPRELEASE, but only for the address the client actually holds.
Source code in src/pydhcp/server/_handlers.py
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 | |
handle_request(msg, context)
Handle DHCPREQUEST by ACKing or NAKing the lease returned from acquire_lease.
RFC 2131 s4.3.2 and Table 4 tell the four shapes apart, and each is
answered from the record acquire_lease returns for the client:
- SELECTING (option 54 names this server): a lease for the address asked for is ACKed; a request this server cannot satisfy is NAKed (s3.1 step 4), never left unanswered.
- INIT-REBOOT (option 50, no option 54,
ciaddr0), RENEWING (ciaddr, unicast to this server) and REBINDING (ciaddr, broadcast): a lease for the address is ACKed, a lease for another address is NAKed, and no lease at all is silence, because the client may belong to another server on the same wire.
Source code in src/pydhcp/server/_handlers.py
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 | |
is_quarantined(ip, *, now=None)
Whether ip is out of the pool after a DHCPDECLINE.
The server asks this of every lease a hook returns, so an
acquire_lease override does not have to. now is time.monotonic()
seconds; omitted, the driver's reading is used.
Source code in src/pydhcp/server/_policy.py
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 | |
lookup_lease(client_id)
The lease this server holds for client_id, in either state, or None.
What a DHCPDECLINE, a DHCPRELEASE and a REQUEST naming another server
ask to learn what the sender holds. The default reads lease_backend;
a server that keeps its leases elsewhere overrides this one method.
Source code in src/pydhcp/server/_policy.py
439 440 441 442 443 444 445 446 | |
quarantine_address(ip, *, now=None)
Stop offering ip for DECLINE_QUARANTINE_SECONDS.
RFC 2131 4.3.3: a DHCPDECLINE says the client found the address already in use, so the server MUST NOT hand it out again. Releasing the binding alone left it first in line to be offered to the next client, which would collide with whatever is really using it.
The map holds at most MAX_DECLINED_ADDRESSES. At the bound the entries
that have run out are dropped first; if none has, a new address is
refused and counted in quarantines_refused, because evicting the
oldest would let a flood of reports push a genuine one out. An address
already held is renewed for a full quarantine.
now is time.monotonic() seconds; omitted, the driver's reading is
used, so an override that takes only ip keeps working.
Source code in src/pydhcp/server/_policy.py
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | |
release_lease(client_id, server_id, msg)
Release any lease associated with client_id; True if one went away.
Override this method when lease release needs to update an external store
or emit custom audit records. Quarantining a declined address is handled
by quarantine_address, which handle_decline calls before this.
Counting is the caller's job, not this method's, because only the caller knows why: an orderly DHCPRELEASE, a DHCPDECLINE reporting an address conflict, and a reclaim after the client chose another server are three different events that all arrive here.
Source code in src/pydhcp/server/_policy.py
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 | |
serve_forever()
async
Bind, then receive in the calling task until shutdown().
Raises what bind() raised, and RuntimeError when already serving or
closed. The sockets stay open on return: aclose() releases them.
Source code in src/pydhcp/listener/_asyncio.py
231 232 233 234 235 236 237 238 239 240 241 242 243 | |
shutdown()
Ask serving to end. Returns at once, from any thread and from a handler.
Nothing is closed here: the receive tasks end on the event loop's next
turn and aclose() releases the sockets. A no-op when nothing serves.
Source code in src/pydhcp/listener/_asyncio.py
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | |
start()
async
Bind, then receive in background tasks, and return once receiving.
Raises what bind() raised, and RuntimeError when already serving or
closed; nothing is left open or running in either case.
Source code in src/pydhcp/listener/_asyncio.py
217 218 219 220 221 222 223 224 225 226 227 228 229 | |
wait_closed(timeout=None)
async
Wait until serving has ended; False if timeout seconds passed first.
Source code in src/pydhcp/listener/_asyncio.py
337 338 339 340 341 342 343 344 345 346 347 348 | |
AsyncDHCPRelay
pydhcp.relay.AsyncDHCPRelay
Bases: _RelayCore, AsyncDHCPListener
The relay on an event loop.
The same rules as DHCPRelay. The pending-client table is unguarded, as
there: what keeps it safe is that AsyncDHCPListener runs handlers on a
single worker thread, so handle() is serialised and in arrival order.
Source code in src/pydhcp/relay/_asyncio.py
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | |
DHCPListener
pydhcp.listener.DHCPListener
Bases: _ListenerCore
Receives DHCP datagrams on a thread and hands each to handle().
serve_forever() receives on the calling thread, start() on a daemon
thread. shutdown() ends the receive loop and never blocks, so a handler
may call it; wait_closed() blocks until the loop has ended; close() is
both, then releases the sockets, and is final. The library installs no
signal handler: Ctrl-C reaches serve_forever() as KeyboardInterrupt.
Source code in src/pydhcp/listener/_sync.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | |
close()
Shut down, wait for the receive loop, then release every socket. Final.
Called on the receive thread itself (from a handler) it shuts down and returns: the loop releases the sockets as it ends. Repeatable.
Source code in src/pydhcp/listener/_sync.py
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | |
serve_forever()
Bind, then receive on the calling thread until shutdown().
Raises what bind() raised, and RuntimeError when already serving or
closed. The sockets stay open on return: close() releases them.
Source code in src/pydhcp/listener/_sync.py
91 92 93 94 95 96 97 98 99 100 101 102 | |
shutdown()
Ask the receive loop to end. Returns at once, from any thread and from a handler.
Source code in src/pydhcp/listener/_sync.py
128 129 130 131 132 133 134 | |
start()
Bind, then receive on a new daemon thread.
Binding happens here, on the caller's thread, so an address that cannot
be bound raises what bind() raised and leaves the listener unstarted
and nothing bound. Raises RuntimeError when already serving or closed.
Source code in src/pydhcp/listener/_sync.py
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | |
wait_closed(timeout=None)
Block until the receive loop has ended; False if timeout seconds passed first.
Raises RuntimeError on the receive thread, which would wait for itself.
Source code in src/pydhcp/listener/_sync.py
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | |
AsyncDHCPListener
pydhcp.listener.AsyncDHCPListener
Bases: _ListenerCore
The listener on an event loop: the receive path of DHCPListener, one task per socket.
handle() runs on a single worker thread, in arrival order, so it may block;
at most max_queued datagrams wait for it and the next is dropped and counted.
Drive it with await serve_forever() or await start(), then shutdown(),
await wait_closed() and await aclose(); async with binds on entry.
Source code in src/pydhcp/listener/_asyncio.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | |
aclose()
async
Shut down, wait for serving to end, then release every socket. Final and repeatable.
Source code in src/pydhcp/listener/_asyncio.py
350 351 352 353 354 | |
serve_forever()
async
Bind, then receive in the calling task until shutdown().
Raises what bind() raised, and RuntimeError when already serving or
closed. The sockets stay open on return: aclose() releases them.
Source code in src/pydhcp/listener/_asyncio.py
231 232 233 234 235 236 237 238 239 240 241 242 243 | |
shutdown()
Ask serving to end. Returns at once, from any thread and from a handler.
Nothing is closed here: the receive tasks end on the event loop's next
turn and aclose() releases the sockets. A no-op when nothing serves.
Source code in src/pydhcp/listener/_asyncio.py
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | |
start()
async
Bind, then receive in background tasks, and return once receiving.
Raises what bind() raised, and RuntimeError when already serving or
closed; nothing is left open or running in either case.
Source code in src/pydhcp/listener/_asyncio.py
217 218 219 220 221 222 223 224 225 226 227 228 229 | |
wait_closed(timeout=None)
async
Wait until serving has ended; False if timeout seconds passed first.
Source code in src/pydhcp/listener/_asyncio.py
337 338 339 340 341 342 343 344 345 346 347 348 | |
DHCPMetrics
Every DHCPListener (and therefore DHCPServer, DHCPClient) owns its own metrics: DHCPMetrics
instance — counters are per-instance, not global, so running multiple listeners in one process
(e.g. in tests) never cross-contaminates counts. Call .snapshot() for a plain dict[str, int].
pydhcp.listener.DHCPMetrics
Per-instance counters. Every listener/server/client/relay owns one.
The field list lives in FIELDS rather than being repeated by __init__,
reset and snapshot: three copies of the same names is how a counter ends
up incremented but absent from a snapshot, or reset everywhere but one.
Source code in src/pydhcp/_metrics.py
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | |
reset()
Set every counter to zero.
Source code in src/pydhcp/_metrics.py
136 137 138 139 | |
snapshot()
A plain dict of every counter's name and value, in FIELDS order.
Source code in src/pydhcp/_metrics.py
141 142 143 | |
pydhcp.client
pydhcp.client
The DHCPv4 client: DHCPClient on threads and AsyncDHCPClient on an event loop.
AsyncDHCPClient
Bases: _ClientCore, AsyncDHCPListener
DHCPClient on an event loop: the same messages, matching and backoff.
discover_offer, dora and send are coroutines taking the same keywords
as the synchronous client's. The receive tasks must be running (start() or
serve_forever()) for an exchange to hear a reply. handle() and
on_reply() run on the event loop, not on a worker thread, so on_reply
must not block. Any number of exchanges may be pending at once, each on its
own transaction and client.
Source code in src/pydhcp/client/_asyncio.py
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | |
discover_offer(chaddr, *, timeout=2.0, retries=2, deadline=None, destination=BROADCAST_DESTINATION, port=_SERVER_PORT, xid=None, client_identifier=None, parameter_request_list=None, broadcast=True)
async
Broadcast DHCPDISCOVER and return the first usable DHCPOFFER.
timeout, deadline and what raises are as in
DHCPClient.discover_offer. Cancelling the call abandons the exchange.
Source code in src/pydhcp/client/_asyncio.py
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | |
dora(chaddr, *, timeout=2.0, retries=2, deadline=None, destination=BROADCAST_DESTINATION, port=_SERVER_PORT, xid=None, client_identifier=None, parameter_request_list=None, broadcast=True)
async
Run a full DISCOVER/OFFER/REQUEST/ACK exchange and return the DHCPACK.
Raises what DHCPClient.dora raises.
Source code in src/pydhcp/client/_asyncio.py
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | |
next_reply(timeout=None)
async
The oldest queued reply, waiting up to timeout seconds; None if none came.
Source code in src/pydhcp/client/_asyncio.py
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 | |
DHCPClient
Bases: _ClientCore, DHCPListener
Small DHCPv4 packet client for tests and troubleshooting.
The base client builds and sends DHCP client messages, then queues matching
replies. It does not configure operating-system network interfaces. Its
receive thread must be running (start()) for an exchange to hear a reply.
Source code in src/pydhcp/client/_sync.py
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | |
discover_offer(chaddr, *, timeout=2.0, retries=2, deadline=None, destination=BROADCAST_DESTINATION, port=_SERVER_PORT, xid=None, client_identifier=None, parameter_request_list=None, broadcast=True)
Broadcast DHCPDISCOVER and return the first usable DHCPOFFER.
timeout is the initial retransmission interval, not a fixed one:
each retransmission waits about twice as long as the last, jittered, up
to RETRANSMIT_MAX_INTERVAL (RFC 2131 s4.1). With the defaults the
whole call is bounded at roughly 2+4+8 seconds rather than 3x2;
deadline bounds it outright, in seconds.
An OFFER is usable when it offers an address and names its server;
others are ignored. Raises DHCPTimeoutError when none arrives.
Source code in src/pydhcp/client/_sync.py
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | |
dora(chaddr, *, timeout=2.0, retries=2, deadline=None, destination=BROADCAST_DESTINATION, port=_SERVER_PORT, xid=None, client_identifier=None, parameter_request_list=None, broadcast=True)
Run a full DISCOVER/OFFER/REQUEST/ACK exchange and return the DHCPACK.
timeout is the initial retransmission interval for each half of the
exchange -- see discover_offer; deadline bounds the two halves
together. Raises DHCPTimeoutError when no usable OFFER or ACK arrives
(an ACK is usable when it comes from the server the REQUEST selected) and
DHCPRefusedError when the server answers the REQUEST with a DHCPNAK.
Source code in src/pydhcp/client/_sync.py
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | |
__getattr__(name)
Bind an asyncio class on first use, so importing this package does not import asyncio.
Source code in src/pydhcp/client/__init__.py
24 25 26 | |
pydhcp.capture
pktcap_plugin below holds the filter keys of a DHCP message, which
pydhcp capture --filter takes beside pktcap's own.
pydhcp.capture
DHCP for pktcap: a dissector and a plugin, and the sockets DHCP messages arrive at.
DHCPLayer
Bases: NamedTuple
The DHCP message a datagram carries, as plain values.
op is the opcode's name (BOOTREQUEST), xid the transaction id as a number,
message_type the name of option 53 (DHCPDISCOVER, UNKNOWN without one),
client_id the client identifier as colon-separated upper-case hex (option 61,
else the hardware type and address; UNKNOWN when there is neither) and message the whole message as
DHCPMessage.to_mapping(). A mapping is not hashable, so neither is the layer.
Source code in src/pydhcp/capture/_dissector.py
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | |
summary()
One line for a person: the type, the transaction id, the client, and
yiaddr and giaddr when they are not zero.
DHCPOFFER xid=1A52B52E client=01:02:00:00:99:00:02 yiaddr=10.99.0.100.
This is the text pktcap's text format shows for a frame whose innermost
layer is this one.
Source code in src/pydhcp/capture/_dissector.py
55 56 57 58 59 60 61 62 63 64 65 66 67 68 | |
asniff_dhcp(listen=None, *, per_interface=None, dissector=None)
sniff_dhcp for an event loop: an asynchronous iterator of dissected frames.
The sockets are bound when this is called. When the iterator ends, fails or is
cancelled, every reader task is cancelled and every socket closed; a loop that
stops early awaits the iterator's aclose(). It has no stop: break and
aclose(), or cancel.
Source code in src/pydhcp/capture/_source.py
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | |
capture_dissector(ports=DHCP_PORTS)
A frame dissector that reads DHCP on ports, over a copy of pktcap's registry.
The registry also declares :class:DHCPLayer and its filter keys (msg_type,
xid, client_id, chaddr, op, option.NAME), so proto=dhcp and
msg_type=DHCPOFFER compile against dissector.registry. The process-wide
registry is not changed, and whatever else is registered there is read as well.
Its stats say what could not be read.
Source code in src/pydhcp/capture/_dissector.py
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | |
dissect_dhcp(data)
Read the DHCP message data holds: its DHCPLayer, and no payload after it.
Raises pktcap.DissectError (a ValueError) for octets that are not a message;
its text is fixed and quotes none of them. Keeps the contract
pktcap.check_dissector checks.
Source code in src/pydhcp/capture/_dissector.py
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | |
pktcap_plugin(registry)
Declare :class:DHCPLayer and its filter keys in registry, then register the dissector.
The keys are op, msg_type, xid, client_id, chaddr and option.NAME_OR_CODE,
each refusing at compile time a value no message could match, and the DHCPLayer fields
as dhcp.FIELD.
A call that raises leaves registry as it found it: ValueError for a layer name or a
port that is taken.
Source code in src/pydhcp/capture/_plugin.py
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | |
register_dhcp_dissector(registry=None)
Have registry (default: pktcap's process-wide one) dissect UDP ports 67 and 68.
Nothing registers on import. ValueError, with nothing registered by this call,
when a port already has a dissector (pktcap's rule).
Source code in src/pydhcp/capture/_dissector.py
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | |
sniff_dhcp(listen=None, *, per_interface=None, stop=None, dissector=None)
The DHCP messages that reach listen, as pktcap's dissected frames, as they arrive.
listen is netimps' listen specification (netimps.parse_listen) read with the
default ports 67 and 68 and IPv4: None is every address, "127.0.0.1:6767" one
socket, an adapter name or a MAC the sockets of that adapter. The sockets are bound
when this is called, and a part of the specification that cannot be bound is an
error before any is opened (ValueError for an adapter that matches nothing,
OSError for a port taken). per_interface=True binds one socket for each
address of the host instead of a wildcard; on Linux such sockets hear no broadcast.
The iterator closes every socket when it ends, fails, is closed or is dropped.
stop() is called between datagrams, and at least once a second on a quiet socket;
true ends the iteration. dissector is a pktcap.FrameDissector: omitted, it is
capture_dissector() reading DHCP on 67, 68 and the ports the sockets are bound to,
so the last layer of a frame that holds a message is a DHCPLayer. The IP header
of a frame is made up and no other host's traffic is seen: see pktcap's sniff_udp.
ImportError naming the pktcap extra when it is not installed.
Source code in src/pydhcp/capture/_source.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | |
pydhcp.packet
pydhcp.packet
DHCPFlags
Bases: IntFlag
The 16-bit flags field of the header (RFC 2131 s2).
Only the broadcast bit is assigned; the other fifteen are reserved and a
decoded value keeps them, so a relay forwards the field it received. Test
the bit with DHCPMessage.broadcast or flags & DHCPFlags.BROADCAST, not
by comparing the whole value.
Source code in src/pydhcp/packet/_enums.py
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | |
BROADCAST = 1 << 15
class-attribute
instance-attribute
Set by client that cant listen to unicast response as it doesnt have an ip yet
label()
UNICAST or BROADCAST, then |0x.... for the reserved bits set.
Source code in src/pydhcp/packet/_enums.py
47 48 49 50 51 52 | |
DHCPMessage
dataclass
Bases: _MessageDisplay
A DHCPv4 message (RFC 2131 s2): the fixed BOOTP header, then options.
The fields, decode/encode, to_mapping/from_mapping, client_id and
the display helpers are inherited from the layers in pydhcp.packet; the
dataclass __init__, __repr__ and __eq__ are the base layer's, and
report this class.
Source code in src/pydhcp/packet/_message.py
12 13 14 15 16 17 18 19 | |
DHCPMessageType
Bases: DHCPOptionType, IntEnum
DHCP message types
Source code in src/pydhcp/options/_codecs/_message_type.py
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | |
DHCPACK = 5
class-attribute
instance-attribute
Server to client with configuration parameters, including committed network address.
DHCPDECLINE = 4
class-attribute
instance-attribute
Client to server indicating network address is already in use.
DHCPDISCOVER = 1
class-attribute
instance-attribute
Client broadcast to locate available servers.
DHCPFORCERENEW = 9
class-attribute
instance-attribute
Forces the client to the RENEW state.
DHCPINFORM = 8
class-attribute
instance-attribute
Client to server, asking only for local configuration parameters; client already has externally configured network address.
DHCPLEASEACTIVE = 13
class-attribute
instance-attribute
The DHCPLEASEACTIVE response to a DHCPLEASEQUERY message allows the relay agent to determine the IP endpoint location and the remaining duration of the IP address lease.
DHCPLEASEQUERY = 10
class-attribute
instance-attribute
The DHCPLEASEQUERY message is a new DHCP message type transmitted from a DHCP relay agent to a DHCP server. A DHCPLEASEQUERY-aware relay agent sends the DHCPLEASEQUERY message when it needs to know the location of an IP endpoint. The DHCPLEASEQUERY-aware DHCP server replies with a DHCPLEASEUNASSIGNED, DHCPLEASEACTIVE, or DHCPLEASEUNKNOWN message.
DHCPLEASEUNASSIGNED = 11
class-attribute
instance-attribute
The DHCPLEASEUNASSIGNED is similar to a DHCPLEASEACTIVE message, but indicates that there is no currently active lease on the resultant IP address but that this DHCP server is authoritative for this IP address.
DHCPLEASEUNKNOWN = 12
class-attribute
instance-attribute
The DHCPLEASEUNKNOWN message indicates that the DHCP server has no knowledge of the information specified in the query (e.g., IP address, MAC address, or Client-identifier option).
DHCPNAK = 6
class-attribute
instance-attribute
Server to client indicating client's notion of network address is incorrect (e.g., client has moved to new subnet) or client's lease as expired
DHCPOFFER = 2
class-attribute
instance-attribute
Server to client in response to DHCPDISCOVER with offer of configuration parameters.
DHCPRELEASE = 7
class-attribute
instance-attribute
Client to server relinquishing network address and cancelling remaining lease.
DHCPREQUEST = 3
class-attribute
instance-attribute
Client message to servers either (a) requesting offered parameters from one server and implicitly declining offers from all others, (b) confirming correctness of previously allocated address after, e.g., system reboot, or (c) extending the lease on a particular network address.
label()
The member's name, or TYPE_<n> for a number that has none.
Source code in src/pydhcp/options/_codecs/_message_type.py
69 70 71 | |
DHCPOpcode
Bases: IntEnum
Specifies if the message originates from a server or client
Source code in src/pydhcp/packet/_enums.py
20 21 22 23 24 25 26 | |
BOOTREPLY = 2
class-attribute
instance-attribute
DHCP message sent from a server to a client.
BOOTREQUEST = 1
class-attribute
instance-attribute
DHCP message sent from a client to a server.
HardwareAddressType
Bases: IntEnum
IANA ARP hardware types, as used by the BOOTP htype field.
Values 0-37 of the IANA "Number Hardware Type (hrd)" registry that are in
use for DHCP; anything else in an octet becomes an unnamed pseudo-member
rather than being rewritten (see _missing_).
Defined here rather than in packet/_enums.py (which re-exports it, and is
where the rest of the message-header enums live) because it is what closes
the options -> packet -> options import cycle: ClientIdentifier
names its leading type octet with this enum, and reaching packet._enums
for it meant a function-local import re-executed on every __repr__. This
module imports nothing from the package.
Source code in src/pydhcp/_network/__init__.py
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | |
format_address(address)
address as text: colon-separated hex for Ethernet, else its repr.
Source code in src/pydhcp/_network/__init__.py
108 109 110 111 112 | |
label()
Name of this hardware type, or HTYPE_<n> when it has none.
Source code in src/pydhcp/_network/__init__.py
99 100 101 | |
pydhcp.packet.structured
A message as a mapping in one of four text formats; DHCPMessage.to_text and
from_text are these two around to_mapping and from_mapping.
pydhcp.packet.structured
dumps(data, format)
The text of a mapping in a structured format, with json.dumps's meaning.
format is json, yaml, toml or ini in any letter case (ValueError
otherwise). JSON is written by the standard library, indented; the others by
pktcap.dumps_record, so they need the pktcap extra (ImportError naming
pip install "pydhcp[pktcap]") and yaml and toml the format library of pktcap
(ImportError naming pip install "pktcap[yaml]" or "pktcap[toml]"). A value
the format cannot hold is a TypeError or ValueError from pktcap that does not
quote the record, and so is a message whose options TOML would write in another
order (an option held as a table before a plain one). The INI form is [record]
with the header fields and one section for options, each value one line of JSON,
and keeps the case of every name.
Source code in src/pydhcp/packet/structured.py
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | |
loads(text, format)
The mapping a structured document holds, with json.loads's meaning.
text is the content, never a file name. format is json, yaml, toml or
ini in any letter case (ValueError otherwise). JSON is read by the standard
library; the others by pktcap.loads_record, so they need the pktcap extra
(ImportError naming pip install "pydhcp[pktcap]"), and yaml and toml the
format library of pktcap (ImportError naming pip install "pktcap[yaml]" or
"pktcap[toml]"). A document pktcap does not take as one record is a ValueError
(pktcap.RecordFormatError) that never quotes the text. An INI document is the
sections [record] and [options] that dumps writes, or the [message] and
[options] a message was written with before. A document that is not a mapping is
a DHCPDecodeError.
Source code in src/pydhcp/packet/structured.py
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | |
Configuration files
The commands read the root's named settings file with
load_config, which is not importable from a public module; its failures are
DHCPConfigError.
pydhcp._config.load_config(source, format=None)
Read one configuration file into a mapping of sections.
The format is format (json, toml, yaml or ini, any case) or else the
file name's ending (.json, .toml, .yaml, .yml, .ini, .cfg); any
other ending is refused. The reader is duho.config: its INI puts the keys of
[DEFAULT] at the top level, and a TOML file before Python 3.11 and a YAML
file need its config and yaml extras.
A file that cannot be read raises the OSError. A document that does not
parse, whose top level is not a mapping, whose format cannot be told, or
whose reader is not installed raises DHCPConfigError with the path and the
position when duho.config gave them. Without the cli extra, which
installs duho, the ImportError names it.
Source code in src/pydhcp/_config.py
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | |
pydhcp.exceptions
pydhcp.exceptions
Every exception the package raises on its own account.
DHCPError is the one base: a caller who wants "anything pydhcp reported"
catches it. Each class also inherits the builtin a caller would already catch
for that kind of failure, so an except ValueError keeps working.
A caller's own mistake, such as a wrong argument type or a call made out of
order, is not here: it raises plain ValueError or TypeError.
DHCPConfigError
Bases: DHCPError, ValueError
A configuration file that cannot be used.
Raised for a document that does not parse, whose top level is not a
mapping, that names a section or key the command does not have, or whose
format cannot be told. path is the file as it was named (<stdin> for
standard input, None when unknown), lineno and colno are 1-based and
None when the parser gave none, and msg is the problem in the words of
this package. The message, the attributes and the exception chain carry no
text from the document, which may hold secrets. Also a ValueError.
str() is one line: path:line:col: msg.
Source code in src/pydhcp/exceptions.py
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | |
DHCPDecodeError
Bases: DHCPError, ValueError
Octets that are not the message, option or name they were read as.
Raised by every decoder for a truncated, oversized, looping or otherwise
malformed input. Also a ValueError.
Source code in src/pydhcp/exceptions.py
30 31 32 33 34 35 | |
DHCPError
Bases: Exception
The base of every exception pydhcp raises on its own account.
Source code in src/pydhcp/exceptions.py
26 27 | |
DHCPRefusedError
Bases: DHCPError
The server answered a DHCPREQUEST with a DHCPNAK.
The client's configuration process starts over (RFC 2131 section 3.1), so the
exchange ends at once instead of retransmitting. nak is the DHCPNAK
message; its DHCP_MESSAGE option, when present, says why.
Source code in src/pydhcp/exceptions.py
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | |
DHCPTimeoutError
Bases: DHCPError, TimeoutError
A client exchange ran out of time.
Raised by DHCPClient and AsyncDHCPClient when the retransmissions, or the
deadline of the call, ran out before an acceptable DHCPOFFER or DHCPACK
arrived. Also a TimeoutError.
Source code in src/pydhcp/exceptions.py
93 94 95 96 97 98 99 | |
DHCPValueError
Bases: DHCPError, ValueError
A value an option codec or message field cannot represent.
Raised when a constructor rejects what it was given: an entry past one
octet's length, an empty list where the RFC requires an entry, a prefix
past 32. Also a ValueError.
Source code in src/pydhcp/exceptions.py
38 39 40 41 42 43 44 | |
NoClientIdentityError
Bases: DHCPError, ValueError
A message carries nothing that identifies its client.
Neither a client identifier option nor a hardware address. Also a
ValueError; a server drops the message rather than failing.
Source code in src/pydhcp/exceptions.py
85 86 87 88 89 90 | |
SocketAddress
pydhcp.SocketAddress
Bases: _SocketAddress
Source code in src/pydhcp/_network/__init__.py
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | |
from_socket(sock)
classmethod
The local address sock is bound to; asks the socket (getsockname()).
Source code in src/pydhcp/_network/__init__.py
130 131 132 133 134 | |
parse(text)
classmethod
Build from "host:port", the text str() produces.
Raises DHCPValueError when the text is not an IPv4 address and a port
in 0-65535, and TypeError when it is not text.
Source code in src/pydhcp/_network/__init__.py
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | |
to_tuple()
The plain (host, port) pair the standard socket calls take.
Source code in src/pydhcp/_network/__init__.py
136 137 138 | |
try_parse(text, default=None)
classmethod
parse, or default for text that does not parse; still TypeError for a non-text.
Source code in src/pydhcp/_network/__init__.py
159 160 161 162 163 164 165 | |
NetworkInterface
pydhcp.NetworkInterface
Bases: NamedTuple
Source code in src/pydhcp/_network/__init__.py
174 175 176 177 178 179 180 181 182 183 184 185 | |
pydhcp.lease
pydhcp.lease
Lease storage: the DHCPLease value, the LeaseBackend contract and its two stores.
DHCPLease
One address held by one client: a value, built once and never changed.
ip is the address: never None, and never 0.0.0.0 unless the lease is
built with strict=False, for a reservation that has no address yet; whoever
takes such a lease checks it with validate(). expires is the
instant the lease ends, a timezone-aware datetime held in UTC, or None
for a lease that never ends; a naive datetime raises DHCPValueError and
any other type TypeError. options is the configuration the lease carries:
it is copied in, so the bag the caller holds is not the lease's, and it is
read-only; lease.options.copy() is an ordinary bag to change. Two leases
with the same address, expiry, option payloads and state are equal and hash
equal.
offered is the state: True for an address held for a client that has been
offered it and has not yet accepted (expires is then the end of the hold),
False, the default, for a binding the client has accepted.
siaddr, sname and file are the BOOTP header fields a reply to the
client carries (the next server, its name and the boot file, RFC 2131 Table
3); unset, the reply's are blank. They take part in equality and hash.
Source code in src/pydhcp/lease/_value.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | |
from_mapping(data, *, codemap=None, strict=True)
classmethod
Build a lease from a mapping in the shape to_mapping produces.
Only ip is required, and with strict=False not even that: it is then
0.0.0.0 when left out, for validate() to catch. expires left out or
null is a lease that never ends, offered defaults to False, the boot
fields to blank and options to none. expires is ISO 8601 text with an
offset (Z included) or an aware datetime; sname and file are text,
null or {"hex": ...}; options is read by DHCPOptions.from_mapping
with codemap. Each value is then checked as DHCPLease(...) checks it.
Other keys are ignored.
Raises:
| Type | Description |
|---|---|
TypeError
|
a field has the wrong type. |
ValueError
|
|
Source code in src/pydhcp/lease/_value.py
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | |
from_text(text, format, *, codemap=None, strict=True)
classmethod
pydhcp.packet.structured.loads then from_mapping, with its errors.
Source code in src/pydhcp/lease/_value.py
214 215 216 217 218 219 220 221 222 223 224 225 226 | |
replace(*, ip=_MISSING, expires=_MISSING, options=_MISSING, offered=_MISSING, siaddr=_MISSING, sname=_MISSING, file=_MISSING, strict=True)
A new lease with the given fields changed and the others carried over.
An omitted field keeps this lease's value, options as the same
read-only object; a given one is checked as DHCPLease(...) checks it,
so expires=None is a lease that never ends. strict applies to a new
ip: an address carried over was accepted already. This lease is not
changed.
Source code in src/pydhcp/lease/_value.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | |
to_mapping()
The lease as plain data: ip, expires, offered, the boot fields, options.
expires is ISO 8601 text in UTC, and is left out for a lease that never
ends (TOML has no null); siaddr, sname and file are written only
when set, sname and file as text or, when not UTF-8, {"hex": ...};
options is DHCPOptions.to_mapping's form.
Source code in src/pydhcp/lease/_value.py
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | |
to_text(format)
The lease as a document: "json", "yaml", "toml" or "ini".
to_mapping written out by pydhcp.packet.structured.dumps.
Source code in src/pydhcp/lease/_value.py
207 208 209 210 211 212 | |
validate()
This lease, or DHCPValueError when it has no address to give.
A lease built with strict=False may hold 0.0.0.0; call this before
using one as a binding. A strict lease always passes.
Source code in src/pydhcp/lease/_value.py
106 107 108 109 110 111 112 113 114 | |
FileLeaseBackend
Bases: InMemoryLeaseBackend
Leases persisted to JSON.
Every mutation writes the whole file by default, which is O(store) each
time. SAVE_INTERVAL_SECONDS above zero coalesces instead: the file is
rewritten at most that often. A change after a quiet interval is written at
once; one that comes sooner is written by a daemon timer thread at the end of
the interval, so a change reaches the disk within SAVE_INTERVAL_SECONDS of
being made and no later. flush() and close() write at once and cancel the
timer.
Off by default deliberately. Coalescing trades a property the operator
cannot see going wrong -- up to an interval of leases lost on a crash -- for
one they can already measure and which MAX_LEASES already bounds. A
default that silently gives up durability for throughput is the wrong way
round; a deployment that wants the trade can ask for it.
Source code in src/pydhcp/lease/_file.py
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 | |
close()
Flush before going away, so a clean shutdown loses nothing.
Source code in src/pydhcp/lease/_file.py
88 89 90 | |
flush()
Write if anything is pending. Safe to call when nothing is.
Source code in src/pydhcp/lease/_file.py
82 83 84 85 86 | |
open()
Read the lease file, once. A missing file is an empty store.
The file is read whole or not at all: a bad entry, a duplicated address
or more live leases than MAX_LEASES leaves the store empty and moves the
file aside as <path>.corrupt (.corrupt.1, .corrupt.2, ... when that
name is taken). Called by the first lease operation if the caller has
not, and by with.
Source code in src/pydhcp/lease/_file.py
67 68 69 70 71 72 73 74 75 76 77 78 79 80 | |
InMemoryLeaseBackend
Leases in a dict, guarded by a re-entrant lock.
The lock makes each operation atomic against the others: a server started
with start() handles packets on a background thread, the async server on a
worker thread, and one backend can be shared by several of them. It does
not make a caller's compound operation atomic -- "is this address free,
and if so allocate it" is two calls, and two threads can still interleave
across them. Hold self._lock around such a sequence if that matters.
The store is bounded by MAX_LEASES. Nothing about a DHCP client is
authenticated, so a flood of forged client identifiers is otherwise an
unbounded allocation -- and, for FileLeaseBackend, a whole-file rewrite
per forged identity, which is quadratic.
Source code in src/pydhcp/lease/_store.py
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | |
lookup_by_ip(ip)
Return the client currently holding ip, offered or bound, if any.
Optional backend extension, not part of the LeaseBackend Protocol: a
backend that does not provide it simply skips the allocator's
already-in-use check. Answered from an index, so the cost does not grow
with the number of leases.
Source code in src/pydhcp/lease/_store.py
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | |
LeaseBackend
Bases: Protocol
Where leases live. ttl is seconds, or math.inf for no expiry (a lease
whose expires is None).
A client's record is in one of two states, told apart by DHCPLease.offered.
Offered: the address is held for that client for hold_seconds after a
DHCPDISCOVER, and expires is the end of the hold. Bound: the client
accepted it, and expires is the end of the lease. An offer that is not
committed in time is an expired record: lookup returns None for it and
the address is free for another client. Every method is atomic against the
others, and each treats a record whose expires has passed as absent.
ttl is typed float rather than int because math.inf is a float and
the implementations have always accepted it. An int is still accepted:
every int is a float to the type system.
Source code in src/pydhcp/lease/_store.py
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | |
allocate(client_id, ip, ttl, options=None)
An offer and its commit in one call: a bound lease for ttl.
Replaces whatever record client_id has. None when another client
holds ip, or when the store is full and client_id is new.
Source code in src/pydhcp/lease/_store.py
38 39 40 41 42 43 44 45 46 47 48 49 50 | |
commit(client_id, ttl)
Turn the client's offered lease into a bound one lasting ttl.
None when the client has no offered lease (none, expired, or already
bound).
Source code in src/pydhcp/lease/_store.py
69 70 71 72 73 74 75 | |
lookup(client_id)
The client's lease, offered or bound, or None.
Source code in src/pydhcp/lease/_store.py
77 78 79 | |
offer(client_id, ip, hold_seconds, options=None)
Hold ip for client_id for hold_seconds and return the offered lease.
None when another client holds ip (offered or bound), when the store
is full and client_id is new, or when client_id holds a bound lease
on another address (an offer never replaces a binding). A client that
holds a bound lease on ip is returned that lease unchanged. A client
with an outstanding offer has it replaced.
Source code in src/pydhcp/lease/_store.py
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | |
release(client_id)
Drop the client's record, in either state; whether there was one.
Source code in src/pydhcp/lease/_store.py
81 82 83 | |
renew(client_id, ttl)
Extend a bound lease to ttl from now; None for no lease or an offer.
Source code in src/pydhcp/lease/_store.py
85 86 87 | |