diff --git a/dhcp/packet.go b/dhcp/packet.go index 746c461..564cbe1 100644 --- a/dhcp/packet.go +++ b/dhcp/packet.go @@ -83,6 +83,26 @@ type Packet struct { Options Options } +// TxType determines how the Packet should be sent on the wire, based +// on its field values. +// +// This implements the transmission decision process in section 4.1 of +// RFC 2131. +func (p *Packet) TxType() TxType { + switch { + case p.RelayAddr != nil && p.RelayAddr.IsGlobalUnicast(): + return TxRelayAddr + case p.Type == MsgNack: + return TxBroadcast + case p.ClientAddr != nil && p.ClientAddr.IsGlobalUnicast(): + return TxClientAddr + case p.Broadcast: + return TxBroadcast + default: + return TxHardwareAddr + } +} + // DebugString prints the contents of a DHCP packet for human consumption. func (p *Packet) DebugString() string { var b bytes.Buffer diff --git a/dhcp/server.go b/dhcp/server.go new file mode 100644 index 0000000..9827fdc --- /dev/null +++ b/dhcp/server.go @@ -0,0 +1,54 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dhcp + +import "net" + +// TxType describes how a Packet should be sent on the wire. +type TxType int + +// The various transmission strategies described in RFC 2131. "MUST", +// "MUST NOT", "SHOULD" and "MAY" are as specified in RFC 2119. +const ( + // Packet MUST be broadcast. + TxBroadcast TxType = iota + // Packet MUST be unicasted to port 67 of RelayAddr + TxRelayAddr + // Packet MUST be unicasted to port 68 of ClientAddr + TxClientAddr + // Packet SHOULD be unicasted to port 68 of YourAddr, with the + // link-layer destination explicitly set to HardwareAddr. You MUST + // NOT rely on ARP resolution to discover the link-layer + // destination address. + // + // Conn implementations that cannot explicitly set the link-layer + // destination address MAY instead broadcast the packet. + TxHardwareAddr +) + +// Conn is a DHCP-oriented packet socket. +// +// Multiple goroutines may invoke methods on a Conn simultaneously. +type Conn interface { + // RecvDHCP reads a Packet from the connection. It returns the + // packet and the interface it was received on, which may be nil + // if interface information cannot be obtained. + RecvDHCP() (pkt *Packet, intf *net.Interface, err error) + // SendDHCP sends pkt. The precise transmission mechanism depends + // on pkt.TxType(). intf should be the net.Interface returned by + // RecvDHCP if responding to a DHCP client, or the interface for + // which configuration is desired if acting as a client. + SendDHCP(pkt *Packet, intf *net.Interface) error +}