summaryrefslogtreecommitdiffhomepage
path: root/pkg/dhcp/dhcp.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/dhcp/dhcp.go')
-rw-r--r--pkg/dhcp/dhcp.go280
1 files changed, 0 insertions, 280 deletions
diff --git a/pkg/dhcp/dhcp.go b/pkg/dhcp/dhcp.go
deleted file mode 100644
index f96ffd891..000000000
--- a/pkg/dhcp/dhcp.go
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright 2018 The gVisor Authors.
-//
-// 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 implements a DHCP client and server as described in RFC 2131.
-package dhcp
-
-import (
- "bytes"
- "encoding/binary"
- "fmt"
- "time"
-
- "gvisor.googlesource.com/gvisor/pkg/tcpip"
-)
-
-// Config is standard DHCP configuration.
-type Config struct {
- Error error
- ServerAddress tcpip.Address // address of the server
- SubnetMask tcpip.AddressMask // client address subnet mask
- Gateway tcpip.Address // client default gateway
- DNS []tcpip.Address // client DNS server addresses
- LeaseLength time.Duration // length of the address lease
-}
-
-func (cfg *Config) decode(opts []option) error {
- *cfg = Config{}
- for _, opt := range opts {
- b := opt.body
- if !opt.code.lenValid(len(b)) {
- return fmt.Errorf("%s: bad length: %d", opt.code, len(b))
- }
- switch opt.code {
- case optLeaseTime:
- t := binary.BigEndian.Uint32(b)
- cfg.LeaseLength = time.Duration(t) * time.Second
- case optSubnetMask:
- cfg.SubnetMask = tcpip.AddressMask(b)
- case optDHCPServer:
- cfg.ServerAddress = tcpip.Address(b)
- case optDefaultGateway:
- cfg.Gateway = tcpip.Address(b)
- case optDomainNameServer:
- for ; len(b) > 0; b = b[4:] {
- if len(b) < 4 {
- return fmt.Errorf("DNS bad length: %d", len(b))
- }
- cfg.DNS = append(cfg.DNS, tcpip.Address(b[:4]))
- }
- }
- }
- return nil
-}
-
-func (cfg Config) encode() (opts []option) {
- if cfg.ServerAddress != "" {
- opts = append(opts, option{optDHCPServer, []byte(cfg.ServerAddress)})
- }
- if cfg.SubnetMask != "" {
- opts = append(opts, option{optSubnetMask, []byte(cfg.SubnetMask)})
- }
- if cfg.Gateway != "" {
- opts = append(opts, option{optDefaultGateway, []byte(cfg.Gateway)})
- }
- if len(cfg.DNS) > 0 {
- dns := make([]byte, 0, 4*len(cfg.DNS))
- for _, addr := range cfg.DNS {
- dns = append(dns, addr...)
- }
- opts = append(opts, option{optDomainNameServer, dns})
- }
- if l := cfg.LeaseLength / time.Second; l != 0 {
- v := make([]byte, 4)
- v[0] = byte(l >> 24)
- v[1] = byte(l >> 16)
- v[2] = byte(l >> 8)
- v[3] = byte(l >> 0)
- opts = append(opts, option{optLeaseTime, v})
- }
- return opts
-}
-
-const (
- // ServerPort is the well-known UDP port number for a DHCP server.
- ServerPort = 67
- // ClientPort is the well-known UDP port number for a DHCP client.
- ClientPort = 68
-)
-
-var magicCookie = []byte{99, 130, 83, 99} // RFC 1497
-
-type xid uint32
-
-type header []byte
-
-func (h header) init() {
- h[1] = 0x01 // htype
- h[2] = 0x06 // hlen
- h[3] = 0x00 // hops
- h[8], h[9] = 0, 0 // secs
- copy(h[236:240], magicCookie)
-}
-
-func (h header) isValid() bool {
- if len(h) < 241 {
- return false
- }
- if o := h.op(); o != opRequest && o != opReply {
- return false
- }
- if h[1] != 0x01 || h[2] != 0x06 {
- return false
- }
- return bytes.Equal(h[236:240], magicCookie)
-}
-
-func (h header) op() op { return op(h[0]) }
-func (h header) setOp(o op) { h[0] = byte(o) }
-func (h header) xidbytes() []byte { return h[4:8] }
-func (h header) xid() xid { return xid(h[4])<<24 | xid(h[5])<<16 | xid(h[6])<<8 | xid(h[7]) }
-func (h header) setBroadcast() { h[10], h[11] = 0x80, 0x00 } // flags top bit
-func (h header) ciaddr() []byte { return h[12:16] }
-func (h header) yiaddr() []byte { return h[16:20] }
-func (h header) siaddr() []byte { return h[20:24] }
-func (h header) giaddr() []byte { return h[24:28] }
-func (h header) chaddr() []byte { return h[28:44] }
-func (h header) sname() []byte { return h[44:108] }
-func (h header) file() []byte { return h[108:236] }
-
-func (h header) options() (opts options, err error) {
- i := headerBaseSize
- for i < len(h) {
- if h[i] == 0 {
- i++
- continue
- }
- if h[i] == 255 {
- break
- }
- if len(h) <= i+1 {
- return nil, fmt.Errorf("option missing length")
- }
- optlen := int(h[i+1])
- if len(h) < i+2+optlen {
- return nil, fmt.Errorf("option %v too long i=%d, optlen=%d", optionCode(h[i]), i, optlen)
- }
- opts = append(opts, option{
- code: optionCode(h[i]),
- body: h[i+2 : i+2+optlen],
- })
- i += 2 + optlen
- }
- return opts, nil
-}
-
-func (h header) setOptions(opts []option) {
- i := headerBaseSize
- for _, opt := range opts {
- h[i] = byte(opt.code)
- h[i+1] = byte(len(opt.body))
- copy(h[i+2:i+2+len(opt.body)], opt.body)
- i += 2 + len(opt.body)
- }
- h[i] = 255 // End option
- i++
- for ; i < len(h); i++ {
- h[i] = 0
- }
-}
-
-// headerBaseSize is the size of a DHCP packet, including the magic cookie.
-//
-// Note that a DHCP packet is required to have an 'end' option that takes
-// up an extra byte, so the minimum DHCP packet size is headerBaseSize + 1.
-const headerBaseSize = 240
-
-type option struct {
- code optionCode
- body []byte
-}
-
-type optionCode byte
-
-const (
- optSubnetMask optionCode = 1
- optDefaultGateway optionCode = 3
- optDomainNameServer optionCode = 6
- optDomainName optionCode = 15
- optReqIPAddr optionCode = 50
- optLeaseTime optionCode = 51
- optDHCPMsgType optionCode = 53 // dhcpMsgType
- optDHCPServer optionCode = 54
- optParamReq optionCode = 55
- optMessage optionCode = 56
- optClientID optionCode = 61
-)
-
-func (code optionCode) lenValid(l int) bool {
- switch code {
- case optSubnetMask, optDefaultGateway,
- optReqIPAddr, optLeaseTime, optDHCPServer:
- return l == 4
- case optDHCPMsgType:
- return l == 1
- case optDomainNameServer:
- return l%4 == 0
- case optMessage, optDomainName, optClientID:
- return l >= 1
- case optParamReq:
- return true // no fixed length
- default:
- return true // unknown option, assume ok
- }
-}
-
-type options []option
-
-func (opts options) dhcpMsgType() (dhcpMsgType, error) {
- for _, opt := range opts {
- if opt.code == optDHCPMsgType {
- if len(opt.body) != 1 {
- return 0, fmt.Errorf("%s: bad length: %d", opt.code, len(opt.body))
- }
- v := opt.body[0]
- if v <= 0 || v >= 8 {
- return 0, fmt.Errorf("DHCP bad length: %d", len(opt.body))
- }
- return dhcpMsgType(v), nil
- }
- }
- return 0, nil
-}
-
-func (opts options) message() string {
- for _, opt := range opts {
- if opt.code == optMessage {
- return string(opt.body)
- }
- }
- return ""
-}
-
-func (opts options) len() int {
- l := 0
- for _, opt := range opts {
- l += 1 + 1 + len(opt.body) // code + len + body
- }
- return l + 1 // extra byte for 'pad' option
-}
-
-type op byte
-
-const (
- opRequest op = 0x01
- opReply op = 0x02
-)
-
-// dhcpMsgType is the DHCP Message Type from RFC 1533, section 9.4.
-type dhcpMsgType byte
-
-const (
- dhcpDISCOVER dhcpMsgType = 1
- dhcpOFFER dhcpMsgType = 2
- dhcpREQUEST dhcpMsgType = 3
- dhcpDECLINE dhcpMsgType = 4
- dhcpACK dhcpMsgType = 5
- dhcpNAK dhcpMsgType = 6
- dhcpRELEASE dhcpMsgType = 7
-)