I build a bootloader, it can send bootme well and the PB5.0 can
reply to it too. But here is a stange problem, bootloader can accept
destination 59.77.17.255 UDP packet but can't accept destination
59.77.17.100
UDP packet, which is its IP. Anytime the program comes to
EbootTFtpReceiver,
the packet must be 59.77.17.255 destination, so can't go on. It seems
to me that, if
IP is 59.77.17.255 every thing works as normal, but if it's
59.77.17.100,
bootloader works as if there is no frame arrived. Anyone can help me? I
have
debugged it for ond day.
The code below is cut from my sourcecode. I add a lot
of EdbgOutputDebugString which is used for debug, don't care about it.
UINT16
LAN91CGetFrame(UINT8 *pBuffer, UINT16 *pLength){ UINT8 *pos =3D
pBuffer;
UINT16 code, pointer; UINT32 length, count; EdbgOutputDebugString
("+
LAN91CGetFrame"); // Make sure that bank 2 is actual OUTPORT16(&
g_pLAN91C->BANKSEL, 2); length =3D 0; while
((INPORT16(&g_pLAN91C->INTR)
& INTR_RX) !=3D 0) { EdbgOutputDebugString ("+LAN91CGetFrame while\r\n")
; // Setup pointer address register pointer =3D PTR_RCV |
PTR_READ
; // Read status OUTPORT16(&g_pLAN91C->PTR, pointer);

code =3D INPORT16(&g_pLAN91C->DATA); pointer +=3D sizeof(UINT16);

if ((code & (STAT_ALGNERR|STAT_BADCRC|STAT_LONG|STAT_SHORT)) =3D=3D 0)
{ // Get packet size OUTPORT16(&g_pLAN91C->PTR,
pointer)
; length =3D (INPORT16(&g_pLAN91C->DATA) & 0x07FF) - 6;

pointer +=3D sizeof(UINT16); // Copy packet count =3D
length
; while (count > 1) {
OUTPORT16(&g_pLAN91C->PTR,
pointer); *(UINT16*)pos =3D INPORT16(&g_pLAN91C->DATA)
; pointer +=3D sizeof(UINT16); pos +=3D
sizeof(
UINT16); count -=3D sizeof(UINT16); }
//
Get control word (which can contain last byte)
OUTPORT16(&g_pLAN91C
->PTR, pointer); code =3D INPORT16(&g_pLAN91C->DATA);

pointer +=3D sizeof(UINT16); if ((code & CTRL_ODD) !=3D 0)
{ length++; *pos =3D (UINT8)code;

} } // Release the memory for the received frame
switch (
GET_CHIP_ID(g_chipRevision)) { case CHIP_ID_LAN91C111:

OUTPORT16(&g_pLAN91C->MMUCR, MMUCR_111_REM_REL_RX); break;

default: OUTPORT16(&g_pLAN91C->MMUCR,
MMUCR_REM_REL_TOP
); } while ((INPORT16(&g_pLAN91C->MMUCR) & MMUCR_BUSY) !=3D
0)
; // If length is non zero we get a packet if (length >
0) break
; } EdbgOutputDebugString ("hahahaha\r\n"); *pLength =3D
(UINT16)
length; return (*pLength);}pfnEDbgGetFrame =3D
(PFN_EDBG_GET_FRAME)
LAN91CGetFrame; BOOL OEMEthGetFrame(BYTE *pData, // OUT -
Receives
frame data UINT16 *pwLength) // IN - Length of Rx
buffer
{ EdbgOutputDebugString ("+OEMEthGetFrame\r\n"); return
(pfnEDbgGetFrame(
pData, pwLength));}BOOL EbootSendBootmeAndWaitForTftp (EDBG_ADDR
*pEdbgAddr,
UCHAR VersionMajor, UCHAR VersionMinor,
char *
szPlatformString, char *szDeviceName,
UCHAR CPUId
, DWORD dwBootFlags){ DWORD dwCurSec =3D OEMEthGetSecs () -
BOOTME_INTERVAL
; USHORT wLen, wDestPort, wSrcPort, wUDPDataLen, *pwUDPData; int
nRetries =3D 0; EdbgOutputDebugString
("+EbootSendBootmeAndWaitForTftp\r\n")
; while (!fTftpLinked) { EdbgOutputDebugString ("+while (!
fTftpLinked)\r\n"); if ((nRetries < MAX_BOOTME_CNT) && (OEMEthGetSecs
() -
dwCurSec >=3D BOOTME_INTERVAL)) { nRetries ++;
dwCurSec
+=3D BOOTME_INTERVAL; // send a bootme message
EbootSendBootme (pEdbgAddr, VersionMajor, VersionMinor,
szPlatformString,
szDeviceName, CPUId, dwBootFlags); } // get another frame
and
pass it to TFTP handler wLen =3D sizeof (gFrameBuffer); if
(
OEMEthGetFrame (gFrameBuffer, &wLen)) { // frame available?

switch (FRAMETYPE (gFrameBuffer)) { case 0x0800: // IP
packet EdbgOutputDebugString ("+FRAMETYPE IP\r\n"); if
(!
EbootCheckUDP(pEdbgAddr, gFrameBuffer, &wDestPort, &wSrcPort,
&pwUDPData, &
wUDPDataLen)) { // UDP? // EDBG command? (should
only
occur if eshell asked us to jump to existing image)
if (!
EbootProcessEDBG (pEdbgAddr, &gHostAddr, gFrameBuffer, pwUDPData,
wUDPDataLen
, &fTftpLinked, &gpCfgData)) { // no, pass it to

TFTP EbootTFtpReceiver (pEdbgAddr, gFrameBuffer,

wDestPort, wSrcPort, pwUDPData, wUDPDataLen);
} } break; case 0x0806: //
ARP
packet EdbgOutputDebugString ("+FRAMETYPE
ARP\r\n"); if (
EbootProcessARP (pEdbgAddr, gFrameBuffer) =3D=3D PROCESS_ARP_RESPONSE)
{ EdbgOutputDebugString( "Some other station has IP
Address
: %s !!! Aborting.\r\n", inet_ntoa(pEdbgAddr->dwIP));

return FALSE; } break; default
: break; } } }
EdbgOutputDebugString (
"-EbootSendBootmeAndWaitForTftp\r\n"); return TRUE;}// This routine

handles the multiplexing of all active TFTP links. It returns 0 if
there was
no valid link formed,// or 1 of there was.WORD EbootTFtpReceiver(
EDBG_ADDR *
pMyAddr, BYTE *pFrameBuffer, UINT16 wDestPort, UINT16 wSrcPort, UINT16
*
pwUDPData, UINT16 cwUDPDataLength ) { int i; UINT16 iLinkSlot =3D
MAX_TFTP_LINKS;EdbgOutputDebugString ("+EbootTFtpReceiver\r\n"); //
Check to
see if this is for a link that is currently in use for( i =3D 0; i <
MAX_TFTP_LINKS; i++ ) { // Here I don't compare the destination (Odo)
port,
only the source (host) because // this could be a repeat open packet,
which
we don't want to cause a second link. // This could happen if a second
open
packet comes because we will have changed the // destination port with
the
acknowledge. if (TFtpLinks[i].State !=3D TFTP_STATE_IDLE && wSrcPort =3D=
=3D
TFtpLinks[i].DestAddr.wPort && wDestPort =3D=3D
TFtpLinks[i].SrcAddr.wPort) {
iLinkSlot =3D i; break; } else if (TFtpLinks[i].State =3D=3D
TFTP_STATE_IDLE)
iLinkSlot =3D i; } // If we broke out of the loop early, then the packet
is for
a link that is already open if (i < MAX_TFTP_LINKS) { // iLinkSlot is
the
index of the link this packet belongs too TFtpStateMachine( wSrcPort,
iLinkSlot, pwUDPData, cwUDPDataLength ); } // Check to see if someone
is
trying to start a new connection, // If so, guarantee that there are
always
TFTP_TX_LINKS link(s) available to transmit information else if
(wDestPort =3D=3D
wOdoWellKnownServerPort && MAX_TFTP_LINKS - nNumTFtpLinksInUse >
TFTP_TX_LINKS
) { // iLinkSlot is the index of a link that is in the IDLE state,
giving
the number of a free link // slot that can be used, the wDestTID and
the
TFTP Message TFtpdFormNewLink( pMyAddr, pFrameBuffer, iLinkSlot,
pwUDPData )
; return 1; } else { for( i =3D 0; i < MAX_TFTP_LINKS; i++ )
{ EdbgOutputDebugString("TFTP link[%u]: State:%u,
DestAddr.wPort: %
u, SrcAddr.wPort: %u\n",
i,TFtpLinks[i].State,
ntohs(TFtpLinks[i].DestAddr.wPort),
ntohs(
TFtpLinks[i].SrcAddr.wPort)); } EdbgOutputDebugString("
TftpReceiver, port: 0x%X, wkp:
0x%X\n\r",wDestPort,wOdoWellKnownServerPort)
; } return 0;} //
TFtpReceiver() //---------------------------------------
---------------------------------------//// Function Name:
EbootCheckUD(...)
// Description..: This routine will check a UDP frame that has been
received
. // It will make sure that it was for our IP address
and
that // the checksums are right and that it's a UDP
packet.
If // something is wrong, the packet will be discarded
and
the // routine will return non-zero. If everything is
right
, // then all the port and IP information will be
filled out
and // the routine will return 0. Note that if we are
doing
the // DHCP process, the DHCP server will send the
OFFER
packet to // the IP address that it would like to give
us.
We have to // be able to accept a packet for any IP
address
in that // case. This condition is signaled to the
routine
by // fPromiscuousIP =3D=3D 1, which is set using
SetPromiscuousIP()//// Inputs.......: EDBG_ADDR * pntr to
address
// BYTE * pntr to frame//

UINT16 * pntr to dst addr// UINT16 *

pntr to src addr// UINT16 ** pntr to pntr to
data
// UINT16 * pntr to data length// Outputs
.=2E....: 0 on success, non zero on
failure////-------------------------------
-----------------------------------------------UINT16 EbootCheckUDP(
EDBG_ADDR *pMyAddr, BYTE *pFrameBuffer
, UINT16 *wDestPort,
UINT16
*wSrcPort, UINT16 **pwData,

UINT16 *cwLength ) { IPHeaderFormat *pIPHeader;
UDPPseudoHeaderFormat UDPPseudoHeader; UDPHeaderFormat *
pUDPHeader; // Note that I don't do any checking that depends on a
length
field // in the packet until after the CRC is verified for that
data
. // This prevents the code from running past the end of buffers,
etc
. // when a bad packet is received.EdbgOutputDebugString
("+EbootCheckUDP\
r\n"); pIPHeader =3D (IPHeaderFormat *)(pFrameBuffer + sizeof(
EthernetFrameHeader)); // Make sure that it was for our IP address,
unless
we're // doing DHCP (indicated by fPromiscuousIP =3D=3D 1) if( !
fPromiscuousIP && pIPHeader->dwDestIP !=3D pMyAddr->dwIP ) {//
EdbgOutputDebugString( // "!CheckUDP: Not our IP
(0x%X)\n",pIPHeader->
dwDestIP);EdbgOutputDebugString ("zjwzjwzjw return 1\r\n");
EdbgOutputDebugString("%s\r\n", inet_ntoa(pIPHeader->dwDestIP));
EdbgOutputDebugString("%s\r\n",
inet_ntoa(pMyAddr->dwIP));if(fPromiscuousIP)
{ EdbgOutputDebugString ("DHCP is ON ! WRONG!!!\r\n");} return(
1 )
; } // Make sure that it is a UDP packet if(
pIPHeader->bProtocol !=3D
17 ) { EdbgOutputDebugString( "!CheckUDP: Not UDP (proto =3D
0x%X)\n"
, pIPHeader->bProtocol ); return( 2 ); } //
Check the
IP header checksum if( CRC( (UINT16 *)pIPHeader,
sizeof(IPHeaderFormat),
NULL, 0 ) !=3D 0 ) { EdbgOutputDebugString( "!CheckUDP: IP
header
checksum failure\n" ); return( 3 ); } // Build the UDP
Pseudo
Header UDPPseudoHeader.dwSrcIP =3D pIPHeader->dwSrcIP;
UDPPseudoHeader.
dwDestIP =3D pIPHeader->dwDestIP; UDPPseudoHeader.bZero =3D 0;
UDPPseudoHeader.bProtocol =3D 17; // UDP Proto is 17
UDPPseudoHeader.
cwTotalUDPLength =3D htons( htons(pIPHeader->cwTotalLength) -
sizeof(
IPHeaderFormat )); // Check the UDP checksum, I'm using the
cwTotalUDPLength // calculated from the IP header info because we
know
that // it's not corrupted and won't give an outrageous length for
the
packet pUDPHeader =3D (UDPHeaderFormat *)((BYTE *)pIPHeader+sizeof(
IPHeaderFormat)); if( pUDPHeader->wCRC !=3D 0 && CRC( (UINT16
*)&
UDPPseudoHeader, sizeof(UDPPseudoHeader), (UINT16
*)pUDPHeader
, ntohs(UDPPseudoHeader.cwTotalUDPLength) ) !=3D 0 ) {
EdbgOutputDebugString( "!CheckUDP: UDP header checksum failure\n" );

return( 4 ); } // Now we know we have a good packet, fill out the

fields *wDestPort =3D pUDPHeader->wDestPort; *wSrcPort =3D
pUDPHeader->
wSrcPort; *pwData =3D (UINT16 *)((BYTE *)pUDPHeader +
sizeof(UDPHeaderFormat)
); *cwLength =3D htons(pUDPHeader->cwTotalUDPLength) -
sizeof(UDPHeaderFormat
); // Indicate success return( 0 );}

Re: bootme problem by ali88z

ali88z
Thu Oct 26 12:08:34 CDT 2006

something wrong, paste one more time

I build a bootloader, it can send bootme well and the PB5.0 can reply
to it too. But here is a stange problem, bootloader can accept
destination 59.77.17.255 UDP packet but can't accept destination
59.77.17.100 UDP packet, which is its IP.
Anytime the program comes to EbootTFtpReceiver, the packet must be from
59.77.17.255, so can't go on.
It seems to me that, if IP is 59.77.17.255 every thing works as normal,
but if it's 59.77.17.100, bootloader works as if there is no frame
arrived. Anyone can help me? I have debugged it for ond day.

The code below is cut from my sourcecode. I add a lot of
EdbgOutputDebugString which is used for debug, don't care about it.

UINT16 LAN91CGetFrame(UINT8 *pBuffer, UINT16 *pLength)
{
UINT8 *pos = pBuffer;
UINT16 code, pointer;
UINT32 length, count;
EdbgOutputDebugString ("+LAN91CGetFrame");
// Make sure that bank 2 is actual
OUTPORT16(&g_pLAN91C->BANKSEL, 2);

length = 0;
while ((INPORT16(&g_pLAN91C->INTR) & INTR_RX) != 0) {
EdbgOutputDebugString ("+LAN91CGetFrame while\r\n");
// Setup pointer address register
pointer = PTR_RCV | PTR_READ;

// Read status
OUTPORT16(&g_pLAN91C->PTR, pointer);
code = INPORT16(&g_pLAN91C->DATA);
pointer += sizeof(UINT16);

if ((code & (STAT_ALGNERR|STAT_BADCRC|STAT_LONG|STAT_SHORT)) ==
0) {

// Get packet size
OUTPORT16(&g_pLAN91C->PTR, pointer);
length = (INPORT16(&g_pLAN91C->DATA) & 0x07FF) - 6;
pointer += sizeof(UINT16);

// Copy packet
count = length;
while (count > 1) {
OUTPORT16(&g_pLAN91C->PTR, pointer);
*(UINT16*)pos = INPORT16(&g_pLAN91C->DATA);
pointer += sizeof(UINT16);
pos += sizeof(UINT16);
count -= sizeof(UINT16);
}

// Get control word (which can contain last byte)
OUTPORT16(&g_pLAN91C->PTR, pointer);
code = INPORT16(&g_pLAN91C->DATA);
pointer += sizeof(UINT16);
if ((code & CTRL_ODD) != 0) {
length++;
*pos = (UINT8)code;
}
}

// Release the memory for the received frame
switch (GET_CHIP_ID(g_chipRevision)) {
case CHIP_ID_LAN91C111:
OUTPORT16(&g_pLAN91C->MMUCR, MMUCR_111_REM_REL_RX);
break;
default:
OUTPORT16(&g_pLAN91C->MMUCR, MMUCR_REM_REL_TOP);
}

while ((INPORT16(&g_pLAN91C->MMUCR) & MMUCR_BUSY) != 0);

// If length is non zero we get a packet
if (length > 0) break;

}
EdbgOutputDebugString ("hahahaha\r\n");
*pLength = (UINT16)length;
return (*pLength);
}

pfnEDbgGetFrame = (PFN_EDBG_GET_FRAME) LAN91CGetFrame;

BOOL OEMEthGetFrame(BYTE *pData, // OUT - Receives frame data
UINT16 *pwLength) // IN - Length of Rx buffer
{
EdbgOutputDebugString ("+OEMEthGetFrame\r\n");
return (pfnEDbgGetFrame(pData, pwLength));
}


BOOL EbootSendBootmeAndWaitForTftp (EDBG_ADDR *pEdbgAddr, UCHAR
VersionMajor, UCHAR VersionMinor,
char *szPlatformString, char
*szDeviceName,
UCHAR CPUId, DWORD dwBootFlags)
{
DWORD dwCurSec = OEMEthGetSecs () - BOOTME_INTERVAL;
USHORT wLen, wDestPort, wSrcPort, wUDPDataLen, *pwUDPData;
int nRetries = 0;
EdbgOutputDebugString ("+EbootSendBootmeAndWaitForTftp\r\n");
while (!fTftpLinked) {
EdbgOutputDebugString ("+while (!fTftpLinked)\r\n");
if ((nRetries < MAX_BOOTME_CNT) && (OEMEthGetSecs () - dwCurSec >=
BOOTME_INTERVAL)) {
nRetries ++;
dwCurSec += BOOTME_INTERVAL;
// send a bootme message
EbootSendBootme (pEdbgAddr, VersionMajor, VersionMinor,
szPlatformString, szDeviceName, CPUId, dwBootFlags);
}
// get another frame and pass it to TFTP handler
wLen = sizeof (gFrameBuffer);
if (OEMEthGetFrame (gFrameBuffer, &wLen)) { // frame
available?
switch (FRAMETYPE (gFrameBuffer)) {
case 0x0800: // IP packet
EdbgOutputDebugString ("+FRAMETYPE IP\r\n");
if (!EbootCheckUDP(pEdbgAddr, gFrameBuffer, &wDestPort, &wSrcPort,
&pwUDPData, &wUDPDataLen)) { // UDP?
// EDBG command? (should only occur if eshell asked
us to jump to existing image)
if (!EbootProcessEDBG (pEdbgAddr, &gHostAddr,
gFrameBuffer, pwUDPData, wUDPDataLen, &fTftpLinked, &gpCfgData)) {
// no, pass it to TFTP
EbootTFtpReceiver (pEdbgAddr, gFrameBuffer,
wDestPort, wSrcPort, pwUDPData, wUDPDataLen);
}
}
break;
case 0x0806: // ARP packet
EdbgOutputDebugString ("+FRAMETYPE ARP\r\n");
if (EbootProcessARP (pEdbgAddr, gFrameBuffer) ==
PROCESS_ARP_RESPONSE) {
EdbgOutputDebugString( "Some other station has IP
Address: %s !!! Aborting.\r\n", inet_ntoa(pEdbgAddr->dwIP));
return FALSE;
}
break;
default:
break;
}
}
}
EdbgOutputDebugString ("-EbootSendBootmeAndWaitForTftp\r\n");
return TRUE;
}



// This routine handles the multiplexing of all active TFTP links. It
returns 0 if there was no valid link formed,
// or 1 of there was.
WORD EbootTFtpReceiver( EDBG_ADDR *pMyAddr, BYTE *pFrameBuffer, UINT16
wDestPort, UINT16 wSrcPort, UINT16 *pwUDPData, UINT16 cwUDPDataLength )
{

int i;
UINT16 iLinkSlot = MAX_TFTP_LINKS;
EdbgOutputDebugString ("+EbootTFtpReceiver\r\n");
// Check to see if this is for a link that is currently in use
for( i = 0; i < MAX_TFTP_LINKS; i++ ) {
// Here I don't compare the destination (Odo) port, only the source
(host) because
// this could be a repeat open packet, which we don't want to cause a
second link.
// This could happen if a second open packet comes because we will
have changed the
// destination port with the acknowledge.
if (TFtpLinks[i].State != TFTP_STATE_IDLE && wSrcPort ==
TFtpLinks[i].DestAddr.wPort
&& wDestPort == TFtpLinks[i].SrcAddr.wPort) {
iLinkSlot = i;
break;
}
else if (TFtpLinks[i].State == TFTP_STATE_IDLE)
iLinkSlot = i;
}

// If we broke out of the loop early, then the packet is for a link
that is already open
if (i < MAX_TFTP_LINKS) {
// iLinkSlot is the index of the link this packet belongs too
TFtpStateMachine( wSrcPort, iLinkSlot, pwUDPData, cwUDPDataLength );
}
// Check to see if someone is trying to start a new connection,
// If so, guarantee that there are always TFTP_TX_LINKS link(s)
available to transmit information
else if (wDestPort == wOdoWellKnownServerPort && MAX_TFTP_LINKS -
nNumTFtpLinksInUse > TFTP_TX_LINKS) {

// iLinkSlot is the index of a link that is in the IDLE state, giving
the number of a free link
// slot that can be used, the wDestTID and the TFTP Message
TFtpdFormNewLink( pMyAddr, pFrameBuffer, iLinkSlot, pwUDPData );
return 1;
}
else {

for( i = 0; i < MAX_TFTP_LINKS; i++ ) {
EdbgOutputDebugString("TFTP link[%u]: State:%u,
DestAddr.wPort: %u, SrcAddr.wPort: %u\n",
i,TFtpLinks[i].State,
ntohs(TFtpLinks[i].DestAddr.wPort),
ntohs(TFtpLinks[i].SrcAddr.wPort));
}
EdbgOutputDebugString("TftpReceiver, port: 0x%X, wkp:
0x%X\n\r",wDestPort,wOdoWellKnownServerPort);
}

return 0;

} // TFtpReceiver()


//------------------------------------------------------------------------------
//
// Function Name: EbootCheckUD(...)
// Description..: This routine will check a UDP frame that has been
received.
// It will make sure that it was for our IP address
and that
// the checksums are right and that it's a UDP packet.
If
// something is wrong, the packet will be discarded
and the
// routine will return non-zero. If everything is
right,
// then all the port and IP information will be filled
out and
// the routine will return 0. Note that if we are
doing the
// DHCP process, the DHCP server will send the OFFER
packet to
// the IP address that it would like to give us. We
have to
// be able to accept a packet for any IP address in
that
// case. This condition is signaled to the routine by

// fPromiscuousIP == 1, which is set using
SetPromiscuousIP()
//
// Inputs.......: EDBG_ADDR * pntr to address
// BYTE * pntr to frame
// UINT16 * pntr to dst addr
// UINT16 * pntr to src addr
// UINT16 ** pntr to pntr to data
// UINT16 * pntr to data length
// Outputs......: 0 on success, non zero on failure
//
//------------------------------------------------------------------------------

UINT16 EbootCheckUDP( EDBG_ADDR *pMyAddr,
BYTE *pFrameBuffer,
UINT16 *wDestPort,
UINT16 *wSrcPort,
UINT16 **pwData,
UINT16 *cwLength )
{
IPHeaderFormat *pIPHeader;
UDPPseudoHeaderFormat UDPPseudoHeader;
UDPHeaderFormat *pUDPHeader;

// Note that I don't do any checking that depends on a length field

// in the packet until after the CRC is verified for that data.
// This prevents the code from running past the end of buffers,
etc.
// when a bad packet is received.
EdbgOutputDebugString ("+EbootCheckUDP\r\n");
pIPHeader = (IPHeaderFormat *)(pFrameBuffer +
sizeof(EthernetFrameHeader));

// Make sure that it was for our IP address, unless we're
// doing DHCP (indicated by fPromiscuousIP == 1)

if( !fPromiscuousIP && pIPHeader->dwDestIP != pMyAddr->dwIP )
{
// EdbgOutputDebugString(
// "!CheckUDP: Not our IP (0x%X)\n",pIPHeader->dwDestIP);
EdbgOutputDebugString ("zjwzjwzjw return 1\r\n");
EdbgOutputDebugString("%s\r\n", inet_ntoa(pIPHeader->dwDestIP));
EdbgOutputDebugString("%s\r\n", inet_ntoa(pMyAddr->dwIP));
if(fPromiscuousIP)
{
EdbgOutputDebugString ("DHCP is ON ! WRONG!!!\r\n");
}
return( 1 );
}

// Make sure that it is a UDP packet

if( pIPHeader->bProtocol != 17 )
{
EdbgOutputDebugString( "!CheckUDP: Not UDP (proto = 0x%X)\n",
pIPHeader->bProtocol );

return( 2 );
}

// Check the IP header checksum

if( CRC( (UINT16 *)pIPHeader, sizeof(IPHeaderFormat), NULL, 0 ) !=
0 )
{
EdbgOutputDebugString( "!CheckUDP: IP header checksum
failure\n" );
return( 3 );
}

// Build the UDP Pseudo Header

UDPPseudoHeader.dwSrcIP = pIPHeader->dwSrcIP;
UDPPseudoHeader.dwDestIP = pIPHeader->dwDestIP;
UDPPseudoHeader.bZero = 0;
UDPPseudoHeader.bProtocol = 17; // UDP Proto is 17
UDPPseudoHeader.cwTotalUDPLength =
htons( htons(pIPHeader->cwTotalLength) - sizeof( IPHeaderFormat
));

// Check the UDP checksum, I'm using the cwTotalUDPLength
// calculated from the IP header info because we know that
// it's not corrupted and won't give an outrageous length for the
packet

pUDPHeader = (UDPHeaderFormat *)((BYTE
*)pIPHeader+sizeof(IPHeaderFormat));

if( pUDPHeader->wCRC != 0 &&
CRC( (UINT16 *)&UDPPseudoHeader,
sizeof(UDPPseudoHeader),
(UINT16 *)pUDPHeader,
ntohs(UDPPseudoHeader.cwTotalUDPLength) ) != 0 )
{
EdbgOutputDebugString( "!CheckUDP: UDP header checksum
failure\n" );
return( 4 );
}

// Now we know we have a good packet, fill out the fields

*wDestPort = pUDPHeader->wDestPort;
*wSrcPort = pUDPHeader->wSrcPort;
*pwData = (UINT16 *)((BYTE *)pUDPHeader + sizeof(UDPHeaderFormat));
*cwLength = htons(pUDPHeader->cwTotalUDPLength) -
sizeof(UDPHeaderFormat);

// Indicate success

return( 0 );
}


Re: bootme problem by Henrik

Henrik
Thu Oct 26 15:55:49 CDT 2006

First thing you should do is to make sure there's no firewall messing
with the comunication.

Henrik Viklund
http://www.addlogic.se

ali88z@gmail.com wrote:
> something wrong, paste one more time
>
> I build a bootloader, it can send bootme well and the PB5.0 can reply
> to it too. But here is a stange problem, bootloader can accept
> destination 59.77.17.255 UDP packet but can't accept destination
> 59.77.17.100 UDP packet, which is its IP.
> Anytime the program comes to EbootTFtpReceiver, the packet must be from
> 59.77.17.255, so can't go on.
> It seems to me that, if IP is 59.77.17.255 every thing works as normal,
> but if it's 59.77.17.100, bootloader works as if there is no frame
> arrived. Anyone can help me? I have debugged it for ond day.
>
> The code below is cut from my sourcecode. I add a lot of
> EdbgOutputDebugString which is used for debug, don't care about it.
>
> UINT16 LAN91CGetFrame(UINT8 *pBuffer, UINT16 *pLength)
> {
> UINT8 *pos = pBuffer;
> UINT16 code, pointer;
> UINT32 length, count;
> EdbgOutputDebugString ("+LAN91CGetFrame");
> // Make sure that bank 2 is actual
> OUTPORT16(&g_pLAN91C->BANKSEL, 2);
>
> length = 0;
> while ((INPORT16(&g_pLAN91C->INTR) & INTR_RX) != 0) {
> EdbgOutputDebugString ("+LAN91CGetFrame while\r\n");
> // Setup pointer address register
> pointer = PTR_RCV | PTR_READ;
>
> // Read status
> OUTPORT16(&g_pLAN91C->PTR, pointer);
> code = INPORT16(&g_pLAN91C->DATA);
> pointer += sizeof(UINT16);
>
> if ((code & (STAT_ALGNERR|STAT_BADCRC|STAT_LONG|STAT_SHORT)) ==
> 0) {
>
> // Get packet size
> OUTPORT16(&g_pLAN91C->PTR, pointer);
> length = (INPORT16(&g_pLAN91C->DATA) & 0x07FF) - 6;
> pointer += sizeof(UINT16);
>
> // Copy packet
> count = length;
> while (count > 1) {
> OUTPORT16(&g_pLAN91C->PTR, pointer);
> *(UINT16*)pos = INPORT16(&g_pLAN91C->DATA);
> pointer += sizeof(UINT16);
> pos += sizeof(UINT16);
> count -= sizeof(UINT16);
> }
>
> // Get control word (which can contain last byte)
> OUTPORT16(&g_pLAN91C->PTR, pointer);
> code = INPORT16(&g_pLAN91C->DATA);
> pointer += sizeof(UINT16);
> if ((code & CTRL_ODD) != 0) {
> length++;
> *pos = (UINT8)code;
> }
> }
>
> // Release the memory for the received frame
> switch (GET_CHIP_ID(g_chipRevision)) {
> case CHIP_ID_LAN91C111:
> OUTPORT16(&g_pLAN91C->MMUCR, MMUCR_111_REM_REL_RX);
> break;
> default:
> OUTPORT16(&g_pLAN91C->MMUCR, MMUCR_REM_REL_TOP);
> }
>
> while ((INPORT16(&g_pLAN91C->MMUCR) & MMUCR_BUSY) != 0);
>
> // If length is non zero we get a packet
> if (length > 0) break;
>
> }
> EdbgOutputDebugString ("hahahaha\r\n");
> *pLength = (UINT16)length;
> return (*pLength);
> }
>
> pfnEDbgGetFrame = (PFN_EDBG_GET_FRAME) LAN91CGetFrame;
>
> BOOL OEMEthGetFrame(BYTE *pData, // OUT - Receives frame data
> UINT16 *pwLength) // IN - Length of Rx buffer
> {
> EdbgOutputDebugString ("+OEMEthGetFrame\r\n");
> return (pfnEDbgGetFrame(pData, pwLength));
> }
>
>
> BOOL EbootSendBootmeAndWaitForTftp (EDBG_ADDR *pEdbgAddr, UCHAR
> VersionMajor, UCHAR VersionMinor,
> char *szPlatformString, char
> *szDeviceName,
> UCHAR CPUId, DWORD dwBootFlags)
> {
> DWORD dwCurSec = OEMEthGetSecs () - BOOTME_INTERVAL;
> USHORT wLen, wDestPort, wSrcPort, wUDPDataLen, *pwUDPData;
> int nRetries = 0;
> EdbgOutputDebugString ("+EbootSendBootmeAndWaitForTftp\r\n");
> while (!fTftpLinked) {
> EdbgOutputDebugString ("+while (!fTftpLinked)\r\n");
> if ((nRetries < MAX_BOOTME_CNT) && (OEMEthGetSecs () - dwCurSec >=
> BOOTME_INTERVAL)) {
> nRetries ++;
> dwCurSec += BOOTME_INTERVAL;
> // send a bootme message
> EbootSendBootme (pEdbgAddr, VersionMajor, VersionMinor,
> szPlatformString, szDeviceName, CPUId, dwBootFlags);
> }
> // get another frame and pass it to TFTP handler
> wLen = sizeof (gFrameBuffer);
> if (OEMEthGetFrame (gFrameBuffer, &wLen)) { // frame
> available?
> switch (FRAMETYPE (gFrameBuffer)) {
> case 0x0800: // IP packet
> EdbgOutputDebugString ("+FRAMETYPE IP\r\n");
> if (!EbootCheckUDP(pEdbgAddr, gFrameBuffer, &wDestPort, &wSrcPort,
> &pwUDPData, &wUDPDataLen)) { // UDP?
> // EDBG command? (should only occur if eshell asked
> us to jump to existing image)
> if (!EbootProcessEDBG (pEdbgAddr, &gHostAddr,
> gFrameBuffer, pwUDPData, wUDPDataLen, &fTftpLinked, &gpCfgData)) {
> // no, pass it to TFTP
> EbootTFtpReceiver (pEdbgAddr, gFrameBuffer,
> wDestPort, wSrcPort, pwUDPData, wUDPDataLen);
> }
> }
> break;
> case 0x0806: // ARP packet
> EdbgOutputDebugString ("+FRAMETYPE ARP\r\n");
> if (EbootProcessARP (pEdbgAddr, gFrameBuffer) ==
> PROCESS_ARP_RESPONSE) {
> EdbgOutputDebugString( "Some other station has IP
> Address: %s !!! Aborting.\r\n", inet_ntoa(pEdbgAddr->dwIP));
> return FALSE;
> }
> break;
> default:
> break;
> }
> }
> }
> EdbgOutputDebugString ("-EbootSendBootmeAndWaitForTftp\r\n");
> return TRUE;
> }
>
>
>
> // This routine handles the multiplexing of all active TFTP links. It
> returns 0 if there was no valid link formed,
> // or 1 of there was.
> WORD EbootTFtpReceiver( EDBG_ADDR *pMyAddr, BYTE *pFrameBuffer, UINT16
> wDestPort, UINT16 wSrcPort, UINT16 *pwUDPData, UINT16 cwUDPDataLength )
> {
>
> int i;
> UINT16 iLinkSlot = MAX_TFTP_LINKS;
> EdbgOutputDebugString ("+EbootTFtpReceiver\r\n");
> // Check to see if this is for a link that is currently in use
> for( i = 0; i < MAX_TFTP_LINKS; i++ ) {
> // Here I don't compare the destination (Odo) port, only the source
> (host) because
> // this could be a repeat open packet, which we don't want to cause a
> second link.
> // This could happen if a second open packet comes because we will
> have changed the
> // destination port with the acknowledge.
> if (TFtpLinks[i].State != TFTP_STATE_IDLE && wSrcPort ==
> TFtpLinks[i].DestAddr.wPort
> && wDestPort == TFtpLinks[i].SrcAddr.wPort) {
> iLinkSlot = i;
> break;
> }
> else if (TFtpLinks[i].State == TFTP_STATE_IDLE)
> iLinkSlot = i;
> }
>
> // If we broke out of the loop early, then the packet is for a link
> that is already open
> if (i < MAX_TFTP_LINKS) {
> // iLinkSlot is the index of the link this packet belongs too
> TFtpStateMachine( wSrcPort, iLinkSlot, pwUDPData, cwUDPDataLength );
> }
> // Check to see if someone is trying to start a new connection,
> // If so, guarantee that there are always TFTP_TX_LINKS link(s)
> available to transmit information
> else if (wDestPort == wOdoWellKnownServerPort && MAX_TFTP_LINKS -
> nNumTFtpLinksInUse > TFTP_TX_LINKS) {
>
> // iLinkSlot is the index of a link that is in the IDLE state, giving
> the number of a free link
> // slot that can be used, the wDestTID and the TFTP Message
> TFtpdFormNewLink( pMyAddr, pFrameBuffer, iLinkSlot, pwUDPData );
> return 1;
> }
> else {
>
> for( i = 0; i < MAX_TFTP_LINKS; i++ ) {
> EdbgOutputDebugString("TFTP link[%u]: State:%u,
> DestAddr.wPort: %u, SrcAddr.wPort: %u\n",
> i,TFtpLinks[i].State,
> ntohs(TFtpLinks[i].DestAddr.wPort),
> ntohs(TFtpLinks[i].SrcAddr.wPort));
> }
> EdbgOutputDebugString("TftpReceiver, port: 0x%X, wkp:
> 0x%X\n\r",wDestPort,wOdoWellKnownServerPort);
> }
>
> return 0;
>
> } // TFtpReceiver()
>
>
> //------------------------------------------------------------------------------
> //
> // Function Name: EbootCheckUD(...)
> // Description..: This routine will check a UDP frame that has been
> received.
> // It will make sure that it was for our IP address
> and that
> // the checksums are right and that it's a UDP packet.
> If
> // something is wrong, the packet will be discarded
> and the
> // routine will return non-zero. If everything is
> right,
> // then all the port and IP information will be filled
> out and
> // the routine will return 0. Note that if we are
> doing the
> // DHCP process, the DHCP server will send the OFFER
> packet to
> // the IP address that it would like to give us. We
> have to
> // be able to accept a packet for any IP address in
> that
> // case. This condition is signaled to the routine by
>
> // fPromiscuousIP == 1, which is set using
> SetPromiscuousIP()
> //
> // Inputs.......: EDBG_ADDR * pntr to address
> // BYTE * pntr to frame
> // UINT16 * pntr to dst addr
> // UINT16 * pntr to src addr
> // UINT16 ** pntr to pntr to data
> // UINT16 * pntr to data length
> // Outputs......: 0 on success, non zero on failure
> //
> //------------------------------------------------------------------------------
>
> UINT16 EbootCheckUDP( EDBG_ADDR *pMyAddr,
> BYTE *pFrameBuffer,
> UINT16 *wDestPort,
> UINT16 *wSrcPort,
> UINT16 **pwData,
> UINT16 *cwLength )
> {
> IPHeaderFormat *pIPHeader;
> UDPPseudoHeaderFormat UDPPseudoHeader;
> UDPHeaderFormat *pUDPHeader;
>
> // Note that I don't do any checking that depends on a length field
>
> // in the packet until after the CRC is verified for that data.
> // This prevents the code from running past the end of buffers,
> etc.
> // when a bad packet is received.
> EdbgOutputDebugString ("+EbootCheckUDP\r\n");
> pIPHeader = (IPHeaderFormat *)(pFrameBuffer +
> sizeof(EthernetFrameHeader));
>
> // Make sure that it was for our IP address, unless we're
> // doing DHCP (indicated by fPromiscuousIP == 1)
>
> if( !fPromiscuousIP && pIPHeader->dwDestIP != pMyAddr->dwIP )
> {
> // EdbgOutputDebugString(
> // "!CheckUDP: Not our IP (0x%X)\n",pIPHeader->dwDestIP);
> EdbgOutputDebugString ("zjwzjwzjw return 1\r\n");
> EdbgOutputDebugString("%s\r\n", inet_ntoa(pIPHeader->dwDestIP));
> EdbgOutputDebugString("%s\r\n", inet_ntoa(pMyAddr->dwIP));
> if(fPromiscuousIP)
> {
> EdbgOutputDebugString ("DHCP is ON ! WRONG!!!\r\n");
> }
> return( 1 );
> }
>
> // Make sure that it is a UDP packet
>
> if( pIPHeader->bProtocol != 17 )
> {
> EdbgOutputDebugString( "!CheckUDP: Not UDP (proto = 0x%X)\n",
> pIPHeader->bProtocol );
>
> return( 2 );
> }
>
> // Check the IP header checksum
>
> if( CRC( (UINT16 *)pIPHeader, sizeof(IPHeaderFormat), NULL, 0 ) !=
> 0 )
> {
> EdbgOutputDebugString( "!CheckUDP: IP header checksum
> failure\n" );
> return( 3 );
> }
>
> // Build the UDP Pseudo Header
>
> UDPPseudoHeader.dwSrcIP = pIPHeader->dwSrcIP;
> UDPPseudoHeader.dwDestIP = pIPHeader->dwDestIP;
> UDPPseudoHeader.bZero = 0;
> UDPPseudoHeader.bProtocol = 17; // UDP Proto is 17
> UDPPseudoHeader.cwTotalUDPLength =
> htons( htons(pIPHeader->cwTotalLength) - sizeof( IPHeaderFormat
> ));
>
> // Check the UDP checksum, I'm using the cwTotalUDPLength
> // calculated from the IP header info because we know that
> // it's not corrupted and won't give an outrageous length for the
> packet
>
> pUDPHeader = (UDPHeaderFormat *)((BYTE
> *)pIPHeader+sizeof(IPHeaderFormat));
>
> if( pUDPHeader->wCRC != 0 &&
> CRC( (UINT16 *)&UDPPseudoHeader,
> sizeof(UDPPseudoHeader),
> (UINT16 *)pUDPHeader,
> ntohs(UDPPseudoHeader.cwTotalUDPLength) ) != 0 )
> {
> EdbgOutputDebugString( "!CheckUDP: UDP header checksum
> failure\n" );
> return( 4 );
> }
>
> // Now we know we have a good packet, fill out the fields
>
> *wDestPort = pUDPHeader->wDestPort;
> *wSrcPort = pUDPHeader->wSrcPort;
> *pwData = (UINT16 *)((BYTE *)pUDPHeader + sizeof(UDPHeaderFormat));
> *cwLength = htons(pUDPHeader->cwTotalUDPLength) -
> sizeof(UDPHeaderFormat);
>
> // Indicate success
>
> return( 0 );
> }


Re: bootme problem by ali88z

ali88z
Thu Oct 26 21:31:48 CDT 2006

Yes, I'm sure about it.
Henrik Viklund wrote:
> First thing you should do is to make sure there's no firewall messing
> with the comunication.
>
> Henrik Viklund
> http://www.addlogic.se
>
> ali88z@gmail.com wrote:
> > something wrong, paste one more time
> >
> > I build a bootloader, it can send bootme well and the PB5.0 can reply
> > to it too. But here is a stange problem, bootloader can accept
> > destination 59.77.17.255 UDP packet but can't accept destination
> > 59.77.17.100 UDP packet, which is its IP.
> > Anytime the program comes to EbootTFtpReceiver, the packet must be from
> > 59.77.17.255, so can't go on.
> > It seems to me that, if IP is 59.77.17.255 every thing works as normal,
> > but if it's 59.77.17.100, bootloader works as if there is no frame
> > arrived. Anyone can help me? I have debugged it for ond day.
> >
> > The code below is cut from my sourcecode. I add a lot of
> > EdbgOutputDebugString which is used for debug, don't care about it.
> >
> > UINT16 LAN91CGetFrame(UINT8 *pBuffer, UINT16 *pLength)
> > {
> > UINT8 *pos = pBuffer;
> > UINT16 code, pointer;
> > UINT32 length, count;
> > EdbgOutputDebugString ("+LAN91CGetFrame");
> > // Make sure that bank 2 is actual
> > OUTPORT16(&g_pLAN91C->BANKSEL, 2);
> >
> > length = 0;
> > while ((INPORT16(&g_pLAN91C->INTR) & INTR_RX) != 0) {
> > EdbgOutputDebugString ("+LAN91CGetFrame while\r\n");
> > // Setup pointer address register
> > pointer = PTR_RCV | PTR_READ;
> >
> > // Read status
> > OUTPORT16(&g_pLAN91C->PTR, pointer);
> > code = INPORT16(&g_pLAN91C->DATA);
> > pointer += sizeof(UINT16);
> >
> > if ((code & (STAT_ALGNERR|STAT_BADCRC|STAT_LONG|STAT_SHORT)) ==
> > 0) {
> >
> > // Get packet size
> > OUTPORT16(&g_pLAN91C->PTR, pointer);
> > length = (INPORT16(&g_pLAN91C->DATA) & 0x07FF) - 6;
> > pointer += sizeof(UINT16);
> >
> > // Copy packet
> > count = length;
> > while (count > 1) {
> > OUTPORT16(&g_pLAN91C->PTR, pointer);
> > *(UINT16*)pos = INPORT16(&g_pLAN91C->DATA);
> > pointer += sizeof(UINT16);
> > pos += sizeof(UINT16);
> > count -= sizeof(UINT16);
> > }
> >
> > // Get control word (which can contain last byte)
> > OUTPORT16(&g_pLAN91C->PTR, pointer);
> > code = INPORT16(&g_pLAN91C->DATA);
> > pointer += sizeof(UINT16);
> > if ((code & CTRL_ODD) != 0) {
> > length++;
> > *pos = (UINT8)code;
> > }
> > }
> >
> > // Release the memory for the received frame
> > switch (GET_CHIP_ID(g_chipRevision)) {
> > case CHIP_ID_LAN91C111:
> > OUTPORT16(&g_pLAN91C->MMUCR, MMUCR_111_REM_REL_RX);
> > break;
> > default:
> > OUTPORT16(&g_pLAN91C->MMUCR, MMUCR_REM_REL_TOP);
> > }
> >
> > while ((INPORT16(&g_pLAN91C->MMUCR) & MMUCR_BUSY) != 0);
> >
> > // If length is non zero we get a packet
> > if (length > 0) break;
> >
> > }
> > EdbgOutputDebugString ("hahahaha\r\n");
> > *pLength = (UINT16)length;
> > return (*pLength);
> > }
> >
> > pfnEDbgGetFrame = (PFN_EDBG_GET_FRAME) LAN91CGetFrame;
> >
> > BOOL OEMEthGetFrame(BYTE *pData, // OUT - Receives frame data
> > UINT16 *pwLength) // IN - Length of Rx buffer
> > {
> > EdbgOutputDebugString ("+OEMEthGetFrame\r\n");
> > return (pfnEDbgGetFrame(pData, pwLength));
> > }
> >
> >
> > BOOL EbootSendBootmeAndWaitForTftp (EDBG_ADDR *pEdbgAddr, UCHAR
> > VersionMajor, UCHAR VersionMinor,
> > char *szPlatformString, char
> > *szDeviceName,
> > UCHAR CPUId, DWORD dwBootFlags)
> > {
> > DWORD dwCurSec = OEMEthGetSecs () - BOOTME_INTERVAL;
> > USHORT wLen, wDestPort, wSrcPort, wUDPDataLen, *pwUDPData;
> > int nRetries = 0;
> > EdbgOutputDebugString ("+EbootSendBootmeAndWaitForTftp\r\n");
> > while (!fTftpLinked) {
> > EdbgOutputDebugString ("+while (!fTftpLinked)\r\n");
> > if ((nRetries < MAX_BOOTME_CNT) && (OEMEthGetSecs () - dwCurSec >=
> > BOOTME_INTERVAL)) {
> > nRetries ++;
> > dwCurSec += BOOTME_INTERVAL;
> > // send a bootme message
> > EbootSendBootme (pEdbgAddr, VersionMajor, VersionMinor,
> > szPlatformString, szDeviceName, CPUId, dwBootFlags);
> > }
> > // get another frame and pass it to TFTP handler
> > wLen = sizeof (gFrameBuffer);
> > if (OEMEthGetFrame (gFrameBuffer, &wLen)) { // frame
> > available?
> > switch (FRAMETYPE (gFrameBuffer)) {
> > case 0x0800: // IP packet
> > EdbgOutputDebugString ("+FRAMETYPE IP\r\n");
> > if (!EbootCheckUDP(pEdbgAddr, gFrameBuffer, &wDestPort, &wSrcPort,
> > &pwUDPData, &wUDPDataLen)) { // UDP?
> > // EDBG command? (should only occur if eshell asked
> > us to jump to existing image)
> > if (!EbootProcessEDBG (pEdbgAddr, &gHostAddr,
> > gFrameBuffer, pwUDPData, wUDPDataLen, &fTftpLinked, &gpCfgData)) {
> > // no, pass it to TFTP
> > EbootTFtpReceiver (pEdbgAddr, gFrameBuffer,
> > wDestPort, wSrcPort, pwUDPData, wUDPDataLen);
> > }
> > }
> > break;
> > case 0x0806: // ARP packet
> > EdbgOutputDebugString ("+FRAMETYPE ARP\r\n");
> > if (EbootProcessARP (pEdbgAddr, gFrameBuffer) ==
> > PROCESS_ARP_RESPONSE) {
> > EdbgOutputDebugString( "Some other station has IP
> > Address: %s !!! Aborting.\r\n", inet_ntoa(pEdbgAddr->dwIP));
> > return FALSE;
> > }
> > break;
> > default:
> > break;
> > }
> > }
> > }
> > EdbgOutputDebugString ("-EbootSendBootmeAndWaitForTftp\r\n");
> > return TRUE;
> > }
> >
> >
> >
> > // This routine handles the multiplexing of all active TFTP links. It
> > returns 0 if there was no valid link formed,
> > // or 1 of there was.
> > WORD EbootTFtpReceiver( EDBG_ADDR *pMyAddr, BYTE *pFrameBuffer, UINT16
> > wDestPort, UINT16 wSrcPort, UINT16 *pwUDPData, UINT16 cwUDPDataLength )
> > {
> >
> > int i;
> > UINT16 iLinkSlot = MAX_TFTP_LINKS;
> > EdbgOutputDebugString ("+EbootTFtpReceiver\r\n");
> > // Check to see if this is for a link that is currently in use
> > for( i = 0; i < MAX_TFTP_LINKS; i++ ) {
> > // Here I don't compare the destination (Odo) port, only the source
> > (host) because
> > // this could be a repeat open packet, which we don't want to cause a
> > second link.
> > // This could happen if a second open packet comes because we will
> > have changed the
> > // destination port with the acknowledge.
> > if (TFtpLinks[i].State != TFTP_STATE_IDLE && wSrcPort ==
> > TFtpLinks[i].DestAddr.wPort
> > && wDestPort == TFtpLinks[i].SrcAddr.wPort) {
> > iLinkSlot = i;
> > break;
> > }
> > else if (TFtpLinks[i].State == TFTP_STATE_IDLE)
> > iLinkSlot = i;
> > }
> >
> > // If we broke out of the loop early, then the packet is for a link
> > that is already open
> > if (i < MAX_TFTP_LINKS) {
> > // iLinkSlot is the index of the link this packet belongs too
> > TFtpStateMachine( wSrcPort, iLinkSlot, pwUDPData, cwUDPDataLength );
> > }
> > // Check to see if someone is trying to start a new connection,
> > // If so, guarantee that there are always TFTP_TX_LINKS link(s)
> > available to transmit information
> > else if (wDestPort == wOdoWellKnownServerPort && MAX_TFTP_LINKS -
> > nNumTFtpLinksInUse > TFTP_TX_LINKS) {
> >
> > // iLinkSlot is the index of a link that is in the IDLE state, giving
> > the number of a free link
> > // slot that can be used, the wDestTID and the TFTP Message
> > TFtpdFormNewLink( pMyAddr, pFrameBuffer, iLinkSlot, pwUDPData );
> > return 1;
> > }
> > else {
> >
> > for( i = 0; i < MAX_TFTP_LINKS; i++ ) {
> > EdbgOutputDebugString("TFTP link[%u]: State:%u,
> > DestAddr.wPort: %u, SrcAddr.wPort: %u\n",
> > i,TFtpLinks[i].State,
> > ntohs(TFtpLinks[i].DestAddr.wPort),
> > ntohs(TFtpLinks[i].SrcAddr.wPort));
> > }
> > EdbgOutputDebugString("TftpReceiver, port: 0x%X, wkp:
> > 0x%X\n\r",wDestPort,wOdoWellKnownServerPort);
> > }
> >
> > return 0;
> >
> > } // TFtpReceiver()
> >
> >
> > //------------------------------------------------------------------------------
> > //
> > // Function Name: EbootCheckUD(...)
> > // Description..: This routine will check a UDP frame that has been
> > received.
> > // It will make sure that it was for our IP address
> > and that
> > // the checksums are right and that it's a UDP packet.
> > If
> > // something is wrong, the packet will be discarded
> > and the
> > // routine will return non-zero. If everything is
> > right,
> > // then all the port and IP information will be filled
> > out and
> > // the routine will return 0. Note that if we are
> > doing the
> > // DHCP process, the DHCP server will send the OFFER
> > packet to
> > // the IP address that it would like to give us. We
> > have to
> > // be able to accept a packet for any IP address in
> > that
> > // case. This condition is signaled to the routine by
> >
> > // fPromiscuousIP == 1, which is set using
> > SetPromiscuousIP()
> > //
> > // Inputs.......: EDBG_ADDR * pntr to address
> > // BYTE * pntr to frame
> > // UINT16 * pntr to dst addr
> > // UINT16 * pntr to src addr
> > // UINT16 ** pntr to pntr to data
> > // UINT16 * pntr to data length
> > // Outputs......: 0 on success, non zero on failure
> > //
> > //------------------------------------------------------------------------------
> >
> > UINT16 EbootCheckUDP( EDBG_ADDR *pMyAddr,
> > BYTE *pFrameBuffer,
> > UINT16 *wDestPort,
> > UINT16 *wSrcPort,
> > UINT16 **pwData,
> > UINT16 *cwLength )
> > {
> > IPHeaderFormat *pIPHeader;
> > UDPPseudoHeaderFormat UDPPseudoHeader;
> > UDPHeaderFormat *pUDPHeader;
> >
> > // Note that I don't do any checking that depends on a length field
> >
> > // in the packet until after the CRC is verified for that data.
> > // This prevents the code from running past the end of buffers,
> > etc.
> > // when a bad packet is received.
> > EdbgOutputDebugString ("+EbootCheckUDP\r\n");
> > pIPHeader = (IPHeaderFormat *)(pFrameBuffer +
> > sizeof(EthernetFrameHeader));
> >
> > // Make sure that it was for our IP address, unless we're
> > // doing DHCP (indicated by fPromiscuousIP == 1)
> >
> > if( !fPromiscuousIP && pIPHeader->dwDestIP != pMyAddr->dwIP )
> > {
> > // EdbgOutputDebugString(
> > // "!CheckUDP: Not our IP (0x%X)\n",pIPHeader->dwDestIP);
> > EdbgOutputDebugString ("zjwzjwzjw return 1\r\n");
> > EdbgOutputDebugString("%s\r\n", inet_ntoa(pIPHeader->dwDestIP));
> > EdbgOutputDebugString("%s\r\n", inet_ntoa(pMyAddr->dwIP));
> > if(fPromiscuousIP)
> > {
> > EdbgOutputDebugString ("DHCP is ON ! WRONG!!!\r\n");
> > }
> > return( 1 );
> > }
> >
> > // Make sure that it is a UDP packet
> >
> > if( pIPHeader->bProtocol != 17 )
> > {
> > EdbgOutputDebugString( "!CheckUDP: Not UDP (proto = 0x%X)\n",
> > pIPHeader->bProtocol );
> >
> > return( 2 );
> > }
> >
> > // Check the IP header checksum
> >
> > if( CRC( (UINT16 *)pIPHeader, sizeof(IPHeaderFormat), NULL, 0 ) !=
> > 0 )
> > {