'-----------------------------------------------------------------------------------------
'name : dhcp_SPI-5200.bas
'copyright : (c) 1995-2017, MCS Electronics Based on dhcp.bas from Atilio Mosca
'purpose : demo: DHCP
'micro : Mega88
'suited for demo : no
'commercial addon needed : only hardware
'-----------------------------------------------------------------------------------------
$regfile = "M88def.dat"
$crystal = 8000000
$baud = 19200
$hwstack = 40
$swstack = 40
$framesize = 40
Rst Alias Portb.0 'WIZ820 used which has a reset pin
Config Rst = Output
Declare Function Xidcookie_ok() As Byte
Declare Function Parse_dhcp_msg(byval Doption As Byte) As Byte
Declare Function Dhcp_ok() As Byte
Declare Sub Print_parse()
'we will use the tt array only in the begin
Dim Tt(548) As Byte 'DHCP buffer
Dim Xid(4) As Byte
Dim Mac_add(6) As Byte
Dim Pa(4) As Byte
Dim Result As Word
Dim Ip(4) As Byte , Submask(4) As Byte , Gateway(4) As Byte
'Transaction ID
'This number should be random but we use the MAC address
Xid(1) = 12
Xid(2) = 34
Xid(3) = 56
Xid(4) = 78
'Mac Address
'This number should match the one in the 'Config Tcpip...' line
'Do not use first byte
Mac_add(1) = 0
Mac_add(2) = 128
Mac_add(3) = 12
Mac_add(4) = 34
Mac_add(5) = 56
Mac_add(6) = 78
Config Spi = Hard , Interrupt = Off , Data_order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0
'Init the spi pins
Spiinit
Rst = 0
Waitms 10
Rst = 1
Waitms 150
'we specify IP 0.0.0.0 and gateway 0.0.0.0. Really important is to use local port 68 !
Config Tcpip = Noint , Mac = Mac_add(1) , Ip = 0.0.0.0 , Submask = 0.0.0.0 , Gateway = 0.0.0.0 , Localport = 68 , Chip = W5200 , Spi = 1
Print "Init"
If Dhcp_ok() = 1 Then
Print "DHCP OK"
Else
Print "err"
End If
End
Do
! nop
' a ping should now work
Loop
End
Function Dhcp_ok() As Byte
Local Btmp As Byte
Local Try As Byte
Dhcp_ok = 0 'assume error
If Getsocket(0 , Sock_dgram , 68 , 0) = 0 Then
For Result = 1 To 548 'clear buffer
Tt(result) = 0
Next
Try = 0
Do
Btmp = Socketstat(0 , Sel_control)
If Btmp = Sock_udp Then Exit Do
Waitms 10
Incr Try
Loop Until Try > 100
'DHCP
Tt(1) = 1 'Dhcp_pack_request
Tt(2) = 1 ' Dhcp_htype10mb
Tt(3) = 6 ' 'mac address lenght Dhcp_hlenethernet
Tt(4) = 0 'Dhcp_hops
Tt(5) = Xid(1)
Tt(6) = Xid(2)
Tt(7) = Xid(3)
Tt(8) = Xid(4)
Tt(11) = &H80 'dhcp flags
Tt(29) = Mac_add(1) 'MAC address
Tt(30) = Mac_add(2)
Tt(31) = Mac_add(3)
Tt(32) = Mac_add(4)
Tt(33) = Mac_add(5)
Tt(34) = Mac_add(6)
Tt(237) = 99 'DHCP cookie
Tt(238) = 130
Tt(239) = 83
Tt(240) = 99
Tt(241) = 53 'options Dhcpmessagetype
Tt(242) = 1
Tt(243) = 1 'Dhcp_discover
Tt(244) = 55 'Dhcpparamrequest
Tt(245) = 4 ' Request list
Tt(246) = 1 'Subnet mask
Tt(247) = 3 'Default Gateway router
Tt(248) = 6 'DNS server
Tt(249) = 255 'end options
Try = 0
Do
Incr Try
Result = Udpwrite(255.255.255.255 , 67 , 0 , Tt(1) , 548 )
Print "(" ; Result ; " bytes)"
For Btmp = 1 To 100
Waitms 10
Result = Socketstat(0 , Sel_recv)
If Result > 0 Then Exit For
Next
Loop Until Result > 0 Or Try > 9
If Result > 0 Then
Print "<-- Receive DHCP Offer (" ; Result ; " bytes)"
Udpreadheader 0 ' read the udp header
Result = Result - 8
Result = Udpread(0 , Tt(1) , Result )
If Tt(1) = 2 Then 'DHCP pack reply
If Xidcookie_ok() = 1 Then 'same XactionID
If Tt(241) = 53 Then ' Dhcp_offer_ok Dhcpmessagetype
If Tt(242) = 1 Then
If Tt(243) = 2 Then ' Dhcp_offer
Tt(1) = 1 'Dhcp_pack_request
Tt(13) = Tt(17) 'IP client
Tt(14) = Tt(18)
Tt(15) = Tt(19)
Tt(16) = Tt(20)
Tt(17) = 0 'my IP
Tt(18) = 0
Tt(19) = 0
Tt(20) = 0
Tt(241) = 53 ' Dhcpmessagetype options
Tt(242) = 1
Tt(243) = 3 'Dhcp_request
Tt(244) = 55 'Dhcpparamrequest
Tt(245) = 4
Tt(246) = 1 'Subnetmask
Tt(247) = 3 'Router
Tt(248) = 6 'Dns
Tt(249) = 255 'Endoption
For Result = 250 To 548 'refill
Tt(result) = 0
Next
Result = Udpwrite(255.255.255.255 , 67 , 0 , Tt(1) , 548 )
'Print "(" ; Result ; " bytes)"
For Btmp = 1 To 100
Waitms 10
Result = Socketstat(0 , Sel_recv)
If Result > 0 Then Exit For
Next
If Result > 0 Then
'Print "<-- Receive DHCP Pack (" ; Result ; " bytes)"
'Clearbuff
Udpreadheader 0 ' read the udp header
Result = Result - 8
Result = Udpread(0 , Tt(1) , Result )
If Tt(1) = 2 Then 'DHCP pack reply?
If Xidcookie_ok() = 1 Then 'same XactionID?
If Tt(241) = 53 Then 'Dhcpmessagetype DHCPACK
If Tt(242) = 1 Then
If Tt(243) = 5 Then ' Dhcp_ack
Pa(1) = Tt(20) 'Get IP in buffer
Pa(2) = Tt(19)
Pa(3) = Tt(18)
Pa(4) = Tt(17)
Btmp = Memcopy(pa(1) , Ip(1) , 4 , 3)
Print "My IP: ";
Print_parse
If Parse_dhcp_msg(1) = 1 Then 'subnet mask
Print "Sub Net Mask: ";
Print_parse
Btmp = Memcopy(pa(1) , Submask(1) , 4 , 3)
End If
If Parse_dhcp_msg(3) = 1 Then 'router
Print "Default Gateway: ";
Print_parse
Btmp = Memcopy(pa(1) , Gateway(1) , 4 , 3)
End If
If Parse_dhcp_msg(54) = 1 Then 'dhcpserveridentifier
Print "DHCP Server: ";
Print_parse
End If
If Parse_dhcp_msg(6) = 1 Then 'DNS
Print "DNS Server: ";
Print_parse
End If
Print "Reconfig..."
Settcp Mac_add(1) , Ip(1) , Submask(1) , Gateway(1)
Dhcp_ok = 1
'*****************************************************************************
'* At this point, the Wxx00, responds to the new IP
'* provided by the DHCP server.
'* You can check this with PING
'*****************************************************************************
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
Closesocket 0 'do not forget to close the socket
End Function
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Function Xidcookie_ok() As Byte
Xidcookie_ok = 0
If Tt(5) = Xid(1) Then
If Tt(6) = Xid(2) Then
If Tt(7) = Xid(3) Then
If Tt(8) = Xid(4) Then 'end of XID check
If Tt(237) = 99 Then 'cookie check
If Tt(238) = 130 Then
If Tt(239) = 83 Then
If Tt(240) = 99 Then
Xidcookie_ok = 1
End If
End If
End If
End If
End If
End If
End If
End If
End Function
'-------------------------------------------------------------------------------
Function Parse_dhcp_msg(byval Doption As Byte) As Byte
Local Ax As Word
Local Ay As Byte
Pa(1) = 0
Pa(2) = 0
Pa(3) = 0
Pa(4) = 0
Parse_dhcp_msg = 0
Ax = 244
Do
Ay = Tt(ax)
If Ay = 255 Then Exit Do
If Ay = Doption Then
Ax = Ax + 5 '2
Pa(1) = Tt(ax)
Decr Ax
Pa(2) = Tt(ax)
Decr Ax
Pa(3) = Tt(ax)
Decr Ax
Pa(4) = Tt(ax)
Parse_dhcp_msg = 1
Exit Do
End If
Incr Ax
Ay = Tt(ax)
Ax = Ax + Ay
Incr Ax
If Ax > 548 Then Exit Do
Loop
End Function
'-------------------------------------------------------------------------------
Sub Print_parse()
Print Pa(4) ; "." ; Pa(3) ; "." ; Pa(2) ; "." ; Pa(1) ; " "
End Sub
'-------------------------------------------------------------------------------
|