bootme problem

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



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 =
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 );}

.



Relevant Pages

  • RE: UDP recvmsg blocks after select(), 2.6 bug?
    ... >> X on protocol Y, where such guarantees constrict what the ... semantic difference between a UDP packet that was dropped and a UDP packet ... >> provided by the kernel, does not guarantee anything about the ...
    (Linux-Kernel)
  • Re: UDP recvmsg blocks after select(), 2.6 bug?
    ... We're talking about read of a packet. ... > semantic difference between a UDP packet that was dropped and a UDP packet ... packet was received, but is corrupt ... >> that selectnever be used with blocking file descriptors. ...
    (Linux-Kernel)
  • Re: Why some hosts in Internet not prefer to be traceroute-d ?
    ... i.e. not to send a TTL exceeded ICMP packet back to the host. ... This block may be not generating ICMP type 11 (most ... exceeded" reply associated with a UDP packet, ...
    (comp.os.linux.networking)
  • Re: Cant Resolve Certain internet DNS names
    ... >> Why are some websites using non-RFC compliant packets for DNS? ... > It is not websites it is your DNS server and it is RFC compliant. ... > queries do not fit into one UDP packet, it has always been that way. ... > into one UDP packet and will be trucated if even a few bytes of a DNS ...
    (microsoft.public.windows.server.dns)
  • Re: Cant Resolve Certain internet DNS names
    ... It is not websites it is your DNS server and it is RFC compliant. ... queries do not fit into one UDP packet, it has always been that way. ... > "SmartDefense is able to recognize an illegal DNS packet. ...
    (microsoft.public.windows.server.dns)