dhcp(3)

SYNOPSIS
pinit dhcp pkt [maxlength [length]] [type]

pfree pkt

pget pkt dhcp [opt] field

pset pkt dhcp [[opt] [del]] field [value]

plist pkt dhcp

DESCRIPTION
This describes the DHCP Protocol Library for the Packet Shell (psh), from here on referred to as the DHCP module. The DHCP module gives Packet Shell users an easy way to create, examine, and manipulate DHCP packets, in order to test or debug DHCP-related programs and utilities. Since DHCP is a superset of BOOTP (RFC 951), the DHCP module can also be used to test or debug BOOTP-related problems.

The DHCP module is very similar to other psh protocol libraries, except that it does not provide popen, pclose, send, or recv commands. Instead, the Packet Shell user is expected to use the DHCP module just for manipulation of DHCP packets, and the Socket Protocol Library for transmitting and receiving them.

The DHCP module aims to provide the Packet Shell user with a simple, precise and versatile mechanism for creating, manipulating and examining DHCP packets. To this end, it strives to shield the user from many of the details of DHCP, such as option overloading, variable-length packets, obscure manifest constants, and internal representation of data. Sometimes, however, these conveniences may get in the way, or prove too constraining. In cases like this, the user should feel free to use the Packet Shell's low level interface to packets through pread and pwrite. The DHCP Module has been designed to handle low-level manipulation such as this.

In addition to the fields specified in RFC 2131, the DHCP module also understands and interprets all of the options specified in RFC 2132, "DHCP Options and Vendor Extensions". The module also supports some conveniences to make interaction easier:

Named Constants
    The DHCP module supports the verbose names for manifest constants that are used in RFC 2131 and RFC 2132. These same verbose names are also printed in response to pget or plist when possible. Of course, the user is free to also use the numeric constants, in any form acceptable to strtoul(3C).

Abbreviations
    Any of the field names, option names, or other named constants may be abbreviated to the shortest name that still uniquely identifies it. Be forewarned that as new names are added to the DHCP specification, previously acceptable abbreviations may become ambiguous.

Case Insensitivity
    Any of the field names, option names, or other named constants may be typed in either case, or a mix of lower and uppercase.

The DHCP Module makes the following commands available to the Packet Shell user:

pinit dhcp pkt [maxlength [length]] [type]
    Initialize a DHCP packet variable. If type is provided, it should be either an integer or a string describing what type of packet this will be. In this case, the DHCP module will initialize several of the fields in the packet to have reasonable defaults. If no type is provided, or a type of "raw" is specified, then a zero-filled DHCP packet is created. Valid types are "discover", "request", "ack", "nak", "decline", "inform", "release", and "offer". For more information on the maxlength and length parameters, see the psh(1) manual page.

pfree pkt
    Delete the packet named pkt. This should be used to inform the Packet Shell that the user is done with a packet and that its resources can be released.

pget pkt dhcp [ opt ] field
    Display the contents of field in the packet named pkt. Multiple representations of field's value may be displayed. The first representation is always a form which can be input to pset, if desired. Any following representations are for the benefit of the user, and have no programmatic purpose. If the whole output of pget is passed to pset, pset will ignore all but the first field.

    The optional argument opt must be provided when field is an option. In this case, if the option is set in the packet, its value is displayed. Otherwise, a diagnostic message is displayed.

pset pkt dhcp [ [ opt ] [ del ] ] field [ value ]
    Set the contents of field in the packet named pkt. The format of value depends on field, but pset will always accept the first format that is produced by a pget on field. Often, other formats which are more readable and digestable are also supported -- experimentation and suggestions are welcome.

    The optional argument opt must be provided when field is an option. In the case of options, multiple values may be permitted, and some options even allow value to be empty. The DHCP module will print diagnostic messages to aid the user whenever possible in these cases.

    Options not previously set are appended to the next available space in the packet. Options which have previously been set have their existing value replaced by value. Additionally, the optional del argument may be passed to indicate that the option named by field should be deleted entirely. In this case, value should not be provided.

plist pkt dhcp
    Display, in an easy-to-digest format, the current values of the fields in pkt, and any options which are currently set in pkt. The format of the output produced by plist should not be relied on -- it is designed for users, not programs.

EXAMPLE
This short example creates a DHCP DISCOVER packet, sends it to the hypothetical server "dhcpserv", receives a reply from the server, and prints the response from the server. It is intended to demonstrate the way the DHCP module interacts with the Socket Protocol Library.

psh% popen socket ep inet dgram udp
psh% foreach i { dontroute broadcast reuseaddr } {
        ep.setsockopt SOL_SOCKET $i 1
    }
psh% ep.bind 0.0.0.0/68
psh% pinit dhcp disc disc
psh% pinit dhcp offer offer
psh% pset disc dhcp chaddr client_hardware_address
psh% pset disc dhcp xid 42
psh% pset disc dhcp flags 0x8000
psh% ep.sendto disc 0 255.255.255.255/67
psh% if { [ep.recvfrom offer 0 500] == "timeout" } {
        puts "no response to DISCOVER packet"
    } else {
        plist offer dhcp
    }

NOTES
Due to subtleties in the way TCL handles arguments in command substitution, psets which accept multiple arguments and have their value set through pget command substitution, will probably not work the way the user expects. For example,

psh% pget pkt chaddr dhcp
     0x01 0x02 0x03 0x04 0x05 0x06
psh% pset pkt2 dhcp chaddr [pget pkt dhcp chaddr]
psh% pget pkt2 dhcp chaddr
     0x01 0x00 0x00 0x00 0x00 0x00

To get around this problem, use the TCL eval command:

psh% pget pkt chaddr dhcp
     0x01 0x02 0x03 0x04 0x05 0x06
psh% eval pset pkt2 dhcp chaddr [pget pkt dhcp chaddr]
psh% pget pkt2 dhcp chaddr
     0x01 0x02 0x03 0x04 0x05 0x06

Additionally, sometimes chaddr may not appear to be working right. This is probably because hlen is not the correct value for the hardware type, which is an especially easy mistake to make when working with raw packets.

FILES

/opt/psh/lib/dhcp
    Dynamically linked DHCP Protocol Library.

/opt/psh/tcllib/dhcp.proto
    Brief online help for the DHCP module.

SEE ALSO
xpsh(1), psh(1), protolib(3).