📄 net_udp.c
字号:
/************************************************************************
*
* NET_UDP_close
* Description :
* -------------
* Close UDP-SAP.
*
*
* Parameters :
* ------------
* -
*
*
* Return values :
* ---------------
* 'OK'(=0), UDP SAP has been closed
*
*
************************************************************************/
UINT32 NET_UDP_close( UINT32 sp_hd )
{
/* validate handle */
IF_UPPER( ERROR_NET_UDP_INVALID_HANDLE, sp_hd, UDP_SAP_COUNT)
/* close SAP */
sap_context[sp_hd].sap_state = UDP_SAP_STATE_CLOSED ;
sap_context[sp_hd].sap = UDP_SAP_UNDEFINED ;
sap_context[sp_hd].usr_receive = NULL ;
return(OK) ;
}
/************************************************************************
*
* NET_UDP_send
* Description :
* -------------
* Request the UDP module to send a 'UDP' datagram
* to a specified destination IP-address and UDP-port.
*
*
* Parameters :
* ------------
* 'ip_adr', IN, destination ip address (BE-format)
* 'port', IN, destination udp port (BE-format)
* 'mac_adr', IN, optional MAC address
* 'sp_hd', IN, handle to select our SAP-context
* 'length', IN, length of frame to send
* 'data', IN, address to start of frame to be send
*
*
* Return values :
* ---------------
* 'OK'(=0)
*
************************************************************************/
UINT32 NET_UDP_send( UINT32 ip_adr, /* destination ip address (BE) */
UINT16 port, /* port (BE-format) */
t_mac_addr *mac_adr, /* optional MAC destination */
UINT32 sp_hd, /* handle returned of 'open' */
UINT32 length, /* total length of frame to send */
UINT8 *data ) /* pointer to start of frame */
{
UINT32 rcode ;
UINT8 *p ;
UINT8 tmp1 ;
UINT16 tmp2 ;
UINT32 tmp4 ;
int i ;
/* validate handle */
IF_UPPER( ERROR_NET_UDP_INVALID_HANDLE, sp_hd, UDP_SAP_COUNT)
/* Fill-in UDP header of frame */
p = &data[UDP_HEADER_BASE + UDP_HEADER_SOURCE_PORT] ;
tmp2 = sap_context[sp_hd].sap ;
put2( tmp2, p ) ; /* Fill-in 'source_port' */
put2( port, p ) ; /* Fill-in 'destination_port' */
tmp2 = CPU_TO_BE16(length - (IP_HEADER_SIZE + MAC_HEADER_SIZE)) ;
put2( tmp2, p ) ; /* Fill-in 'length' */
tmp2 = 0 ;
put2( tmp2, p ) ; /* Fill-in 'checksum' (temp = 0) */
/* Calculate UDP checksum, which include the pseudo header */
/* get our IP address, and validate */
IF_ERROR( (rcode),
(SYSCON_read( SYSCON_COM_EN0_IP_ADDR_ID,
&(tmp4),
sizeof(tmp4)) ) )
/* Fill-in the pseudo-header to prepare for checksum calculation */
p = &data[UDP_PSEUDO_HEADER_BASE] ;
put4( tmp4, p ) ; /* Fill-in 'source-ip' */
put4( ip_adr, p ) ; /* Fill-in 'dest-ip' */
tmp1 = 0 ;
put1( tmp1, p ) ; /* Fill-in 'zero' */
tmp1 = IP_SAP_UDP ;
put1( tmp1, p ) ; /* Fill-in 'protocol' */
tmp2 = CPU_TO_BE16(length - (IP_HEADER_SIZE + MAC_HEADER_SIZE)) ;
put2( tmp2, p ) ; /* Fill-in 'length' */
/* complete UDP-header with checksum */
tmp2 = (UDP_PSEUDO_HEADER_SIZE + (length - (IP_HEADER_SIZE + MAC_HEADER_SIZE)))/2 ;
if (length%2)
{
data[length] = 0 ;
tmp2 = tmp2 + 1 ;
}
p = &data[UDP_PSEUDO_HEADER_BASE] ;
tmp2 = NET_checksum( (UINT16*)p, tmp2 ) ;
if ( tmp2 == 0 )
{
tmp2 = ~tmp2 ;
}
p = (data + UDP_HEADER_BASE + UDP_HEADER_CHECKSUM) ;
put2( tmp2, p ) ; /* Fill-in calculated 'checksum' */
/* request IP to send this frame */
rcode = NET_IP_send( ip_sp_hd,
ip_adr,
mac_adr,
length,
data ) ;
/* return completion */
return( rcode ) ;
}
/************************************************************************
* Implementation : Static functions
************************************************************************/
/************************************************************************
*
* NET_UDP_receive
* Description :
* -------------
* This function is registered in the IP-module and linked with the
* IP-protocol = '17', to let the IP call us back with a reference
* to the received frame, containing an UDP-frame.
* In this function the UDP-header will be validated and
* the any opened UDP-SAP will be checked to call a user registered
* receive handler.
*
*
*
* Parameters :
* ------------
* 'src_ip_adr': sender's IP-address (BE-format)
* 'src_mac_adr': sender's MAC-address
* 'length': length of received ethernet frame
* 'data': pointer for received ethernet frame (in driver's space)
*
*
* Return values :
* ---------------
* 'OK'
*
************************************************************************/
static
UINT32 NET_UDP_receive( UINT32 src_ip_adr,
t_mac_addr *src_mac_adr,
UINT32 length,
UINT8 *data )
{
UINT32 rcode ;
UINT8 *p ;
UINT8 tmp1 ;
UINT16 tmp2, checksum, src_port, dst_port, udp_length ;
UINT32 tmp4 ;
t_udp_usr_receive receive ;
int i ;
#ifdef NET_DEBUG
printf("NET_UDP_receive:\n") ;
#endif
/* validate UDP checksum */
p = (data + UDP_HEADER_BASE + UDP_HEADER_CHECKSUM) ;
get2( p, checksum) ;
/* Do checksum verification when requested */
if (checksum != 0)
{
p = (data + UDP_HEADER_BASE + UDP_HEADER_CHECKSUM) ;
tmp2 = 0 ;
put2( tmp2, p ) ;
/* prepend pseudo header */
/* get our IP address, and validate */
IF_ERROR( (rcode),
(SYSCON_read( SYSCON_COM_EN0_IP_ADDR_ID,
&(tmp4),
sizeof(tmp4)) ) )
/* Fill-in the pseudo-header to prepare for checksum calculation */
p = &data[UDP_PSEUDO_HEADER_BASE] ;
put4( src_ip_adr, p ) ; /* Fill-in 'source-ip' */
put4( tmp4, p ) ; /* Fill-in 'dest-ip' */
tmp1 = 0 ;
put1( tmp1, p ) ; /* Fill-in 'zero' */
tmp1 = IP_SAP_UDP ;
put1( tmp1, p ) ; /* Fill-in 'protocol' */
tmp2 = CPU_TO_BE16(length - (IP_HEADER_SIZE + MAC_HEADER_SIZE)) ;
put2( tmp2, p ) ; /* Fill-in 'length' */
tmp2 = (UDP_PSEUDO_HEADER_SIZE + (length - (IP_HEADER_SIZE + MAC_HEADER_SIZE)))/2 ;
if (length%2)
{
data[length] = 0 ;
tmp2 = tmp2 + 1 ;
}
p = &data[UDP_PSEUDO_HEADER_BASE] ;
tmp2 = NET_checksum( (UINT16*)p, tmp2 ) ;
if (tmp2 == 0)
{
tmp2 = ~tmp2 ;
}
if ( tmp2 != checksum )
{
return( ERROR_NET_UDP_INVALID_CHECKSUM ) ;
}
}
/* validate UDP length */
p = (data + UDP_HEADER_BASE + UDP_HEADER_LENGTH) ;
get2( p, udp_length) ;
udp_length = BE16_TO_CPU( udp_length ) ;
if (udp_length != (length - (IP_HEADER_SIZE + MAC_HEADER_SIZE)) )
{
return( ERROR_NET_UDP_INVALID_LENGTH) ;
}
/* get UDP-'port'-field's of this received frame */
p = (data + UDP_HEADER_BASE) ;
get2( p, src_port) ;
get2( p, dst_port) ;
/* search SAP table to match any registered user */
for ( i = 0; i <UDP_SAP_COUNT ; i++ )
{
if ( sap_context[i].sap == dst_port )
{
if ( sap_context[i].sap_state == UDP_SAP_STATE_OPEN )
{
/* we have a registered SAP context, call user */
receive = sap_context[i].usr_receive ;
rcode = (*receive)( src_ip_adr,
src_port,
src_mac_adr,
i,
length,
data ) ;
#ifdef NET_DEBUG
if (rcode) printf("UDP-receive, rcode = %x\n", rcode ) ;
#endif
return( rcode ) ;
}
}
}
return( ERROR_NET_UDP_NO_SAP ) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -