📄 bootp.c
字号:
/***************************************************************************************
File: bootp.c
Date: 7.10.2002
Version: 0.1
Author: Jari Lahti (jari@violasystems.com)
Description: This file implements BOOT protocol client
Version Info: 7.10.2002 - First version (Jari Lahti)
***************************************************************************************/
#include "opentcp.h"
UINT8 bootpapp_init = 0;
struct
{
UINT8 state;
UINT8 mode;
INT8 sochandle;
UINT16 tmrhandle;
UINT16 bootsecs;
} Bootp;
/********************************************************************************
Function: init_bootpc
Parameters: UINT8 mode - 0: Do not save parameters permanently
1: Save parameters permanently
Return val: INT8 - (>=0) OK
(-1) Error
Date: 7.19.2002
Desc: This function should be called before the BOOTP application
is used to set the operating parameters of it
*********************************************************************************/
INT8 init_bootpc (UINT8 mode)
{
/* Already initialized? */
if(bootpapp_init)
return(1);
/* Get socket handle */
Bootp.sochandle = udp_getsocket(0, bootpc_eventlistener, UDP_OPT_SEND_CS | UDP_OPT_CHECK_CS);
if(Bootp.sochandle < 0)
return(-1);
/* Put it to listening mode */
if( udp_open(Bootp.sochandle, BOOTP_CLIENTPORT) < 0 )
return(-1);
/* Get timer handle */
Bootp.tmrhandle = get_timer();
Bootp.bootsecs = 0;
Bootp.mode = mode;
Bootp.state = BOOTPC_STATE_DISABLED;
bootpapp_init = 1;
return(1);
}
/********************************************************************************
Function: bootpc_stop
Parameters: void
Return val: void
Date: 9.10.2002
Desc: Closes the bootp
*********************************************************************************/
void bootpc_stop (void)
{
if(bootpapp_init == 0)
return;
Bootp.state = BOOTPC_STATE_DISABLED;
}
/********************************************************************************
Function: bootpc_enable
Parameters: void
Return val: INT8 (-1) - Error
(>=0) - OK
Date: 9.10.2002
Desc: Enables the bootp
*********************************************************************************/
INT8 bootpc_enable (void)
{
if(bootpapp_init == 0)
return(-1);
Bootp.state = BOOTPC_STATE_ENABLED;
return(1);
}
/********************************************************************************
Function: bootpc_run
Parameters: void
Return val: void
Date: 7.10.2002
Desc: The main thread of bootp that should be called periodically
*********************************************************************************/
void bootpc_run (void)
{
INT16 i;
/* State machine */
if(bootpapp_init == 0)
return;
switch(Bootp.state)
{
case BOOTPC_STATE_ENABLED:
/* Check the IP address of the device and start BOOTP procedure for getting */
/* one if zero or 255.255.255.255 */
if( (localmachine.localip == 0) || (localmachine.localip == 0xFFFFFFFF) )
{
/* We need to start BOOTP request procedure */
/* Firstly wait random time */
localmachine.localip = 0;
localmachine.defgw = 0;
localmachine.netmask = 0;
init_timer(Bootp.tmrhandle, ((UINT32)(localmachine.localHW[0]) << 2) + localmachine.localHW[1]);
Bootp.state = BOOTPC_STATE_REQUEST_NEEDED;
}
return;
case BOOTPC_STATE_REQUEST_NEEDED:
if( check_timer(Bootp.tmrhandle) != 0 )
return;
/* Send request if we haven't get the IP in some other way */
if(localmachine.localip != 0)
{
Bootp.state = BOOTPC_STATE_ENABLED;
return;
}
i = 0;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x01;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x01;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x06;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0xCA;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x03;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x32;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0xF1;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = (UINT8)(Bootp.bootsecs >> 8);
OTCP_TXBUF[UDP_APP_OFFSET + i++] = (UINT8)Bootp.bootsecs;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x80;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = localmachine.localHW[5];
OTCP_TXBUF[UDP_APP_OFFSET + i++] = localmachine.localHW[4];
OTCP_TXBUF[UDP_APP_OFFSET + i++] = localmachine.localHW[3];
OTCP_TXBUF[UDP_APP_OFFSET + i++] = localmachine.localHW[2];
OTCP_TXBUF[UDP_APP_OFFSET + i++] = localmachine.localHW[1];
OTCP_TXBUF[UDP_APP_OFFSET + i++] = localmachine.localHW[0];
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 99;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 130;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 83;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 99;
OTCP_TXBUF[UDP_APP_OFFSET + i++] = 255;
for(i;i<300;i++)
OTCP_TXBUF[UDP_APP_OFFSET + i] = 0;
/* Send it */
udp_send(Bootp.sochandle, IP_BROADCAST_ADDRESS, BOOTP_SERVERPORT, &OTCP_TXBUF[UDP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - UDP_APP_OFFSET, 300);
init_timer(Bootp.tmrhandle, BOOTP_RETRY_TOUT*TIMERTIC);
Bootp.bootsecs += BOOTP_RETRY_TOUT*TIMERTIC;
Bootp.state = BOOTPC_STATE_WAITING_REPLY;
return;
case BOOTPC_STATE_WAITING_REPLY:
/* Wait untill timeout elapsed and try again */
if( check_timer(Bootp.tmrhandle) != 0 )
return;
/* Try again */
Bootp.state = BOOTPC_STATE_REQUEST_NEEDED;
return;
case BOOTPC_STATE_REPLY_GET:
/* You can save the parameters here to e.g. EEPROM */
Bootp.state = BOOTPC_STATE_ENABLED;
return;
default:
return;
}
}
INT32 bootpc_eventlistener (INT8 cbhandle, UINT8 event, UINT32 remip, UINT16 remport, UINT16 bufindex, UINT16 dlen)
{
INT16 i,j;
UINT32 ip = 0;
UINT32 nm = 0;
UINT32 dgw = 0;
UINT8 ch;
/* This function is called by UDP stack to inform about events */
if(bootpapp_init == 0)
return(-1);
if( cbhandle != Bootp.sochandle) /* Not our handle */
return(-1);
/* The only event is data */
if(Bootp.state != BOOTPC_STATE_WAITING_REPLY)
return(-1);
/* Process reply */
NETWORK_RECEIVE_INITIALIZE(bufindex);
if(dlen < 300)
return(-1);
if( RECEIVE_NETWORK_B() != BOOTP_REPLY)
return(-1);
if( RECEIVE_NETWORK_B() != BOOTP_HTYPE_ETHERNET)
return(-1);
if( RECEIVE_NETWORK_B() != BOOTP_HWLEN_ETHERNET)
return(-1);
RECEIVE_NETWORK_B(); /* Skip hops */
/* Check transaction ID */
if( RECEIVE_NETWORK_B() != 0xCA)
return(-1);
if( RECEIVE_NETWORK_B() != 0x03)
return(-1);
if( RECEIVE_NETWORK_B() != 0x32)
return(-1);
if( RECEIVE_NETWORK_B() != 0xF1)
return(-1);
/* Skip elapsed, unused, client address */
for(i=0; i<8; i++)
RECEIVE_NETWORK_B();
/* Get IP */
ip = RECEIVE_NETWORK_B();
ip <<= 8;
ip |= RECEIVE_NETWORK_B();
ip <<= 8;
ip |= RECEIVE_NETWORK_B();
ip <<= 8;
ip |= RECEIVE_NETWORK_B();
/* Skip server ip & bootp router address */
for(i=0; i<8; i++)
RECEIVE_NETWORK_B();
/* Check MAC */
if( RECEIVE_NETWORK_B() != localmachine.localHW[0])
return(-1);
if( RECEIVE_NETWORK_B() != localmachine.localHW[1])
return(-1);
if( RECEIVE_NETWORK_B() != localmachine.localHW[2])
return(-1);
if( RECEIVE_NETWORK_B() != localmachine.localHW[3])
return(-1);
if( RECEIVE_NETWORK_B() != localmachine.localHW[4])
return(-1);
if( RECEIVE_NETWORK_B() != localmachine.localHW[5])
return(-1);
RECEIVE_NETWORK_B();
RECEIVE_NETWORK_B();
for(i=0; i<200; i++)
RECEIVE_NETWORK_B();
/* Check options */
dlen -= 236;
i = 0;
while(i<dlen)
{
ch = RECEIVE_NETWORK_B();
i++;
if( (ch != BOOTP_OPTION_SUBNETMASK) && (ch != BOOTP_OPTION_DEFGW) )
{
/* Not supported option, skip it */
j = RECEIVE_NETWORK_B();
i++;
if(j >= 2)
{
j -= 2;
while(j--)
{
RECEIVE_NETWORK_B();
i++;
}
}
continue;
}
if( ch == BOOTP_OPTION_SUBNETMASK)
{
RECEIVE_NETWORK_B(); /* Skip totlen */
nm = RECEIVE_NETWORK_B();
nm <<= 8;
nm |= RECEIVE_NETWORK_B();
nm <<= 8;
nm |= RECEIVE_NETWORK_B();
nm <<= 8;
nm |= RECEIVE_NETWORK_B();
i += 5;
}
if( ch == BOOTP_OPTION_DEFGW)
{
j = RECEIVE_NETWORK_B(); /* Get totlen */
dgw = RECEIVE_NETWORK_B();
dgw <<= 8;
dgw |= RECEIVE_NETWORK_B();
dgw <<= 8;
dgw |= RECEIVE_NETWORK_B();
dgw <<= 8;
dgw |= RECEIVE_NETWORK_B();
i += 5;
/* Skip others */
if( j>5 )
{
j -= 5;
while(j--)
{
RECEIVE_NETWORK_B();
i++;
}
}
}
}
/* Store parameters */
localmachine.localip = ip;
localmachine.defgw = dgw;
localmachine.netmask = nm;
/* Change state */
Bootp.state = BOOTPC_STATE_REPLY_GET;
return(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -