Update of /project/movitz/cvsroot/movitz/losp/lib/net
In directory common-lisp.net:/tmp/cvs-serv14520
Modified Files:
dhcp.lisp
Log Message:
*** empty log message ***
Date: Tue May 24 09:15:54 2005
Author: ffjeld
Index: movitz/losp/lib/net/dhcp.lisp
diff -u movitz/losp/lib/net/dhcp.lisp:1.2 movitz/losp/lib/net/dhcp.lisp:1.3
--- movitz/losp/lib/net/dhcp.lisp:1.2 Tue May 24 01:30:38 2005
+++ movitz/losp/lib/net/dhcp.lisp Tue May 24 09:15:54 2005
@@ -10,7 +10,7 @@
;;;; Author: Frode Vatvedt Fjeld <frodef(a)acm.org>
;;;; Created at: Fri May 13 23:24:01 2005
;;;;
-;;;; $Id: dhcp.lisp,v 1.2 2005/05/23 23:30:38 ffjeld Exp $
+;;;; $Id: dhcp.lisp,v 1.3 2005/05/24 07:15:54 ffjeld Exp $
;;;;
;;;;------------------------------------------------------------------
@@ -56,14 +56,15 @@
+---------------------------------------------------------------+
|#
-(defmacro with-dhcp-header ((dhcp packet &key (start '(udp :end))) &body body)
+(defmacro with-dhcp-header ((dhcp packet &key start) &body body)
(let* ((dhcp-ref (gensym "dhcp-ref-"))
(start-var (gensym "dhcp-start-"))
(packet-var (gensym "dhcp-packet-"))
(offset-var (gensym "dhcp-packet-start-")))
- `(let* ((,start-var ,start)
- (,packet-var (ensure-data-vector ,packet ,start-var 232))
+ `(let* ((,packet-var ,packet)
+ (,start-var ,(or start `(fill-pointer ,packet-var)))
(,offset-var (+ ,start-var (movitz-type-slot-offset 'movitz-basic-vector 'data))))
+ (ensure-data-vector ,packet ,start-var 232)
(macrolet ((,dhcp-ref (offset type)
`(memref ,',packet-var (+ ,',offset-var ,offset) :type ,type :endian :big))
(,dhcp (slot)
@@ -77,7 +78,7 @@
(:flags
`(,',dhcp-ref 10 :unsigned-byte16))
((:ciaddr :yiaddr :siaddr :giaddr)
- `(,',dhcp-ref ,(+ 12 (position slot '(:ciaddr :yiaddr :siaddr :giaddr)))
+ `(,',dhcp-ref ,(+ 12 (* 4 (position slot '(:ciaddr :yiaddr :siaddr :giaddr))))
:unsigned-byte32))
(:chaddr
`(memrange ,',packet-var 0 (+ ,',offset-var 28) 16 :unsigned-byte8))
@@ -102,7 +103,7 @@
(defun dhcp-push-options (packet &rest options)
(declare (dynamic-extent options))
(loop while options
- do (ecase (pop options)
+ do (case (pop options)
(:lease-time
(vector-push 51 packet)
(vector-push 4 packet)
@@ -133,16 +134,17 @@
unless (= 0 option)
collect
(case option
- (1 (assert (= 4 (vector-read packet)))
+ (1 (assert (= 4 (vector-read packet)) () "Wrong length for subnet-mask.")
(cons :subnet-mask
(subseq packet
(fill-pointer packet)
(incf (fill-pointer packet) 4))))
(3 (let ((length (vector-read packet)))
(cons :routers
- (subseq packet
- (fill-pointer packet)
- (incf (fill-pointer packet) length)))))
+ (loop repeat (truncate length 4)
+ collect (subseq packet
+ (fill-pointer packet)
+ (incf (fill-pointer packet) 4))))))
(6 (let ((length (vector-read packet)))
(cons :dns-servers
(subseq packet
@@ -160,7 +162,7 @@
(subseq packet
(fill-pointer packet)
(incf (fill-pointer packet) length))))))
- (28 (assert (= 4 (vector-read packet)))
+ (28 (assert (= 4 (vector-read packet)) () "Wrong length for broadcast.")
(cons :broadcast
(subseq packet
(fill-pointer packet)
@@ -175,7 +177,7 @@
(subseq packet
(fill-pointer packet)
(incf (fill-pointer packet) length)))))
- (51 (assert (= 4 (vector-read packet)))
+ (51 (assert (= 4 (vector-read packet)) () "Wrong length for lease-time.")
(cons :lease-time
(loop with time = 0 repeat 4
do (setf time (+ (* 256 time) (vector-read packet)))
@@ -205,7 +207,7 @@
(fill-pointer packet)
(incf (fill-pointer packet) length)))))))))
-(defun format-dhcp-request (nic &rest dhcp-options &key (message-type :dhcpdiscover))
+(defun format-dhcp-request (nic &rest dhcp-options &key (xid 0) (message-type :dhcpdiscover))
(let ((packet (make-ethernet-packet)))
(with-ether-header (ether packet)
(setf (ether :source) (mac-address nic)
@@ -213,7 +215,7 @@
(ether :type) +ether-type-ip4+)
(with-ip4-header (ip packet :start (ether :end))
(with-udp-header (udp packet)
- (with-dhcp-header (dhcp packet)
+ (with-dhcp-header (dhcp packet :start (udp :end))
(setf (ip :version) 4
(ip :protocol) 17
(ip :ihl) 5
@@ -226,6 +228,7 @@
(dhcp :hlen ) 6
(dhcp :hops) 0
(dhcp :secs) 0
+ (dhcp :xid) xid
(dhcp :chaddr) (mac-address nic)
(dhcp :magic) +dhcp-magic+)
(setf (fill-pointer packet) (dhcp :end))
@@ -241,10 +244,12 @@
(udp :checksum) (udp :compute-checksum ip))
packet))))))
-(defun dhcp-request (&optional (nic (or *ip4-nic* (ip4-init))))
- (loop with packet = (make-ethernet-packet)
+(defun dhcp-request (&optional (nic (or *ip4-nic* (ip4-init))) &rest dhcp-options)
+ (declare (dynamic-extent dhcp-options))
+ (loop with packet = (make-ethernet-packet)
+ with xid = (random 10000)
repeat 5
- do (transmit nic (format-dhcp-request nic))
+ do (transmit nic (apply #'format-dhcp-request nic :xid xid dhcp-options))
(sleep 1/2)
when (loop while (receive nic packet)
thereis (with-ether-header (ether packet)
@@ -256,15 +261,25 @@
(ip4-address (ip :source)))
(with-udp-header (udp packet)
(when (= 68 (udp :destination-port))
+ (setf (fill-pointer packet)
+ (udp :end))
(with-dhcp-header (dhcp packet)
- (and (= +dhcp-magic+ (dhcp :magic))
- (setf (fill-pointer packet)
- (dhcp :end))))))))))
- return (values packet (parse-dhcp-options packet))))
-
-
-
-
-
-
-
\ No newline at end of file
+ (and (= xid (dhcp :xid))
+ (= +dhcp-magic+ (dhcp :magic))))))))))
+ return packet))
+
+(defun dhcp-init ()
+ (let ((packet (dhcp-request)))
+ (if (not packet)
+ (warn "DHCP lookup failed.")
+ (with-dhcp-header (dhcp packet)
+ (setf (fill-pointer packet) (dhcp :end))
+ (let ((options (parse-dhcp-options packet)))
+ (setf *ip4-ip* (ip4-address (dhcp :yiaddr))
+ *ip4-router* (first (cdr (assoc :routers options))))
+ (format *terminal-io* "Setting IP ~/ip4:pprint-ip4/ ~@[~A~]~@[.~A~] router ~/ip4:pprint-ip4/."
+ *ip4-ip*
+ (cdr (assoc :host-name options))
+ (cdr (assoc :domain-name options))
+ *ip4-router*)))))
+ (values))