00001 00002 00003 00028 /********************************************************************* 00029 * Software License Agreement 00030 * 00031 * Copyright (C) 2002-2008 Microchip Technology Inc. All rights 00032 * reserved. 00033 * 00034 * Microchip licenses to you the right to use, modify, copy, and 00035 * distribute: 00036 * (i) the Software when embedded on a Microchip microcontroller or 00037 * digital signal controller product ("Device") which is 00038 * integrated into Licensee's product; or 00039 * (ii) ONLY the Software driver source files ENC28J60.c and 00040 * ENC28J60.h ported to a non-Microchip device used in 00041 * conjunction with a Microchip ethernet controller for the 00042 * sole purpose of interfacing with the ethernet controller. 00043 * 00044 * You should refer to the license agreement accompanying this 00045 * Software for additional information regarding your rights and 00046 * obligations. 00047 * 00048 * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT 00049 * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT 00050 * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A 00051 * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL 00052 * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR 00053 * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF 00054 * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS 00055 * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE 00056 * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER 00057 * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT 00058 * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE. 00059 * 00060 * 00061 * Author Date Comment 00062 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00063 * Nilesh Rajbharti 3/19/01 Original (Rev 1.0) 00064 * Nilesh Rajbharti 2/26/03 Fixed UDPGet and UDPProcess bugs 00065 * as discovered and fixed by John Owen 00066 * of Powerwave. 00067 * 1. UDPGet would return FALSE on last good byte 00068 * 2. UDPProcess was incorrectly calculating length. 00069 * Nilesh Rajbharti 5/19/03 Added bFirstRead flag similar to TCP 00070 * to detect very first UDPGet and 00071 * reset MAC Rx pointer to begining of 00072 * UDP data area. This would ensure that 00073 * if UDP socket has pending Rx data and 00074 * another module resets MAC Rx pointer, 00075 * next UDP socket Get would get correct 00076 * data. 00077 * Robert Sloan (RSS) 5/29/03 Improved FindMatchingSocket() 00078 * Nilesh Rajbharti 12/2/03 Added UDPChecksum logic in UDPProcess() 00079 * Nilesh Rajbharti 12/5/03 Modified UDPProcess() and FindMatchingSocket() 00080 * to include localIP as new parameter. 00081 * This corrects pseudo header checksum 00082 * logic in UDPProcess(). 00083 * It also corrects broadcast packet 00084 * matching correct in FindMatchingSocket(). 00085 * Howard Schlunder 1/16/06 Fixed an imporbable RX checksum bug 00086 * when using a Microchip Ethernet controller) 00087 * Howard Schlunder 6/02/06 Fixed a bug where all RXed UDP packets 00088 * without a checksum (0x0000) were thrown 00089 * away. No checksum is legal in UDP. 00090 * Howard Schlunder 8/10/06 Fixed a bug where UDP sockets would 00091 * unintentionally keep the remote MAC 00092 * address cached, even after calling 00093 * UDPInit(), UDPClose(), or reseting 00094 * the part without clearing all the 00095 * PIC memory. 00096 ********************************************************************/ 00097 #define __UDP_C 00098 00099 #include "TCPIP.h" 00100 #include "mdns.h" 00101 00102 00103 /**************************************************************************** 00104 Section: 00105 Configuration Parameters 00106 ***************************************************************************/ 00107 00108 // First port number for randomized local port number selection 00109 #define LOCAL_UDP_PORT_START_NUMBER (4096u) 00110 00111 // Last port number for randomized local port number selection 00112 #define LOCAL_UDP_PORT_END_NUMBER (8192u) 00113 00114 /**************************************************************************** 00115 Section: 00116 UDP Global Variables 00117 ***************************************************************************/ 00118 00119 // Stores an array of information pertaining to each UDP socket 00120 UDP_SOCKET_INFO UDPSocketInfo[MAX_UDP_SOCKETS]; 00121 00122 // Indicates which UDP socket is currently active 00123 UDP_SOCKET activeUDPSocket; 00124 00125 WORD UDPTxCount; // Number of bytes written to this UDP segment 00126 WORD UDPRxCount; // Number of bytes read from this UDP segment 00127 static UDP_SOCKET LastPutSocket = INVALID_UDP_SOCKET; // Indicates the last socket to which data was written 00128 static WORD wPutOffset; // Offset from beginning of payload where data is to be written. 00129 static WORD wGetOffset; // Offset from beginning of payload from where data is to be read. 00130 00131 // Stores various flags for the UDP module 00132 static struct 00133 { 00134 unsigned char bFirstRead : 1; // No data has been read from this segment yet 00135 unsigned char bWasDiscarded : 1; // The data in this segment has been discarded 00136 } Flags; 00137 00138 // Indicates which socket has currently received data for this loop 00139 static UDP_SOCKET SocketWithRxData = INVALID_UDP_SOCKET; 00140 00141 /**************************************************************************** 00142 Section: 00143 Function Prototypes 00144 ***************************************************************************/ 00145 00146 static UDP_SOCKET FindMatchingSocket(UDP_HEADER *h, NODE_INFO *remoteNode, 00147 IP_ADDR *localIP); 00148 00149 /**************************************************************************** 00150 Section: 00151 Connection Management Functions 00152 ***************************************************************************/ 00153 00154 /***************************************************************************** 00155 Function: 00156 void UDPInit(void) 00157 00158 Summary: 00159 Initializes the UDP module. 00160 00161 Description: 00162 Initializes the UDP module. This function initializes all the UDP 00163 sockets to the closed state. 00164 00165 Precondition: 00166 None 00167 00168 Parameters: 00169 None 00170 00171 Returns: 00172 None 00173 00174 Remarks: 00175 This function is called only one during lifetime of the application. 00176 ***************************************************************************/ 00177 void UDPInit(void) 00178 { 00179 UDP_SOCKET s; 00180 00181 for ( s = 0; s < MAX_UDP_SOCKETS; s++ ) 00182 { 00183 UDPClose(s); 00184 } 00185 Flags.bWasDiscarded = 1; 00186 } 00187 00188 00189 /***************************************************************************** 00190 Function: 00191 void UDPTask(void) 00192 00193 Summary: 00194 Performs state management and housekeeping for UDP. 00195 00196 Description: 00197 Performs state management and housekeeping for UDP. This is an internal 00198 function meant to be called by StackTask() (not a user API). 00199 00200 Precondition: 00201 None 00202 00203 Parameters: 00204 None 00205 00206 Return Values: 00207 None 00208 00209 Remarks: 00210 UDPTask() is called once per StackTask() iteration to ensure that calls 00211 to UDPIsPutReady() always update the Ethernet Write pointer location 00212 between StackTask() iterations. 00213 ***************************************************************************/ 00214 void UDPTask(void) 00215 { 00216 LastPutSocket = INVALID_UDP_SOCKET; 00217 } 00218 00219 00220 /***************************************************************************** 00221 Function: 00222 UDP_SOCKET UDPOpen(UDP_PORT localPort, NODE_INFO* remoteNode, 00223 UDP_PORT remotePort) 00224 00225 Summary: 00226 Creates a UDP socket handle for transmiting or receiving UDP packets. 00227 00228 Description: 00229 Creates a UDP socket handle for transmiting or receiving UDP packets. 00230 Call this function to obtain a handle required by other UDP function. 00231 00232 Precondition: 00233 UDPInit() must have been previously called. 00234 00235 Parameters: 00236 localPort - UDP port number to listen on. If 0, stack will dynamically 00237 assign a unique port number to use. 00238 remoteNode - Pointer to remote node info (MAC and IP address) for this 00239 connection. If this is a server socket (receives the first packet) 00240 or the destination is the broadcast address, then this parameter 00241 should be NULL. 00242 remotePort - For client sockets, the remote port number. 00243 00244 Return Values: 00245 Success - 00246 A UDP socket handle that can be used for subsequent UDP API calls. 00247 Failure - 00248 INVALID_UDP_SOCKET. This function fails when no more UDP socket 00249 handles are available. Increase MAX_UDP_SOCKETS to make more sockets 00250 available. 00251 00252 Remarks: 00253 When finished using the UDP socket handle, call the UDPClose() function 00254 to free the socket and delete the handle. 00255 ***************************************************************************/ 00256 UDP_SOCKET UDPOpen(UDP_PORT localPort, 00257 NODE_INFO *remoteNode, 00258 UDP_PORT remotePort) 00259 { 00260 UDP_SOCKET s; 00261 UDP_SOCKET_INFO *p; 00262 00263 // Local temp port numbers. 00264 static WORD NextPort __attribute__((persistent)); 00265 00266 00267 p = UDPSocketInfo; 00268 for ( s = 0; s < MAX_UDP_SOCKETS; s++ ) 00269 { 00270 if(p->localPort == INVALID_UDP_PORT) 00271 { 00272 p->localPort = localPort; 00273 00274 if(localPort == 0x0000u) 00275 { 00276 if(NextPort > LOCAL_UDP_PORT_END_NUMBER || NextPort < LOCAL_UDP_PORT_START_NUMBER) 00277 NextPort = LOCAL_UDP_PORT_START_NUMBER; 00278 00279 p->localPort = NextPort++; 00280 } 00281 00282 // If remoteNode is supplied, remember it. 00283 if(remoteNode) 00284 { 00285 memcpy((void*)&p->remoteNode, 00286 (const void*)remoteNode, 00287 sizeof(p->remoteNode)); 00288 } 00289 else 00290 { 00291 // else Set broadcast address 00292 memset((void*)&p->remoteNode, 0xFF, sizeof(p->remoteNode)); 00293 } 00294 00295 p->remotePort = remotePort; 00296 00297 // Mark this socket as active. 00298 // Once an active socket is set, subsequent operation can be 00299 // done without explicitely supply socket identifier. 00300 activeUDPSocket = s; 00301 return s; 00302 } 00303 p++; 00304 } 00305 00306 return (UDP_SOCKET)INVALID_UDP_SOCKET; 00307 } 00308 00309 00310 00311 00312 /***************************************************************************** 00313 Function: 00314 void UDPClose(UDP_SOCKET s) 00315 00316 Summary: 00317 Closes a UDP socket and frees the handle. 00318 00319 Description: 00320 Closes a UDP socket and frees the handle. Call this function to release 00321 a socket and return it to the pool for use by future communications. 00322 00323 Precondition: 00324 UDPInit() must have been previously called. 00325 00326 Parameters: 00327 s - The socket handle to be released. 00328 00329 Returns: 00330 None 00331 00332 Remarks: 00333 This function does not affect the previously designated active socket. 00334 ***************************************************************************/ 00335 void UDPClose(UDP_SOCKET s) 00336 { 00337 if(s == INVALID_UDP_SOCKET) 00338 return; 00339 00340 UDPSocketInfo[s].localPort = INVALID_UDP_PORT; 00341 UDPSocketInfo[s].remoteNode.IPAddr.Val = 0x00000000; 00342 } 00343 00344 00345 /***************************************************************************** 00346 Function: 00347 void UDPSetTxBuffer(WORD wOffset) 00348 00349 Summary: 00350 Moves the pointer within the TX buffer. 00351 00352 Description: 00353 This function allows the write location within the TX buffer to be 00354 specified. Future calls to UDPPut, UDPPutArray, UDPPutString, etc will 00355 write data from the indicated location. 00356 00357 Precondition: 00358 UDPInit() must have been previously called and a socket is currently 00359 active. 00360 00361 Parameters: 00362 wOffset - Offset from beginning of UDP packet data payload to place the 00363 write pointer. 00364 00365 Returns: 00366 None 00367 ***************************************************************************/ 00368 void UDPSetTxBuffer(WORD wOffset) 00369 { 00370 IPSetTxBuffer(wOffset+sizeof(UDP_HEADER)); 00371 wPutOffset = wOffset; 00372 } 00373 00374 00375 /***************************************************************************** 00376 Function: 00377 void UDPSetRxBuffer(WORD wOffset) 00378 00379 Summary: 00380 Moves the pointer within the RX buffer. 00381 00382 Description: 00383 This function allows the read location within the RX buffer to be 00384 specified. Future calls to UDPGet and UDPGetArray will read data from 00385 the indicated location forward. 00386 00387 Precondition: 00388 UDPInit() must have been previously called and a socket is currently 00389 active. 00390 00391 Parameters: 00392 wOffset - Offset from beginning of UDP packet data payload to place the 00393 read pointer. 00394 00395 Returns: 00396 None 00397 ***************************************************************************/ 00398 void UDPSetRxBuffer(WORD wOffset) 00399 { 00400 IPSetRxBuffer(wOffset+sizeof(UDP_HEADER)); 00401 wGetOffset = wOffset; 00402 } 00403 00404 00405 00406 /**************************************************************************** 00407 Section: 00408 Transmit Functions 00409 ***************************************************************************/ 00410 00411 /***************************************************************************** 00412 Function: 00413 WORD UDPIsPutReady(UDP_SOCKET s) 00414 00415 Summary: 00416 Determines how many bytes can be written to the UDP socket. 00417 00418 Description: 00419 This function determines if bytes can be written to the specified UDP 00420 socket. It also prepares the UDP module for writing by setting the 00421 indicated socket as the currently active connection. 00422 00423 Precondition: 00424 UDPInit() must have been previously called. 00425 00426 Parameters: 00427 s - The socket to be made active 00428 00429 Returns: 00430 The number of bytes that can be written to this socket. 00431 ***************************************************************************/ 00432 WORD UDPIsPutReady(UDP_SOCKET s) 00433 { 00434 if(!MACIsTxReady()) 00435 return 0; 00436 00437 if(LastPutSocket != s) 00438 { 00439 LastPutSocket = s; 00440 UDPTxCount = 0; 00441 UDPSetTxBuffer(0); 00442 } 00443 00444 activeUDPSocket = s; 00445 00446 return MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER) - UDPTxCount; 00447 } 00448 00449 /***************************************************************************** 00450 Function: 00451 BOOL UDPPut(BYTE v) 00452 00453 Summary: 00454 Writes a byte to the currently active socket. 00455 00456 Description: 00457 This function writes a single byte to the currently active UDP socket, 00458 while incrementing the buffer length. UDPIsPutReady should be used 00459 before calling this function to specify the currently active socket. 00460 00461 Precondition: 00462 UDPIsPutReady() was previously called to specify the current socket. 00463 00464 Parameters: 00465 v - The byte to be loaded into the transmit buffer. 00466 00467 Return Values: 00468 TRUE - The byte was successfully written to the socket. 00469 FALSE - The transmit buffer is already full and so the write failed. 00470 ***************************************************************************/ 00471 BOOL UDPPut(BYTE v) 00472 { 00473 // See if we are out of transmit space. 00474 if(wPutOffset >= (MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER))) 00475 { 00476 return FALSE; 00477 } 00478 00479 // Load application data byte 00480 MACPut(v); 00481 wPutOffset++; 00482 if(wPutOffset > UDPTxCount) 00483 UDPTxCount = wPutOffset; 00484 00485 return TRUE; 00486 } 00487 00488 /***************************************************************************** 00489 Function: 00490 WORD UDPPutArray(BYTE *cData, WORD wDataLen) 00491 00492 Summary: 00493 Writes an array of bytes to the currently active socket. 00494 00495 Description: 00496 This function writes an array of bytes to the currently active UDP socket, 00497 while incrementing the buffer length. UDPIsPutReady should be used 00498 before calling this function to specify the currently active socket. 00499 00500 Precondition: 00501 UDPIsPutReady() was previously called to specify the current socket. 00502 00503 Parameters: 00504 cData - The array to write to the socket. 00505 wDateLen - Number of bytes from cData to be written. 00506 00507 Returns: 00508 The number of bytes successfully placed in the UDP transmit buffer. If 00509 this value is less than wDataLen, then the buffer became full and the 00510 input was truncated. 00511 ***************************************************************************/ 00512 WORD UDPPutArray(BYTE *cData, WORD wDataLen) 00513 { 00514 WORD wTemp; 00515 00516 wTemp = (MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER)) - wPutOffset; 00517 if(wTemp < wDataLen) 00518 wDataLen = wTemp; 00519 00520 wPutOffset += wDataLen; 00521 if(wPutOffset > UDPTxCount) 00522 UDPTxCount = wPutOffset; 00523 00524 // Load application data bytes 00525 MACPutArray(cData, wDataLen); 00526 00527 return wDataLen; 00528 } 00529 00530 /***************************************************************************** 00531 Function: 00532 WORD UDPPutROMArray(ROM BYTE *cData, WORD wDataLen) 00533 00534 Summary: 00535 Writes an array of bytes from ROM to the currently active socket. 00536 00537 Description: 00538 This function writes an array of bytes from ROM to the currently active 00539 UDP socket, while incrementing the buffer length. UDPIsPutReady should 00540 be used before calling this function to specify the currently active 00541 socket. 00542 00543 Precondition: 00544 UDPIsPutReady() was previously called to specify the current socket. 00545 00546 Parameters: 00547 cData - The array to write to the socket. 00548 wDateLen - Number of bytes from cData to be written. 00549 00550 Returns: 00551 The number of bytes successfully placed in the UDP transmit buffer. If 00552 this value is less than wDataLen, then the buffer became full and the 00553 input was truncated. 00554 00555 Remarks: 00556 This function is aliased to UDPPutArray on non-PIC18 platforms. 00557 ***************************************************************************/ 00558 #if defined(__18CXX) 00559 WORD UDPPutROMArray(ROM BYTE *cData, WORD wDataLen) 00560 { 00561 WORD wTemp; 00562 00563 wTemp = (MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER)) - wPutOffset; 00564 if(wTemp < wDataLen) 00565 wDataLen = wTemp; 00566 00567 wPutOffset += wDataLen; 00568 if(wPutOffset > UDPTxCount) 00569 UDPTxCount = wPutOffset; 00570 00571 // Load application data bytes 00572 MACPutROMArray(cData, wDataLen); 00573 00574 return wDataLen; 00575 } 00576 #endif 00577 00578 /***************************************************************************** 00579 Function: 00580 BYTE* UDPPutString(BYTE *strData) 00581 00582 Summary: 00583 Writes null-terminated string to the currently active socket. 00584 00585 Description: 00586 This function writes a null-terminated string to the currently active 00587 UDP socket, while incrementing the buffer length. UDPIsPutReady should 00588 be used before calling this function to specify the currently active 00589 socket. 00590 00591 Precondition: 00592 UDPIsPutReady() was previously called to specify the current socket. 00593 00594 Parameters: 00595 cData - Pointer to the string to be written to the socket. 00596 00597 Returns: 00598 A pointer to the byte following the last byte written. Note that this 00599 is different than the UDPPutArray functions. If this pointer does not 00600 dereference to a NULL byte, then the buffer became full and the input 00601 data was truncated. 00602 ***************************************************************************/ 00603 BYTE* UDPPutString(BYTE *strData) 00604 { 00605 return strData + UDPPutArray(strData, strlen((char*)strData)); 00606 } 00607 00608 /***************************************************************************** 00609 Function: 00610 BYTE* UDPPutString(BYTE *strData) 00611 00612 Summary: 00613 Writes null-terminated string from ROM to the currently active socket. 00614 00615 Description: 00616 This function writes a null-terminated string from ROM to the currently 00617 active UDP socket, while incrementing the buffer length. UDPIsPutReady 00618 should be used before calling this function to specify the currently 00619 active socket. 00620 00621 Precondition: 00622 UDPIsPutReady() was previously called to specify the current socket. 00623 00624 Parameters: 00625 cData - Pointer to the string to be written to the socket. 00626 00627 Returns: 00628 A pointer to the byte following the last byte written. Note that this 00629 is different than the UDPPutArray functions. If this pointer does not 00630 dereference to a NULL byte, then the buffer became full and the input 00631 data was truncated. 00632 00633 Remarks: 00634 This function is aliased to UDPPutString on non-PIC18 platforms. 00635 ***************************************************************************/ 00636 #if defined(__18CXX) 00637 ROM BYTE* UDPPutROMString(ROM BYTE *strData) 00638 { 00639 return strData + UDPPutROMArray(strData, strlenpgm((ROM char*)strData)); 00640 } 00641 #endif 00642 00643 /***************************************************************************** 00644 Function: 00645 void UDPFlush(void) 00646 00647 Summary: 00648 Transmits all pending data in a UDP socket. 00649 00650 Description: 00651 This function builds a UDP packet with the pending TX data and marks it 00652 for transmission over the network interface. Since UDP is a frame-based 00653 protocol, this function must be called before returning to the main 00654 stack loop whenever any data is written. 00655 00656 Precondition: 00657 UDPIsPutReady() was previously called to specify the current socket, and 00658 data has been written to the socket using the UDPPut family of functions. 00659 00660 Parameters: 00661 None 00662 00663 Returns: 00664 None 00665 00666 Remarks: 00667 Note that unlike TCPFlush, UDPFlush must be called before returning to 00668 the main stack loop. There is no auto transmit for UDP segments. 00669 ***************************************************************************/ 00670 void UDPFlush(void) 00671 { 00672 UDP_HEADER h; 00673 UDP_SOCKET_INFO *p; 00674 WORD wReadPtrSave; 00675 WORD wChecksum; 00676 WORD wUDPLength; 00677 00678 p = &UDPSocketInfo[activeUDPSocket]; 00679 00680 wUDPLength = UDPTxCount + sizeof(UDP_HEADER); 00681 00682 // Generate the correct UDP header 00683 h.SourcePort = swaps(p->localPort); 00684 h.DestinationPort = swaps(p->remotePort); 00685 h.Length = swaps(wUDPLength); 00686 h.Checksum = 0x0000; 00687 00688 // Calculate IP pseudoheader checksum if we are going to enable 00689 // the checksum field 00690 #if defined(UDP_USE_TX_CHECKSUM) 00691 { 00692 PSEUDO_HEADER pseudoHeader; 00693 00694 // MODIFIX: Use the eWicht structure sIPConfig. 00695 pseudoHeader.SourceAddress = sIPConfig.MyIPAddr; 00696 pseudoHeader.DestAddress = p->remoteNode.IPAddr; 00697 pseudoHeader.Zero = 0x0; 00698 pseudoHeader.Protocol = IP_PROT_UDP; 00699 pseudoHeader.Length = wUDPLength; 00700 SwapPseudoHeader(pseudoHeader); 00701 h.Checksum = ~CalcIPChecksum((BYTE*)&pseudoHeader, sizeof(pseudoHeader)); 00702 } 00703 #endif 00704 00705 // Position the hardware write pointer where we will need to 00706 // begin writing the IP header 00707 MACSetWritePtr(BASE_TX_ADDR + sizeof(ETHER_HEADER)); 00708 00709 // Write IP header to packet 00710 IPPutHeader(&p->remoteNode, IP_PROT_UDP, wUDPLength); 00711 00712 // Write UDP header to packet 00713 MACPutArray((BYTE*)&h, sizeof(h)); 00714 00715 // Calculate the final UDP checksum and write it in, if enabled 00716 #if defined(UDP_USE_TX_CHECKSUM) 00717 { 00718 wReadPtrSave = MACSetReadPtr(BASE_TX_ADDR + sizeof(ETHER_HEADER) + sizeof(IP_HEADER)); 00719 wChecksum = CalcIPBufferChecksum(wUDPLength); 00720 MACSetReadPtr(wReadPtrSave); 00721 MACSetWritePtr(BASE_TX_ADDR + sizeof(ETHER_HEADER) + sizeof(IP_HEADER) + 6); // 6 is the offset to the Checksum field in UDP_HEADER 00722 MACPutArray((BYTE*)&wChecksum, sizeof(wChecksum)); 00723 } 00724 #endif 00725 00726 // Transmit the packet 00727 MACFlush(); 00728 00729 // Reset packet size counter for the next TX operation 00730 UDPTxCount = 0; 00731 LastPutSocket = INVALID_UDP_SOCKET; 00732 } 00733 00734 00735 00736 /**************************************************************************** 00737 Section: 00738 Receive Functions 00739 ***************************************************************************/ 00740 00741 /***************************************************************************** 00742 Function: 00743 WORD UDPIsGetReady(UDP_SOCKET s) 00744 00745 Summary: 00746 Determines how many bytes can be read from the UDP socket. 00747 00748 Description: 00749 This function determines if bytes can be read from the specified UDP 00750 socket. It also prepares the UDP module for reading by setting the 00751 indicated socket as the currently active connection. 00752 00753 Precondition: 00754 UDPInit() must have been previously called. 00755 00756 Parameters: 00757 s - The socket to be made active (which has already been opened or is 00758 listening) 00759 00760 Returns: 00761 The number of bytes that can be read from this socket. 00762 ***************************************************************************/ 00763 WORD UDPIsGetReady(UDP_SOCKET s) 00764 { 00765 activeUDPSocket = s; 00766 if(SocketWithRxData != s) 00767 return 0; 00768 00769 // If this is the very first time we are accessing this packet, 00770 // move the read point to the begining of the packet. 00771 if(Flags.bFirstRead) 00772 { 00773 Flags.bFirstRead = 0; 00774 UDPSetRxBuffer(0); 00775 } 00776 00777 return UDPRxCount; 00778 } 00779 00780 /***************************************************************************** 00781 Function: 00782 BOOL UDPGet(BYTE *v) 00783 00784 Summary: 00785 Reads a byte from the currently active socket. 00786 00787 Description: 00788 This function reads a single byte from the currently active UDP socket, 00789 while decrementing the remaining buffer length. UDPIsGetReady should be 00790 used before calling this function to specify the currently active socket. 00791 00792 Precondition: 00793 UDPIsGetReady() was previously called to specify the current socket. 00794 00795 Parameters: 00796 v - The buffer to receive the data being read. 00797 00798 Return Values: 00799 TRUE - A byte was successfully read 00800 FALSE - No data remained in the read buffer 00801 ***************************************************************************/ 00802 BOOL UDPGet(BYTE *v) 00803 { 00804 // Make sure that there is data to return 00805 if((wGetOffset >= UDPRxCount) || (SocketWithRxData != activeUDPSocket)) 00806 return FALSE; 00807 00808 *v = MACGet(); 00809 wGetOffset++; 00810 00811 return TRUE; 00812 } 00813 00814 00815 /***************************************************************************** 00816 Function: 00817 WORD UDPGetArray(BYTE *cData, WORD wDataLen) 00818 00819 Summary: 00820 Reads an array of bytes from the currently active socket. 00821 00822 Description: 00823 This function reads an array from bytes to the currently active UDP socket, 00824 while decrementing the remaining buffer length. UDPIsGetReady should be 00825 used before calling this function to specify the currently active socket. 00826 00827 Precondition: 00828 UDPIsPutReady() was previously called to specify the current socket. 00829 00830 Parameters: 00831 cData - The buffer to receive the bytes being read. 00832 wDateLen - Number of bytes to be read from the socket. 00833 00834 Returns: 00835 The number of bytes successfully read from the UDP buffer. If this 00836 value is less than wDataLen, then the buffer was emptied and no more 00837 data is available. 00838 ***************************************************************************/ 00839 WORD UDPGetArray(BYTE *cData, WORD wDataLen) 00840 { 00841 WORD wBytesAvailable; 00842 00843 // Make sure that there is data to return 00844 if((wGetOffset >= UDPRxCount) || (SocketWithRxData != activeUDPSocket)) 00845 return 0; 00846 00847 // Make sure we don't try to read more data than exists 00848 wBytesAvailable = UDPRxCount - wGetOffset; 00849 if(wBytesAvailable < wDataLen) 00850 wDataLen = wBytesAvailable; 00851 00852 wDataLen = MACGetArray(cData, wDataLen); 00853 wGetOffset += wDataLen; 00854 00855 return wDataLen; 00856 } 00857 00858 /***************************************************************************** 00859 Function: 00860 void UDPDiscard(void) 00861 00862 Summary: 00863 Discards any remaining RX data from a UDP socket. 00864 00865 Description: 00866 This function discards any remaining received data in the currently 00867 active UDP socket. 00868 00869 Precondition: 00870 UDPIsGetReady() was previously called to select the currently active 00871 socket. 00872 00873 Parameters: 00874 None 00875 00876 Returns: 00877 None 00878 00879 Remarks: 00880 It is safe to call this function more than is necessary. If no data is 00881 available, this function does nothing. 00882 ***************************************************************************/ 00883 void UDPDiscard(void) 00884 { 00885 if(!Flags.bWasDiscarded) 00886 { 00887 MACDiscardRx(); 00888 UDPRxCount = 0; 00889 Flags.bWasDiscarded = 1; 00890 } 00891 } 00892 00893 00894 00895 /**************************************************************************** 00896 Section: 00897 Data Processing Functions 00898 ***************************************************************************/ 00899 00900 /***************************************************************************** 00901 Function: 00902 BOOL UDPProcess(NODE_INFO *remoteNode, IP_ADDR *localIP, WORD len) 00903 00904 Summary: 00905 Handles an incoming UDP segment. 00906 00907 Description: 00908 This function handles an incoming UDP segment to determine if it is 00909 acceptable and should be handed to one of the stack applications for 00910 processing. 00911 00912 Precondition: 00913 UDPInit() has been called an a UDP segment is ready in the MAC buffer. 00914 00915 Parameters: 00916 remoteNode - The remote node that sent this segment. 00917 localIP - The destination IP address for this segment. 00918 len - Total length of the UDP segment. 00919 00920 Return Values: 00921 TRUE - A valid packet is waiting and the stack applications should be 00922 called to handle it. 00923 FALSE - The packet was discarded. 00924 ***************************************************************************/ 00925 00926 BOOL UDPProcess(NODE_INFO *remoteNode, IP_ADDR *localIP, WORD len) 00927 { 00928 UDP_HEADER h; 00929 UDP_SOCKET s; 00930 PSEUDO_HEADER pseudoHeader; 00931 DWORD_VAL checksums; 00932 00933 // MODIFIX: Check for valid IP addresses here, else return! 00934 // Valid IP addresses: 00935 // 1) Broadcast (255.255.255.255) 00936 // 2) Multicast (All in-between 224.0.0.0 and 239.255.255.255) 00937 // 3) Network-Broadcast (i.e for a 192.168.1/24 network this is 192.168.1.255) 00938 // -> not supported and therefore commented out. 00939 // 4) Unicast with matching IP address. 00940 if ((localIP->Val != 0xFFFFFFFFul) && 00941 ((localIP->v[0] < 224) || (localIP->v[0] > 239)) && 00942 // (localIP->Val != (sIPConfig.MyIPAddr.Val | (~sIPConfig.MyMask.Val))) && 00943 (localIP->Val != sIPConfig.MyIPAddr.Val)) 00944 { 00945 return FALSE; 00946 } 00947 00948 00949 SocketWithRxData = INVALID_UDP_SOCKET; 00950 UDPRxCount = 0; 00951 00952 // Retrieve UDP header. 00953 MACGetArray((BYTE*)&h, sizeof(h)); 00954 00955 h.SourcePort = swaps(h.SourcePort); 00956 h.DestinationPort = swaps(h.DestinationPort); 00957 h.Length = swaps(h.Length) - sizeof(UDP_HEADER); 00958 00959 // See if we need to validate the checksum field (0x0000 is disabled) 00960 if(h.Checksum) 00961 { 00962 // Calculate IP pseudoheader checksum. 00963 pseudoHeader.SourceAddress = remoteNode->IPAddr; 00964 pseudoHeader.DestAddress.Val = localIP->Val; 00965 pseudoHeader.Zero = 0x0; 00966 pseudoHeader.Protocol = IP_PROT_UDP; 00967 pseudoHeader.Length = len; 00968 00969 SwapPseudoHeader(pseudoHeader); 00970 00971 checksums.w[0] = ~CalcIPChecksum((BYTE*)&pseudoHeader, 00972 sizeof(pseudoHeader)); 00973 00974 00975 // Now calculate UDP packet checksum in NIC RAM -- should match pseudoHeader 00976 IPSetRxBuffer(0); 00977 checksums.w[1] = CalcIPBufferChecksum(len); 00978 00979 if(checksums.w[0] != checksums.w[1]) 00980 { 00981 MACDiscardRx(); 00982 return FALSE; 00983 } 00984 } 00985 00986 s = FindMatchingSocket(&h, remoteNode, localIP); 00987 if(s == INVALID_UDP_SOCKET) 00988 { 00989 // If there is no matching socket, There is no one to handle 00990 // this data. Discard it. 00991 MACDiscardRx(); 00992 return FALSE; 00993 } 00994 else 00995 { 00996 SocketWithRxData = s; 00997 UDPRxCount = h.Length; 00998 Flags.bFirstRead = 1; 00999 Flags.bWasDiscarded = 0; 01000 } 01001 01002 // MODIFIX: Add this request for a quick processing of the MDNS frames. 01003 // Especially the remote node and destination data is needed by MDNS 01004 // responder for answering via MDNS unicasts. 01005 if(UDPSocketInfo[s].remotePort == MDNS_PORT) 01006 { 01007 MDNSProcessFrame(remoteNode, localIP); 01008 return FALSE; 01009 } 01010 01011 return TRUE; 01012 } 01013 01014 /***************************************************************************** 01015 Function: 01016 static UDP_SOCKET FindMatchingSocket(UDP_HEADER *h, NODE_INFO *remoteNode, 01017 IP_ADDR *localIP) 01018 01019 Summary: 01020 Matches an incoming UDP segment to a currently active socket. 01021 01022 Description: 01023 This function attempts to match an incoming UDP segment to a currently 01024 active socket for processing. 01025 01026 Precondition: 01027 UDP segment header and IP header have both been retrieved. 01028 01029 Parameters: 01030 h - The UDP header that was received. 01031 remoteNode - IP and MAC of the remote node that sent this segment. 01032 localIP - IP address that this segment was destined for. 01033 01034 Returns: 01035 A UDP_SOCKET handle of a matching socket, or INVALID_UDP_SOCKET when no 01036 match could be made. 01037 ***************************************************************************/ 01038 static UDP_SOCKET FindMatchingSocket(UDP_HEADER *h, 01039 NODE_INFO *remoteNode, 01040 IP_ADDR *localIP) 01041 { 01042 UDP_SOCKET s; 01043 UDP_SOCKET partialMatch; 01044 UDP_SOCKET_INFO *p; 01045 01046 partialMatch = INVALID_UDP_SOCKET; 01047 01048 p = UDPSocketInfo; 01049 for ( s = 0; s < MAX_UDP_SOCKETS; s++ ) 01050 { 01051 // This packet is said to be matching with current socket: 01052 // 1. If its destination port matches with our local port and 01053 // 2. Packet source IP address matches with socket remote IP address. 01054 // OR this socket had transmitted packet with destination address as broadcast (subnet or limited broadcast). 01055 if ( p->localPort == h->DestinationPort ) 01056 { 01057 if(p->remotePort == h->SourcePort) 01058 { 01059 // MODIFIX: Special handling for MDNS frames: 01060 if (p->remotePort == MDNS_PORT) 01061 { 01062 return s; 01063 } 01064 01065 // MODIFIX: Removed the IP request, is done before. 01066 if (p->remoteNode.IPAddr.Val == remoteNode->IPAddr.Val) 01067 { 01068 return s; 01069 } 01070 } 01071 01072 partialMatch = s; 01073 } 01074 p++; 01075 } 01076 01077 if ( partialMatch != INVALID_UDP_SOCKET ) 01078 { 01079 p = &UDPSocketInfo[partialMatch]; 01080 01081 memcpy((void*)&p->remoteNode, 01082 (const void*)remoteNode, sizeof(p->remoteNode)); 01083 01084 p->remotePort = h->SourcePort; 01085 } 01086 return partialMatch; 01087 } 01088 01089 01092 01093 // MODIFIX: Added the following function for retrieving the amount of already 01094 // put bytes. 01095 WORD UDPGetPutOffset(void) 01096 { 01097 return wPutOffset; 01098 } 01099 01102 // MODIFIX: Added the following function for retrieving the amount of already 01103 // got bytes. 01104 01105 WORD UDPGetGetOffset(void) 01106 { 01107 return wGetOffset; 01108 } 01109
1.5.5