Net::D...:Packet(3pm)

πŸ“¦
version 0.696 Β· 4 versions
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

πŸ’– Net::DHCP::Packet β€” the Perl DHCP packet girlies πŸ’–

Ok so bestie, welcome to Net::DHCP::Packet(3pm) β€” the User Contributed Perl Documentation page that's about to become your whole personality. Buckle up πŸŽ€


✨ NAME ✨

Net::DHCP::Packet β€” object methods to create a DHCP packet. That's it, that's the vibe. It's giving "I make DHCP packets and I do it flawlessly." πŸ’…

🌸 VERSION 🌸

version 0.696 β€” noted, memorized, immortalized ✨

πŸ¦‹ SYNOPSIS πŸ¦‹

use Net::DHCP::Packet;

my $p = Net::DHCP::Packet->new(
     'Chaddr' => '000BCDEF',
     'Xid' => 0x9F0FD,
     'Ciaddr' => '0.0.0.0',
     'Siaddr' => '0.0.0.0',
     'Hops' => 0);

Look at her. Iconic. No notes. πŸ‘‘

πŸ’œ DESCRIPTION πŸ’œ

She represents a DHCP packet, exactly as specified in RFC 1533 and RFC 2132. Literally just a whole DHCP packet in object form, living her best life. 🫢

🧚 CONSTRUCTOR 🧚

This module only provides the basic constructor β€” she's lowkey minimal like that. If you want the "easy" constructors, you go use the Net::DHCP::Session module instead, bestie. That's where the easy ones live.

new( )

new( BUFFER )

new( ARG => VALUE, ARG => VALUE... )

Creates a Net::DHCP::Packet object, which you can use to send or receive DHCP network packets. πŸŽ€ BOOTP is not supported β€” not now, not ever, don't even ask.

With no argument at all, a default empty packet gets created:

$packet = Net::DHCP::Packet();

A BUFFER argument gets interpreted as a binary buffer β€” like the kind the socket recv() function hands you. And if the packet is malformed? A fatal error is issued. Like, she will simply not tolerate a messy malformed packet. 😭

use IO::Socket::INET;
use Net::DHCP::Packet;

$sock = IO::Socket::INET->new(LocalPort => 67, Proto => "udp", Broadcast => 1)
        or die "socket: $@";

while ($sock->recv($newmsg, 1024)) {
    $packet = Net::DHCP::Packet->new($newmsg);
    print $packet->toString();
}

To create a fresh new packet, new() takes arguments as key-value pairs:

ARGUMENT   FIELD      OCTETS       DESCRIPTION
--------   -----      ------       -----------

Op         op            1  Message op code / message type.
                            1 = BOOTREQUEST, 2 = BOOTREPLY
Htype      htype         1  Hardware address type, see ARP section in "Assigned
                            Numbers" RFC; e.g., '1' = 10mb ethernet.
Hlen       hlen          1  Hardware address length (e.g.  '6' for 10mb
                            ethernet).
Hops       hops          1  Client sets to zero, optionally used by relay agents
                            when booting via a relay agent.
Xid        xid           4  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.
Secs       secs          2  Filled in by client, seconds elapsed since client
                            began address acquisition or renewal process.
Flags      flags         2  Flags (see figure 2).
Ciaddr     ciaddr        4  Client IP address; only filled in if client is in
                            BOUND, RENEW or REBINDING state and can respond
                            to ARP requests.
Yiaddr     yiaddr        4  'your' (client) IP address.
Siaddr     siaddr        4  IP address of next server to use in bootstrap;
                            returned in DHCPOFFER, DHCPACK by server.
Giaddr     giaddr        4  Relay agent IP address, used in booting via a
                            relay agent.
Chaddr     chaddr       16  Client hardware address.
Sname      sname        64  Optional server host name, null terminated string.
File       file        128  Boot file name, null terminated string; "generic"
                            name or null in DHCPDISCOVER, fully qualified
                            directory-path name in DHCPOFFER.
IsDhcp     isDhcp        4  Controls whether the packet is BOOTP or DHCP.
                            DHCP conatains the "magic cookie" of 4 bytes.
                            0x63 0x82 0x53 0x63.
DHO_*code                   Optional parameters field.  See the options
                            documents for a list of defined options.
                            See Net::DHCP::Constants.
Padding    padding       *  Optional padding at the end of the packet

See below methods for the values and the syntax breakdown β€” they're all down there waiting for you 🫢

Note: DHCP options are created in the same order as the key-value pairs. Order matters, bestie. She's not gonna alphabetize your options for you πŸ’…

πŸ”₯ METHODS πŸ”₯

πŸŽ€ ATTRIBUTE METHODS πŸŽ€

comment( [STRING] )

Sets or gets the comment attribute. It's object meta-data only β€” pure vibes, no wire format. πŸ“

op( [BYTE] )

Sets/gets the BOOTP opcode.

Normal values are:

BOOTREQUEST()
BOOTREPLY()

htype( [BYTE] )

Sets/gets the hardware address type.

Common value is HTYPE_ETHER() (1) = ethernet. Classic. Ethernet is the main character here tbh ⭐

hlen ( [BYTE] )

Sets/gets the hardware address length. Value must be between 0 and 16.

For most NIC's, the MAC address has 6 bytes. Six. Not five. Not seven. Six. 😌

hops ( [BYTE] )

Sets/gets the number of hops.

This field is incremented by each encountered DHCP relay agent. Every relay agent that touches it adds one, like a little counter of how many hands the packet passed through πŸ¦‹

xid ( [INTEGER] )

Sets/gets the 32 bits transaction id.

This field should be a random value set by the DHCP client. Randomness is the moment, ok? 🎲

secs ( [SHORT] )

Sets/gets the 16 bits elapsed boot time in seconds. ⏱️

flags ( [SHORT] )

Sets/gets the 16 bits flags.

0x8000 = Broadcast reply requested.

ciaddr ( [STRING] )

Sets/gets the client IP address.

IP address is only accepted as a string like '10.24.50.3'.

Note: IP address is internally stored as a 4 bytes binary string. See "Special methods" below. Don't come at her with binary, she's already got it handled πŸ”₯

yiaddr ( [STRING] )

Sets/gets the your IP address.

IP address is only accepted as a string like '10.24.50.3'.

Note: IP address is internally stored as a 4 bytes binary string. See "Special methods" below.

siaddr ( [STRING] )

Sets/gets the next server IP address.

IP address is only accepted as a string like '10.24.50.3'.

Note: IP address is internally stored as a 4 bytes binary string. See "Special methods" below.

giaddr ( [STRING] )

Sets/gets the relay agent IP address.

IP address is only accepted as a string like '10.24.50.3'.

Note: IP address is internally stored as a 4 bytes binary string. See "Special methods" below.

chaddr ( [STRING] )

Sets/gets the client hardware address. Its length is given by the hlen attribute β€” the two are literally linked, they're besties.

Value is formatted as an Hexadecimal string representation.

Example: "0010A706DFFF" for 6 bytes mac address.
Note : internal format is packed bytes string. See "Special methods" below. πŸ’…

sname ( [STRING] )

Sets/gets the "server host name". Maximum size is 63 bytes. If greater, a warning is issued. She will let you know, loudly, but she will not crash on you 🫢

file ( [STRING] )

Sets/gets the "boot file name". Maximum size is 127 bytes. If greater, a warning is issued. Same energy, different field πŸŽ€

isDhcp ( [BOOLEAN] )

Sets/gets the DHCP cookie. Returns whether the cookie is valid or not β€” hence whether the packet is DHCP or BOOTP.

Default value is 1, valid DHCP cookie. Fresh out the box she's DHCP ✨

padding ( [BYTES] )

Sets/gets the optional padding at the end of the DHCP packet, i.e. after DHCP options. It's the little bow on top of the packet 🎁

🌈 DHCP OPTIONS METHODS 🌈

This section describes how to read or set DHCP options. Methods come in two flavours:

  1. Text format with automatic type conversion ✨
  2. Raw binary format πŸ’€

The standard way of accessing options is through automatic type conversion, described in the "DHCP OPTION TYPES" section. Only a subset of types is supported β€” mainly those defined in rfc 2132. Not all types made the cut, sorry not sorry.

Raw binary functions are provided for pure performance optimization, and for unsupported types manipulation. Speed and edge cases, the two reasons to do anything tbh πŸ”₯

addOptionValue ( CODE, VALUE )

Adds a DHCP option field. Common code values are listed in Net::DHCP::Constants DHO_*.

Values are automatically converted according to their data types, depending on their format as defined by RFC 2132. Please see "DHCP OPTION TYPES" for supported options and corresponding formats.

If you need access to the raw binary values, please use addOptionRaw().

$pac = Net::DHCP::Packet->new();
$pac->addOption(DHO_DHCP_MESSAGE_TYPE(), DHCPINFORM());
$pac->addOption(DHO_NAME_SERVERS(), "10.0.0.1", "10.0.0.2"));

addSubOptionValue ( CODE, SUBCODE, VALUE )

Adds a DHCP sub-option field. Common code values are listed in Net::DHCP::Constants SUBOPTION_*.

Values are automatically converted according to their data types, depending on their format as defined by RFC 2132. Please see "DHCP OPTION TYPES" for supported options and corresponding formats.

If you need access to the raw binary values, please use addSubOptionRaw().

$pac = Net::DHCP::Packet->new();
# FIXME update exampls
$pac->addSubOption(DHO_DHCP_MESSAGE_TYPE(), DHCPINFORM());
$pac->addSubOption(DHO_NAME_SERVERS(), "10.0.0.1", "10.0.0.2"));

getOptionValue ( CODE )

Returns the value of a DHCP option.

Automatic type conversion is done according to their data types, as defined in RFC 2132. Please see "DHCP OPTION TYPES" for supported options and corresponding formats.

If you need access to the raw binary values, please use getOptionRaw().

Return value is either a string or an array, depending on the context. She's flexible like that πŸ’…

$ip  = $pac->getOptionValue(DHO_SUBNET_MASK());
$ips = $pac->getOptionValue(DHO_NAME_SERVERS());

addOptionRaw ( CODE, VALUE )

Adds a DHCP OPTION provided in packed binary format. Please see corresponding RFC for manual type conversion β€” yes, manual, you're on your own for the conversion, bestie 😭

addSubOptionRaw ( CODE, SUBCODE, VALUE )

Adds a DHCP SUB-OPTION provided in packed binary format. Please see corresponding RFC for manual type conversion.

getOptionRaw ( CODE )

Gets a DHCP OPTION provided in packed binary format. Please see corresponding RFC for manual type conversion.

getSubOptionRaw ( CODE, SUBCODE )

Gets a DHCP SUB-OPTION provided in packed binary format. Please see corresponding RFC for manual type conversion.

getSubOptionValue ()

This is an empty stub for now. She's a work in progress, an icon in progress πŸŽ€

removeSubOption ()

This is an empty stub for now. Also a work in progress. Also an icon.

removeOption ( CODE )

Remove option from option list. Simple as that. Bye bye option πŸ‘‹

encodeRelayAgent ()

These are half baked, but will encode the relay agent options in the future. Half baked but full of potential 🧁

decodeRelayAgent ()

These are half baked, but will decode the relay agent options in the future. Same energy, decoding edition ✨

unpackRelayAgent ( HASH )

returns a human readable 'relay agent options', not to be confused with decodeRelayAgent β€” they are different, ok? Don't mix them up, iykyk πŸ™ˆ

I packcsr( ARRAYREF )

returns the packed Classless Static Route option built from a list of CIDR style address/mask combos. Address + mask combos β†’ one packed option. Slay πŸ¦‹

unpackcsr

Not implemented, currently croaks. She's just not ready yet, give her time πŸ’€

🚫 addOption ( CODE, VALUE ) 🚫

Gone, bestie. Removed as of version 0.60. Please use addOptionRaw() instead. πŸ’…

🚫 getOption ( CODE ) 🚫

Also gone. Removed as of version 0.60. Please use getOptionRaw() instead. 🫢


πŸ’Ύ DHCP OPTIONS TYPES πŸ’Ύ

Okay so this section is all about the supported option types (cf. RFC 2132). For unsupported data types, please use getOptionRaw() and addOptionRaw to manipulate binary format directly. 🧚

πŸ“¨ dhcp message type πŸ“¨

Only supported for the DHO_DHCP_MESSAGE_TYPE (053) option. Converts an integer to a single byte. ✨

Option code for 'dhcp message' format:

(053) DHO_DHCP_MESSAGE_TYPE

Example:

$pac->addOptionValue(DHO_DHCP_MESSAGE_TYPE(), DHCPINFORM());

🧡 string 🧡

Pure string attribute, no type conversion. Lowkey simple, highkey useful. πŸ’–

Option codes for 'string' format:

(012) DHO_HOST_NAME
(014) DHO_MERIT_DUMP
(015) DHO_DOMAIN_NAME
(017) DHO_ROOT_PATH
(018) DHO_EXTENSIONS_PATH
(047) DHO_NETBIOS_SCOPE
(056) DHO_DHCP_MESSAGE
(060) DHO_VENDOR_CLASS_IDENTIFIER
(062) DHO_NWIP_DOMAIN_NAME
(064) DHO_NIS_DOMAIN
(065) DHO_NIS_SERVER
(066) DHO_TFTP_SERVER
(067) DHO_BOOTFILE
(086) DHO_NDS_TREE_NAME
(098) DHO_USER_AUTHENTICATION_PROTOCOL

Example:

$pac->addOptionValue(DHO_TFTP_SERVER(), "foobar");

🌐 single ip address 🌐

Exactly one IP address, in dotted numerical format '192.168.1.1'. One and done, no cap. ✨

Option codes for 'single ip address' format:

(001) DHO_SUBNET_MASK
(016) DHO_SWAP_SERVER
(028) DHO_BROADCAST_ADDRESS
(032) DHO_ROUTER_SOLICITATION_ADDRESS
(050) DHO_DHCP_REQUESTED_ADDRESS
(054) DHO_DHCP_SERVER_IDENTIFIER
(118) DHO_SUBNET_SELECTION

Example:

$pac->addOptionValue(DHO_SUBNET_MASK(), "255.255.255.0");

🌈 multiple ip addresses 🌈

Any number of IP addresses, in dotted numerical format '192.168.1.1'. Empty value allowed. It's giving flexible friend energy. πŸ¦‹

Option codes for 'multiple ip addresses' format:

(003) DHO_ROUTERS
(004) DHO_TIME_SERVERS
(005) DHO_NAME_SERVERS
(006) DHO_DOMAIN_NAME_SERVERS
(007) DHO_LOG_SERVERS
(008) DHO_COOKIE_SERVERS
(009) DHO_LPR_SERVERS
(010) DHO_IMPRESS_SERVERS
(011) DHO_RESOURCE_LOCATION_SERVERS
(041) DHO_NIS_SERVERS
(042) DHO_NTP_SERVERS
(044) DHO_NETBIOS_NAME_SERVERS
(045) DHO_NETBIOS_DD_SERVER
(048) DHO_FONT_SERVERS
(049) DHO_X_DISPLAY_MANAGER
(068) DHO_MOBILE_IP_HOME_AGENT
(069) DHO_SMTP_SERVER
(070) DHO_POP3_SERVER
(071) DHO_NNTP_SERVER
(072) DHO_WWW_SERVER
(073) DHO_FINGER_SERVER
(074) DHO_IRC_SERVER
(075) DHO_STREETTALK_SERVER
(076) DHO_STDA_SERVER
(085) DHO_NDS_SERVERS

Example:

$pac->addOptionValue(DHO_NAME_SERVERS(), "10.0.0.11 192.168.1.10");

πŸŽ€ pairs of ip addresses πŸŽ€

Even number of IP addresses, in dotted numerical format '192.168.1.1'. Empty value allowed. Matchy-matchy IPs only, bestie. πŸ’…

Option codes for 'pairs of ip address' format:

(021) DHO_POLICY_FILTER
(033) DHO_STATIC_ROUTES

Example:

$pac->addOptionValue(DHO_STATIC_ROUTES(), "10.0.0.1 192.168.1.254");

πŸ”’ byte, short and integer πŸ”’

Numerical value in byte (8 bits), short (16 bits) or integer (32 bits) format. Numbers stay numbers, periodt. πŸ”₯

Option codes for 'byte (8)' format:

(019) DHO_IP_FORWARDING
(020) DHO_NON_LOCAL_SOURCE_ROUTING
(023) DHO_DEFAULT_IP_TTL
(027) DHO_ALL_SUBNETS_LOCAL
(029) DHO_PERFORM_MASK_DISCOVERY
(030) DHO_MASK_SUPPLIER
(031) DHO_ROUTER_DISCOVERY
(034) DHO_TRAILER_ENCAPSULATION
(036) DHO_IEEE802_3_ENCAPSULATION
(037) DHO_DEFAULT_TCP_TTL
(039) DHO_TCP_KEEPALIVE_GARBAGE
(046) DHO_NETBIOS_NODE_TYPE
(052) DHO_DHCP_OPTION_OVERLOAD
(116) DHO_AUTO_CONFIGURE

Option codes for 'short (16)' format:

(013) DHO_BOOT_SIZE
(022) DHO_MAX_DGRAM_REASSEMBLY
(026) DHO_INTERFACE_MTU
(057) DHO_DHCP_MAX_MESSAGE_SIZE

Option codes for 'integer (32)' format:

(002) DHO_TIME_OFFSET
(024) DHO_PATH_MTU_AGING_TIMEOUT
(035) DHO_ARP_CACHE_TIMEOUT
(038) DHO_TCP_KEEPALIVE_INTERVAL
(051) DHO_DHCP_LEASE_TIME
(058) DHO_DHCP_RENEWAL_TIME
(059) DHO_DHCP_REBINDING_TIME

Examples:

$pac->addOptionValue(DHO_DHCP_OPTION_OVERLOAD(), 3);
$pac->addOptionValue(DHO_INTERFACE_MTU(), 1500);
$pac->addOptionValue(DHO_DHCP_RENEWAL_TIME(), 24*60*60);

🧺 multiple bytes, shorts 🧺

A list of bytes or shorts. Little list, big main character energy. 🌟

Option codes for 'multiple bytes (8)' format:

(055) DHO_DHCP_PARAMETER_REQUEST_LIST

Option codes for 'multiple shorts (16)' format:

(025) DHO_PATH_MTU_PLATEAU_TABLE
(117) DHO_NAME_SERVICE_SEARCH

Examples:

$pac->addOptionValue(DHO_DHCP_PARAMETER_REQUEST_LIST(),  "1 3 6 12 15 28 42 72");

πŸ” SERIALIZATION METHODS πŸ”

serialize ()

Converts a Net::DHCP::Packet to a string, ready to put on the network. Slay, packet, slay. ✨

marshall ( BYTES )

The inverse of serialize. Converts a string, presumably a received UDP packet, into a Net::DHCP::Packet.

🚨 If the packet is malformed, a fatal error is produced. No cap, handle with care. πŸ’€

🧰 HELPER METHODS 🧰

toString ()

Returns a textual representation of the packet, for debugging. Perfect for when you need the tea. πŸ“

packinet ( STRING )

Transforms an IP address "xx.xx.xx.xx" into a packed 4 bytes string.

These are simple never failing versions of inet_ntoa and inet_aton.

packinets ( STRING )

Transforms a list of space delimited IP addresses into a packed bytes string.

packinets_array( LIST )

Transforms an array (list) of IP addresses into a packed bytes string.

unpackinet ( STRING )

Transforms a packed bytes IP address into a "xx.xx.xx.xx" string.

unpackinets ( STRING )

Transforms a packed bytes list of IP addresses into a list of "xx.xx.xx.xx" space delimited string.

unpackinets_array ( STRING )

Transforms a packed bytes list of IP addresses into an array of "xx.xx.xx.xx" strings.


⚑ SPECIAL METHODS ⚑

These methods are provided for performance tuning only. They give access to internal data representation, thus avoiding unnecessary type conversion. Speed demon behavior, honestly. πŸ”₯

ciaddrRaw ( [STRING])

Sets/gets the client IP address in packed 4 characters binary strings.

yiaddrRaw ( [STRING] )

Sets/gets your IP address in packed 4 characters binary strings.

siaddrRaw ( [STRING] )

Sets/gets the next server IP address in packed 4 characters binary strings.

giaddrRaw ( [STRING] )

Sets/gets the relay agent IP address in packed 4 characters binary strings.

chaddrRaw ( [STRING] )

Sets/gets the client hardware address in packed binary string. Its length is given by the "hlen" attribute.


🌈 EXAMPLES 🌈

Sending a simple DHCP packet:

#!/usr/bin/perl
# Simple DHCP client - sending a broadcasted DHCP Discover request

use IO::Socket::INET;
use Net::DHCP::Packet;
use Net::DHCP::Constants;

# creat DHCP Packet
$discover = Net::DHCP::Packet->new(
                      xid => int(rand(0xFFFFFFFF)), # random xid
                      Flags => 0x8000,              # ask for broadcast answer
                      DHO_DHCP_MESSAGE_TYPE() => DHCPDISCOVER()
                      );

# send packet
$handle = IO::Socket::INET->new(Proto => 'udp',
                                Broadcast => 1,
                                PeerPort => '67',
                                LocalPort => '68',
                                PeerAddr => '255.255.255.255')
              or die "socket: $@";     # yes, it uses $@ here
$handle->send($discover->serialize())
              or die "Error sending broadcast inform:$!\n";

Sniffing DHCP packets.

#!/usr/bin/perl
# Simple DHCP server - listen to DHCP packets and print them

use IO::Socket::INET;
use Net::DHCP::Packet;
$sock = IO::Socket::INET->new(LocalPort => 67, Proto => "udp", Broadcast => 1)
        or die "socket: $@";
while ($sock->recv($newmsg, 1024)) {
        $packet = Net::DHCP::Packet->new($newmsg);
        print STDERR $packet->toString();
}

Sending a LEASEQUERY (provided by John A. Murphy).

#!/usr/bin/perl
# Simple DHCP client - send a LeaseQuery (by IP) and receive the response

use IO::Socket::INET;
use Net::DHCP::Packet;
use Net::DHCP::Constants;

$usage = "usage: $0 DHCP_SERVER_IP DHCP_CLIENT_IP\n"; $ARGV[1] || die $usage;

# create a socket
$handle = IO::Socket::INET->new(Proto => 'udp',
                                Broadcast => 1,
                                PeerPort => '67',
                                LocalPort => '67',
                                PeerAddr => $ARGV[0])
              or die "socket: $@";     # yes, it uses $@ here

# create DHCP Packet
$inform = Net::DHCP::Packet->new(
                    op => BOOTREQUEST(),
                    Htype  => '0',
                    Hlen   => '0',
                    Ciaddr => $ARGV[1],
                    Giaddr => $handle->sockhost(),
                    Xid => int(rand(0xFFFFFFFF)),     # random xid
                    DHO_DHCP_MESSAGE_TYPE() => DHCPLEASEQUERY
                    );

# send request
$handle->send($inform->serialize()) or die "Error sending LeaseQuery: $!\n";

#receive response
$handle->recv($newmsg, 1024) or die;
$packet = Net::DHCP::Packet->new($newmsg);
print $packet->toString();

A simple DHCP Server is provided in the "examples" directory. It is composed of "dhcpd.pl" a very simple server example, and "dhcpd_test.pl" a simple tester for this server. Cute little test squad, honestly. 🫢


πŸ‘‘ AUTHOR πŸ‘‘

Dean Hamstead <djzort@cpan.org> Previously Stephan Hadinger <shadinger@cpan.org>. Original version by F. van Dun. Iconic lineage, periodt. πŸ’œ

πŸ› BUGS πŸ›

See <https://rt.cpan.org/Dist/Display.html?Queue=Net-DHCP>.

πŸ› οΈ GOT PATCHES? πŸ› οΈ

Many young people like to use Github, so by all means send me pull requests at

https://github.com/djzort/Net-DHCP

This is free software. It can be distributed and/or modified under the same terms as Perl itself.

πŸ¦‹ SEE ALSO πŸ¦‹

Net::DHCP::Options, Net::DHCP::Constants.


You made it to the end, bestie! πŸŽ€βœ¨ This page is serving perl v5.36.0 energy and is dated 2022-11-19 β€” straight from the Net::D...:Packet(3pm) page. Stay slaying. πŸ’–πŸŒΈ

πŸ“¦ where this page comes from