NEW
  AUTO 3,1
*--------------------------------------
DHCP.INIT		lda IPCFG+S.NETCFG.STATUS
				and #S.IPCFG.STATUS.OK
				bne .99					Already Configured, exit

				stz IPCFG+S.NETCFG.STATUS

				ldx #3

.1				eor A2osX.TIMER16,x
				sta DHCP.DISC.XID,x
				sta DHCP.REQ.XID,x
				dex
				bpl .1

				ldx #5

.2				lda IPCFG+S.NETCFG.MAC,x
				sta DHCP.DISC.CHADDR,x
				sta DHCP.REQ.CHADDR,x
				dex
				bpl .2

				clc
.9				rts

.99				>LDYA L.MSG.DHCP.NA

				>SYSCALL PutS
				lda #0
				sec
				rts
*--------------------------------------
DHCP.RUN		>PUSHBI S.SOCKET.T.DGRAM
				>PUSHBI 0				no protocol
				>LIBCALL hLIBTCPIP,LIBTCPIP.Socket
				bcc	.1

.9				jmp DHCP.RUN.KO

.1				sta hSocket
				>PUSHA
				>PUSHW L.SA.LOCAL
				>LIBCALL hLIBTCPIP,LIBTCPIP.Bind
				bcs .9

				>SLEEP

				>PUSHB hSocket
				>PUSHBI S.SOCKET.O.BROADCAST
				>LIBCALL hLIBTCPIP,LIBTCPIP.setsockopt

				>PUSHB hSocket
				>PUSHW L.SA.REMOTE
				>LIBCALL hLIBTCPIP,LIBTCPIP.Connect
				bcs .9

				>LDYA L.MSG.DHCP.CFG1
				>SYSCALL PutS

				>SLEEP

DHCP.RUN.SDISC	>PUSHB hSocket
				>PUSHW L.DHCP.DISC
				>PUSHWI DHCP.DISC.LEN
				>PUSHW L.SA.DEST

				>LIBCALL hLIBTCPIP,LIBTCPIP.SendTo
				bcc .1

				jmp DHCP.RUN.KO

.1				lda #S.IPCFG.STATUS.SDISC
				sta IPCFG

DHCP.RUN.ROFFER	jsr DHCP.RUN.SKT.RECV
				bcc .1

				lda #1
				jmp DHCP.RUN.KO

.1				jsr CheckDHCPOffer
				bcs DHCP.RUN.ROFFER
				lda #S.IPCFG.STATUS.ROFFER
				sta IPCFG

DHCP.RUN.SREQ	>PUSHW L.MSG.DHCP.CFG2
				ldx #0

.1				>PUSHB IPCFG+S.IPCFG.DHCPSRVR,x
				inx
				cpx #4
				bne .1

				>PUSHBI 4
				>SYSCALL PrintF

				>PUSHB hSocket
				>PUSHW L.DHCP.REQ
				>PUSHWI DHCP.REQ.LEN
				>PUSHW L.SA.DEST
				>LIBCALL hLIBTCPIP,LIBTCPIP.SendTo
				bcs DHCP.RUN.KO

				lda #S.IPCFG.STATUS.SREQ
				sta IPCFG

DHCP.RUN.RACK	jsr DHCP.RUN.SKT.RECV
				bcc .1

				lda #2
				bra DHCP.RUN.KO

.1				jsr CheckDHCPAck
				bcs DHCP.RUN.RACK

DHCP.RUN.OK		lda #S.IPCFG.STATUS.OK
				sta IPCFG
				>PUSHW L.IPCFG
				>LIBCALL hLIBTCPIP,LIBTCPIP.SETCFG

				>PUSHW L.MSG.DHCP.OK

				ldx #0

.1				lda IPCFG+S.IPCFG.IP,x
				>PUSHA
				inx
				cpx #4
				bne .1

				ldx #0

.2				lda IPCFG+S.IPCFG.MASK,x
				>PUSHA
				inx
				cpx #4
				bne .2

				>PUSHBI 8
				>SYSCALL PrintF

				lda #0					Leave with NO ERROR
				sec
				rts

DHCP.RUN.KO		pha
				>PUSHW L.MSG.DHCP.KO
				pla
				pha
				>PUSHA
				>PUSHBI 1
				>SYSCALL PrintF
				pla
				sec
				rts
*--------------------------------------
DHCP.RUN.SKT.RECV
				lda #TIMEOUT.MAX
				sta TimeOut

.1				>SLEEP

				lda hSocket
				>LIBCALL hLIBTCPIP,LIBTCPIP.Recv
				bcc	.8

				cmp #E.NODATA
				bne .9

				lda TimeOut
				bne .1

.9				sec
				rts

.8				sta hFrame

				>SYSCALL GetMemPtr
				>STYA ZPFrameBase
				rts
*--------------------------------------
DHCP.QUIT		lda hSocket
				beq .1

				>LIBCALL hLIBTCPIP,LIBTCPIP.Shutdown

.1				clc
				rts
*--------------------------------------
CheckDHCPOffer	jsr CheckDHCPXID
				bcs .9

				lda ZPFrameBase
				clc
				adc #S.DHCP.OPTIONS
				sta ZPFramePtr

				lda ZPFrameBase+1
				adc /S.DHCP.OPTIONS
				sta ZPFramePtr+1
				lda (ZPFramePtr)
				cmp #S.DHCP.OPTIONS.MSGTYPE
				bne .9

				ldy #2
				lda (ZPFramePtr),y
				cmp #S.DHCP.OPTIONS.DHCPOffer
				bne .9

*				ldy #S.DHCP.YIADDR+11	Copy YIADDR,SIADDR+GIADDR
*				ldx #11
*.1				lda (ZPFrameBase),y
*				sta DHCP.REQ.YIADDR,x
*				dey
*				dex
*				bpl .1

				ldy #S.DHCP.YIADDR+3
				ldx #3

.2				lda (ZPFrameBase),y
				sta DHCP.REQ.OPT.REQIP,x
				sta IPCFG+S.IPCFG.IP,x
				dey
				dex
				bpl .2

				ldy #S.DHCP.SIADDR+3
				lda (ZPFrameBase),y
				bne .3

				ldy #S.IP.SRC+3

.3				ldx #3

.4				lda (ZPFrameBase),y
				sta IPCFG+S.IPCFG.DHCPSRVR,x
				sta DHCP.REQ.OPT.SVRIP,x
				dey
				dex
				bpl .4

.5				inc	ZPFramePtr				skip Option 53 (DHCPOffer:530102)
				bne .6

				inc ZPFramePtr+1

.6				lda (ZPFramePtr)
				sec
				adc ZPFramePtr				add option len + 1
				sta ZPFramePtr
				bcc .7

				inc ZPFramePtr+1

.7				lda (ZPFramePtr)
				cmp #S.DHCP.OPTIONS.END
				beq .8

				jsr GetDHCPOption			May override SVRIP
				bra .5

.8				jsr CS.RUN.DISCARD
				clc
				rts

.9				jsr CS.RUN.DISCARD
				sec
				rts
*--------------------------------------
GetDHCPOption	cmp #S.DHCP.OPTIONS.MASK
				bne .1

				ldx #S.IPCFG.MASK
				bra GetDHCPOption.CopyIP

.1				cmp #S.DHCP.OPTIONS.GW
				bne .2

				ldx #S.IPCFG.GW
				bra GetDHCPOption.CopyIP

.2				cmp #S.DHCP.OPTIONS.DNS
				bne .3

				ldx #S.IPCFG.DNS1
				bra GetDHCPOption.CopyIP

.3				cmp #S.DHCP.OPTIONS.SRVID
				bne .4

				ldy #5
				ldx #3

.31				lda (ZPFramePtr),y
				sta DHCP.REQ.OPT.SVRIP,x
				dey
				dex
				bpl .31

				rts

.4				cmp #S.DHCP.OPTIONS.DOMAIN
				bne .9

				ldy #1
				lda (ZPFramePtr),y		Get String len
				cmp #45
				bcc .6

				lda #44

.6				sta IPCFG+S.IPCFG.DOMAIN	store len

				tax

.7				iny
				lda (ZPFramePtr),y
				sta IPCFG+S.IPCFG.DOMAIN-1,y
				dex
				bne .7

.9				rts
*--------------------------------------
GetDHCPOption.CopyIP
				ldy #1
				lda (ZPFramePtr),y		Get Byte count
				cmp #9
				bcc .1

				lda #8					max 8 bytes (2 DNS)

.1				iny

.2				pha
				lda (ZPFramePtr),y
				sta IPCFG,x
				iny
				inx
				pla
				dec
				bne .2

				rts
*--------------------------------------
CheckDHCPAck	jsr CheckDHCPXID
				bcs .9

				lda ZPFrameBase
				clc
				adc #S.DHCP.OPTIONS
				sta ZPFramePtr

				lda ZPFrameBase+1
				adc /S.DHCP.OPTIONS
				sta ZPFramePtr+1
				lda (ZPFramePtr)
				cmp #S.DHCP.OPTIONS.MSGTYPE
				bne .9

				ldy #2
				lda (ZPFramePtr),y
				cmp #S.DHCP.OPTIONS.DHCPAck
				bne .9

				jsr CS.RUN.DISCARD
				clc
				rts

.9				jsr CS.RUN.DISCARD
				sec
				rts
*--------------------------------------
CS.RUN.DISCARD	lda hFrame
				>SYSCALL FreeMem
				rts
*--------------------------------------
CheckDHCPXID	ldy #S.DHCP.XID+3
				ldx #3

.1				lda (ZPFrameBase),y
				cmp DHCP.DISC.XID,x	same XID ?
				bne .9

				dey
				dex
				bpl .1

				clc
				rts

.9				sec
				rts
*--------------------------------------
MAN
SAVE usr/src/bin/ipconfig.s.dhcp
LOAD usr/src/bin/ipconfig.s
ASM
