dhcp test
This commit is contained in:
parent
01b201266c
commit
69c2837a31
|
@ -5,41 +5,12 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
"github.com/google/gopacket/layers"
|
||||||
MAGIC_COOKIE uint32 = 0x63825363
|
|
||||||
OPT_CODE_SERVER_IDENTIFIER uint8 = 54
|
|
||||||
OPT_CODE_SUBNET_MASK uint8 = 1
|
|
||||||
OPT_CODE_ROUTER uint8 = 3
|
|
||||||
OPT_CODE_DNS uint8 = 6
|
|
||||||
)
|
|
||||||
|
|
||||||
type dhcpDiscover struct {
|
"github.com/google/gopacket"
|
||||||
MsgType byte
|
gl "github.com/google/gopacket/layers"
|
||||||
HwType byte
|
)
|
||||||
HwAddrLen byte
|
|
||||||
Hops byte
|
|
||||||
Xid uint32
|
|
||||||
Secs uint16
|
|
||||||
BootpFlags uint16
|
|
||||||
ClientIp uint32
|
|
||||||
YourIp uint32
|
|
||||||
NextServerIp uint32
|
|
||||||
RelayAgentIp uint32
|
|
||||||
ClientMacAddr [6]byte
|
|
||||||
ClientHwAddrPadding [10]byte
|
|
||||||
ServerHostName [64]byte
|
|
||||||
BootFileName [128]byte
|
|
||||||
MagicCookie uint32
|
|
||||||
Mtype byte
|
|
||||||
MtypeLen byte
|
|
||||||
MtypeVal byte
|
|
||||||
Opts [200]byte
|
|
||||||
End byte
|
|
||||||
Padding [16]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func doDiscover(address string) (map[string]string, error) {
|
func doDiscover(address string) (map[string]string, error) {
|
||||||
|
|
||||||
|
@ -51,13 +22,9 @@ func doDiscover(address string) (map[string]string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
sendDiscover(conn) // broadcast 255.255.255.255:67
|
sendDiscover(conn) // broadcast 255.255.255.255:67
|
||||||
|
|
||||||
return readOffer(conn) // unicast
|
return readOffer(conn) // unicast
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -70,32 +37,27 @@ func sendDiscover(conn *net.UDPConn) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
dhcp := dhcpDiscover{
|
dhcp := &gl.DHCPv4{Operation: gl.DHCPOpRequest, HardwareType: gl.LinkTypeEthernet, Xid: 0x12345678,
|
||||||
MsgType: 0x01,
|
ClientIP: net.IP{0, 0, 0, 0}, YourClientIP: net.IP{0, 0, 0, 0}, NextServerIP: net.IP{0, 0, 0, 0}, RelayAgentIP: net.IP{0, 0, 0, 0},
|
||||||
HwType: 0x01,
|
ClientHWAddr: net.HardwareAddr{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc},
|
||||||
HwAddrLen: 0x06,
|
ServerName: make([]byte, 64), File: make([]byte, 128)}
|
||||||
Hops: 0x00,
|
|
||||||
Xid: 0x00000000,
|
|
||||||
Secs: 0x0000,
|
|
||||||
ClientIp: 0x00000000,
|
|
||||||
YourIp: 0x00000000,
|
|
||||||
NextServerIp: 0x00000000,
|
|
||||||
RelayAgentIp: 0x00000000,
|
|
||||||
MagicCookie: MAGIC_COOKIE,
|
|
||||||
Mtype: 0x35,
|
|
||||||
MtypeLen: 0x01,
|
|
||||||
MtypeVal: 0x01,
|
|
||||||
End: 0xff,
|
|
||||||
}
|
|
||||||
|
|
||||||
var flag uint16 = 0
|
dhcp.Options = append(dhcp.Options, gl.NewDHCPOption(gl.DHCPOptMessageType, []byte{byte(gl.DHCPMsgTypeDiscover)}))
|
||||||
dhcp.BootpFlags = ^flag // flag = unicast , ^flag = broadcast
|
dhcp.Options = append(dhcp.Options, gl.NewDHCPOption(gl.DHCPOptHostname, []byte{'o', 'v', 'e', 'r', 'f', 'l', 'o', 'w', '.', 'c', 'o', 'm'}))
|
||||||
|
dhcp.Options = append(dhcp.Options, gl.NewDHCPOption(gl.DHCPOptPad, nil))
|
||||||
|
dhcp.Options = append(dhcp.Options, gl.NewDHCPOption(gl.DHCPOptParamsRequest,
|
||||||
|
[]byte{byte(gl.DHCPOptSubnetMask), byte(gl.DHCPOptBroadcastAddr), byte(gl.DHCPOptTimeOffset),
|
||||||
|
byte(gl.DHCPOptRouter), byte(gl.DHCPOptDomainName), byte(gl.DHCPOptDNS), byte(gl.DHCPOptDomainSearch),
|
||||||
|
byte(gl.DHCPOptHostname), byte(gl.DHCPOptNetBIOSTCPNS), byte(gl.DHCPOptInterfaceMTU), byte(gl.DHCPOptClasslessStaticRoute),
|
||||||
|
byte(gl.DHCPOptNTPServers)}))
|
||||||
|
|
||||||
writer := new(bytes.Buffer)
|
buf := gopacket.NewSerializeBuffer()
|
||||||
if err := binary.Write(writer, binary.BigEndian, dhcp); err != nil {
|
opts := gopacket.SerializeOptions{FixLengths: true}
|
||||||
|
err = gopacket.SerializeLayers(buf, opts, dhcp)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = conn.WriteToUDP(writer.Bytes(), serverAddr)
|
_, err = conn.WriteToUDP(buf.Bytes(), serverAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -107,62 +69,52 @@ func readOffer(conn *net.UDPConn) (map[string]string, error) {
|
||||||
offerOptions := make(map[string]string)
|
offerOptions := make(map[string]string)
|
||||||
|
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 1024)
|
||||||
_, _, err := conn.ReadFromUDP(buf)
|
n, _, err := conn.ReadFromUDP(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if n <= 0 {
|
||||||
offer := dhcpDiscover{}
|
return nil, fmt.Errorf("%s", "Emptry response.")
|
||||||
|
|
||||||
reader := new(bytes.Buffer)
|
|
||||||
reader.Write(buf)
|
|
||||||
if err := binary.Read(reader, binary.BigEndian, &offer); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if offer.MagicCookie != MAGIC_COOKIE {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//option searching
|
var dhcp gl.DHCPv4
|
||||||
r := new(bytes.Buffer)
|
decoded := []gopacket.LayerType{}
|
||||||
r.Write(offer.Opts[:])
|
parser := gopacket.NewDecodingLayerParser(gl.LayerTypeDHCPv4, &dhcp)
|
||||||
|
if err = parser.DecodeLayers(buf, &decoded); err != nil {
|
||||||
for i := 0; i < r.Len(); i++ {
|
return nil, err
|
||||||
v := r.Next(1)[0]
|
}
|
||||||
|
for _, layerType := range decoded {
|
||||||
if v == OPT_CODE_SUBNET_MASK && r.Next(1)[0] == 4 {
|
switch layerType {
|
||||||
ipStr := byteToIPString(r.Next(4))
|
case layers.LayerTypeDHCPv4:
|
||||||
offerOptions["SUBNETMASK"] = ipStr
|
for _, opt := range dhcp.Options {
|
||||||
}
|
switch opt.Type {
|
||||||
|
case gl.DHCPOptServerID:
|
||||||
if v == OPT_CODE_ROUTER && r.Next(1)[0] == 4 {
|
offerOptions["DHCP_SERVER"] = optDataToIPString(opt.Data)
|
||||||
ipStr := byteToIPString(r.Next(4))
|
break
|
||||||
offerOptions["ROUTER"] = ipStr
|
case gl.DHCPOptLeaseTime:
|
||||||
}
|
var sec int32
|
||||||
|
if err = binary.Read(bytes.NewReader(opt.Data), binary.BigEndian, &sec); err == nil {
|
||||||
if v == OPT_CODE_DNS {
|
offerOptions["LEASE_TIME"] = fmt.Sprintf("%d", sec)
|
||||||
len := r.Next(1)[0]
|
}
|
||||||
var dns []string
|
break
|
||||||
var ipStr string
|
case gl.DHCPOptSubnetMask:
|
||||||
ipStr = byteToIPString(r.Next(4))
|
offerOptions["SUBNET_MASK"] = optDataToIPString(opt.Data)
|
||||||
dns = append(dns, ipStr)
|
break
|
||||||
if len == 8 {
|
case gl.DHCPOptRouter:
|
||||||
ipStr = byteToIPString(r.Next(4))
|
offerOptions["ROUTER"] = optDataToIPString(opt.Data)
|
||||||
dns = append(dns, ipStr)
|
break
|
||||||
|
case gl.DHCPOptDNS:
|
||||||
|
offerOptions["DNS_SERVER"] = optDataToIPString(opt.Data)
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
offerOptions["DNS"] = strings.Join(dns, ",")
|
|
||||||
}
|
|
||||||
|
|
||||||
if v == OPT_CODE_SERVER_IDENTIFIER && r.Next(1)[0] == 4 {
|
|
||||||
ipStr := byteToIPString(r.Next(4))
|
|
||||||
offerOptions["DHCP_SERVER"] = ipStr
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return offerOptions, nil
|
return offerOptions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func byteToIPString(b []byte) string {
|
func optDataToIPString(b []byte) string {
|
||||||
var ipStr string
|
var ipStr string
|
||||||
len := len(b)
|
len := len(b)
|
||||||
for i := 0; i < len; i++ {
|
for i := 0; i < len; i++ {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDHCP(t *testing.T) {
|
func TestDHCP(t *testing.T) {
|
||||||
offer, err := doDiscover("192.168.1.201")
|
offer, err := doDiscover("192.168.1.203")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("ERROR : %s", err.Error())
|
t.Errorf("ERROR : %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user