#!/opt/psh/bin/psh

#
# Copyright (c) 1998 Sun Microsystems, Inc.
# 
# This software is provided by Sun ``AS IS'' and any express or implied
# warranties, including, but not limited to, the implied warranties of
# merchantability and fitness for a particular purpose are disclaimed.
# In no event shall Sun Microsystems be liable for any direct, indirect,
# incidental, special, exemplary, or consequential damages.
# 
# This software is not a product, and is provided for evaluation purposes
# only.
# 
# This software may not be resold without the express permission of
# Sun Microsystems.
# 
#ident	"@(#)validate_offer	1.1	98/02/24 SMI"
#

set bootpc	68
set bootps	67
set srv_timeout 15000;		# msec
set slp_timeout 10;		# sec
set xid		42;

proc dhcp_client_add { cl_ethaddr srv_ipaddr } {

	global argv0 bootpc bootps srv_timeout srv_id xid

	# make all the packets we'll need up front
	foreach i { disc offer } {
		pinit bootpc $i - - $i
	}

	# open the socket, set options so we can broadcast 
	popen socket ep inet dgram udp
	foreach i { dontroute broadcast reuseaddr } {
		ep.setsockopt SOL_SOCKET $i 1
	}

	# initialize discover packet
	eval pset disc bootpc chaddr	$cl_ethaddr
	pset disc bootpc xid		$xid
	pset disc bootpc flags		0x8000

	puts "$argv0: sending DISCOVER packet to $srv_ipaddr, port $bootps"

	ep.bind 0.0.0.0/$bootpc
	ep.sendto disc 0 $srv_ipaddr/$bootps
	if { [ep.recvfrom offer 0 $srv_timeout] == "timeout" } {
		puts "$argv0: no response to DISCOVER packet"
		return;
	}

	set srv_id  [pget offer bootpc opt "server id"]
	puts "$argv0: received OFFER packet from $srv_id"
	puts [plist offer]
	
	# got offer, now validate as much as we can
	if { [pget disc bootpc xid] != [pget offer bootpc xid] } {
		puts "$argv0:  xid of OFFER packet doesn't match DISCOVER xid"
		return;
	}
	if { [expr [lindex [pget offer bootpc flags] 0] != [lindex [pget offer bootpc flags] 0]] } {
		puts "$argv0:  mismatch between DISCOVER and OFFER flags"
		return;
	}
	if { [pget offer bootpc giaddr] != [pget offer bootpc giaddr] } {
		puts "$argv0:  mismatch between DISCOVER and OFFER giaddr"
		return;
	}
	if { [pget offer bootpc chaddr] != [pget offer bootpc chaddr] } {
		puts "$argv0:  mismatch between DISCOVER and OFFER chaddr"
		return;
	}

	# free all the packets
	foreach i { disc offer } {
		pfree $i
	}
}

#
# if no one passed us an ether addr, try to find one
#

if { [expr $argc < 2] } {
	puts "$argv0: no client ethernet address given, trying to find one..."

	regsub -all ":" [lindex [exec ifconfig -a | grep BROADCAST] 0] "" i
	regsub -all ":|^" [lindex [exec ifconfig $i ether | tail +2] 1] " 0x" \
	    cl_ethaddr
	set srv_ipaddr "255.255.255.255"
} else {
	regsub -all ":|^" [lindex $argv 0]" " 0x" cl_ethaddr 
	set srv_ipaddr [lindex $argv 1]
}

puts "$argv0: using (ethernet addr `$cl_ethaddr')"
dhcp_client_add "$cl_ethaddr" "$srv_ipaddr"
