📄 net_ip.c
字号:
UINT32 NET_IP_send( UINT32 ip_sp_hd, /* service provider defined handle */ UINT32 dst_adr, /* destination ip address (BE) */ t_mac_addr *dst_mac_adr, /* destination MAC-address */ UINT32 length, /* total length of frame to send */ UINT8 *data ) /* pointer to start of frame */{ UINT32 rcode ; t_mac_addr mac_addr ; UINT8 *p ; UINT16 tmp2 ; /* validate handle */ IF_UPPER( ERROR_NET_IP_INVALID_HANDLE, ip_sp_hd, IP_SAP_COUNT) /* validate state */ if ( sap_context[ip_sp_hd].ip_sap_state != IP_SAP_STATE_OPEN ) { return( ERROR_NET_IP_SAP_CLOSED ) ; } /* validate destination IP-address */ if (dst_adr == IP_ADDR_UNDEFINED) { /* Destination host is undefined ! */ sprintf( net_diag_msg,"Destination host: %d.%d.%d.%d", ((dst_adr>>24)&0xff), ((dst_adr>>16)&0xff), ((dst_adr>> 8)&0xff), ((dst_adr>> 0)&0xff) ); net_last_error = ERROR_NET_INVALID_HOST_IP ; return( ERROR_NET_INVALID_HOST_IP ) ; } /* get our IP address, and validate */ if (env_ipaddr == IP_ADDR_UNDEFINED) { /* Our IP address of this board is undefined ! */ sprintf( net_diag_msg,"Board IP-address: %d.%d.%d.%d", ((UINT8*)&env_ipaddr)[0], ((UINT8*)&env_ipaddr)[1], ((UINT8*)&env_ipaddr)[2], ((UINT8*)&env_ipaddr)[3] ); net_last_error = ERROR_NET_INVALID_BOARD_IP ; return( ERROR_NET_INVALID_BOARD_IP ) ; } /* validate subnet mask */ if (env_subnetmask == 0) { /* Subnet mask is undefined ! */ sprintf( net_diag_msg,"subnetmask: %d.%d.%d.%d", ((UINT8*)&env_subnetmask)[0], ((UINT8*)&env_subnetmask)[1], ((UINT8*)&env_subnetmask)[2], ((UINT8*)&env_subnetmask)[3] ); net_last_error = ERROR_NET_INVALID_SUBNET_MASK ; return( ERROR_NET_INVALID_SUBNET_MASK ) ; } /* check, if we have any MAC to use */ if (dst_mac_adr == NULL) { /* clear mac */ memcpy(mac_addr, mac_undefined_adr, SYS_MAC_ADDR_SIZE) ; /* Check for use of default gateway */ if ( (env_subnetmask & env_ipaddr) != (env_subnetmask & dst_adr) ) { /* Not on same subnet, we need to use default gateway */ if (env_gateway == 0) { /* Gateway address is undefined ! */ sprintf( net_diag_msg,"Gateway IP-address: %d.%d.%d.%d", ((UINT8*)&env_gateway)[0], ((UINT8*)&env_gateway)[1], ((UINT8*)&env_gateway)[2], ((UINT8*)&env_gateway)[3] ); net_last_error = ERROR_NET_INVALID_GATEWAY_IP ; return( ERROR_NET_INVALID_GATEWAY_IP ) ; } /* We must be on same subnet as gateway */ if ( (env_subnetmask & env_ipaddr) != (env_subnetmask & env_gateway) ) { sprintf( net_diag_msg,"ip: %d.%d.%d.%d, gw: %d.%d.%d.%d, sub: %d.%d.%d.%d", ((UINT8*)&env_ipaddr)[0], ((UINT8*)&env_ipaddr)[1], ((UINT8*)&env_ipaddr)[2], ((UINT8*)&env_ipaddr)[3], ((UINT8*)&env_gateway)[0], ((UINT8*)&env_gateway)[1], ((UINT8*)&env_gateway)[2], ((UINT8*)&env_gateway)[3], ((UINT8*)&env_subnetmask)[0], ((UINT8*)&env_subnetmask)[1], ((UINT8*)&env_subnetmask)[2], ((UINT8*)&env_subnetmask)[3] ); net_last_error = ERROR_NET_NOT_ON_SAME_SUBNET_IP ; return( ERROR_NET_NOT_ON_SAME_SUBNET_IP ) ; } /* We need to resolute the MAC-address of gateway */ IF_ERROR( (rcode), (NET_ARP_open( env_gateway, &mac_addr) ) ) } else { /* On same subnet, we need to resolute the MAC-address of destination */ IF_ERROR( (rcode), (NET_ARP_open( dst_adr, &mac_addr) ) ) } } /* Fill-in IP header of frame */ p = (data + IP_HEADER_BASE) ; /* Fill-in version+header length */ put1( IP_HEADER_VERSION_LENGTH_IPV4, p ) ; /* Fill-in 'type-of-service' */ put1( IP_HEADER_TYPE_OF_SERVICE_NORMAL, p ) ; /* Fill-in 'total-length' */ tmp2 = length - MAC_HEADER_SIZE ; putbe2( tmp2, p ) ; /* Fill-in 'identification' */ putbe2( NET_IP_identification++, p ) ; /* Fill-in 'fragment' (not used) */ putbe2( IP_HEADER_FRAGMENT_NO, p ) ; /* Fill-in 'time-to-live' */ put1( IP_HEADER_TIME_TO_LIVE_NORMAL, p ) ; /* Fill-in 'protocol' */ put1( sap_context[ip_sp_hd].ip_sap, p ) ; /* Fill-in 'checksum' (temp = 0) */ put2( 0, p ) ; /* Fill-in 'source-IP-adr' */ put4( env_ipaddr, p ) ; /* Fill-in 'destination-IP-adr' */ put4( dst_adr, p ) ; /* Fill-in calculated 'checksum' */ tmp2 = NET_checksum( (UINT16*)((UINT32)data + IP_HEADER_BASE), IP_HEADER_SIZE/2 ) ; p = (data + IP_HEADER_BASE + IP_HEADER_CHECKSUM) ; put2( tmp2, p ) ; /* request MAC to send this frame */ if (dst_mac_adr == NULL) { /* use resoluted MAC-address */ rcode = NET_MAC_send( mac_sp_hd, &mac_addr, length, data ) ; } else { /* use callers supplied MAC-address */ rcode = NET_MAC_send( mac_sp_hd, dst_mac_adr, length, data ) ; } /* return completion */ return( rcode ) ;}/************************************************************************ * Implementation : Static functions ************************************************************************//************************************************************************ * * NET_IP_receive * Description : * ------------- * This function is registered in the MAC-module and linked with the * MAC-type = '0x800', to let the MAC call us back with an reference * to the received frame, containing an IP-frame. * In this function the IP-header will be validated and the IP-SAP * table will be searched for any match between the actual value * of the IP-protocol field and a registered user to handle upper * protocol layer. * * * * Parameters : * ------------ * 'src_mac_adr': senders MAC-address * 'length': length of received ethernet frame * 'data': pointer for received ethernet frame (in driver's space) * * * Return values : * --------------- * 'OK' * ************************************************************************/staticUINT32 NET_IP_receive( t_mac_addr *src_mac_adr, UINT32 length, UINT8 *data ){ UINT32 rcode, src_ip_addr, dst_ip_addr; t_ip_usr_receive receive ; UINT8 *p ; UINT8 sap ; UINT16 checksum, totlen ; UINT16 tmp2 ; int i ;#ifdef NET_DEBUG printf("NET_IP_receive\n") ;#endif /* validate checksum */ p = (data + IP_HEADER_BASE + IP_HEADER_CHECKSUM) ; get2( p, checksum) ; p = (data + IP_HEADER_BASE + IP_HEADER_CHECKSUM) ; put2( 0, p ) ; tmp2 = NET_checksum( (UINT16*)((UINT32)data + IP_HEADER_BASE), IP_HEADER_SIZE/2 ) ; if ( tmp2 != checksum ) { return( ERROR_NET_IP_INVALID_CHECKSUM ) ; } /* Having verified checksum, let this frame be untouched */ p = (data + IP_HEADER_BASE + IP_HEADER_CHECKSUM) ; put2( checksum, p ) ; /* get IP-'total_length'-field of this received frame and adjust length */ p = (data + IP_HEADER_BASE + IP_HEADER_TOTAL_LENGTH) ; get2( p, totlen) ; length = BE16_TO_CPU(totlen) + MAC_HEADER_SIZE ; /* validate length */ if (length > MAC_MAX_FRAME_SIZE) { return( ERROR_NET_IP_INVALID_LENGTH ) ; } /* get IP-'protocol'-field of this received frame */ p = (data + IP_HEADER_BASE + IP_HEADER_PROTOCOL) ; get1( p, sap) ; /* get source IP address of this received frame */ p = (data + IP_HEADER_BASE + IP_HEADER_SOURCE_IP_ADDRESS) ; get4( p, src_ip_addr) ; /* get destination IP address of this received frame, and validate destination is our address */ get4( p, dst_ip_addr) ; if (env_ipaddr != dst_ip_addr) { return( ERROR_NET_IP_INVALID_DST_IP_ADDR ) ; } /* search the SAP table to match this 'sap' */ for ( i = 0; i <IP_SAP_COUNT ; i++ ) { if ( sap_context[i].ip_sap == sap ) { if ( sap_context[i].ip_sap_state == IP_SAP_STATE_OPEN ) { /* we have a registered SAP context, call user */ receive = sap_context[i].ip_usr_receive ; rcode = (*receive)( src_ip_addr, src_mac_adr, length, data ) ; return( rcode ) ; } } } /* No SAP, reply 'PROTOCOL is UNREACHABLE' */ p = (data + IP_HEADER_BASE) ; rcode = NET_ICMP_UNREACHABLE_send( src_ip_addr, src_mac_adr, p, ICMP_UNREACHABLE_HEADER_CODE_PROT_UNREACHABLE ) ; return( ERROR_NET_IP_NO_SAP ) ;}/************************************************************************ * * NET_IP_alloc_sap * Description : * ------------- * Allocate a IP SAP, register user context and return a sp-handle. * * * Parameters : * ------------ * * 'sap_id', IN, value of IP-'protocol' to bind for * 'ip_usr_receive', IN, user-receive function to be registered * 'ip_sp_hd', OUT, handle of IP to be used by user by call * of 'send' or 'close' * * * Return values : * --------------- * 'ERROR_NET_IP_NO_FREE_SAP', No SAP entry could be allocated * 'OK' = 0x00: * * ************************************************************************/staticUINT32 NET_IP_alloc_sap( UINT8 sap_id, t_ip_usr_receive ip_usr_receive, UINT32 *ip_sp_hd ){ int i ; /* allocate a free IP SAP table entry */ for ( i = 0; i <IP_SAP_COUNT ; i++) { if ( sap_context[i].ip_sap_state == IP_SAP_STATE_CLOSED ) { /* save SAP context in allocated entry */ sap_context[i].ip_sap_state = IP_SAP_STATE_OPEN ; sap_context[i].ip_sap = sap_id ; sap_context[i].ip_usr_receive = ip_usr_receive ; *ip_sp_hd = i ; return( OK ) ; } } /* we should not arrive here */ return( ERROR_NET_IP_NO_FREE_SAP ) ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -