0
mirror of https://github.com/Indemsys/Frequency_Inverter.git synced 2026-05-12 14:28:29 +00:00
Files
2022-01-04 12:22:53 +02:00

211 lines
7.0 KiB
C

/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ping6.c$
* $Version : 3.8.1.0$
* $Date : Jun-14-2012$
*
* Comments:
*
* This file contains the implementation of a minimal
* ICMPv6 echo request.
*
*END************************************************************************/
#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "icmp6_prv.h"
#include "arp.h"
boolean ICMP6_expire_echo (TCPIP_EVENT_PTR);
/************************************************************************
* NAME: RTCS6_ping
* RETURNS : RTCS_OK or error code
* DESCRIPTION: Send an ICMPv6 echo request, and wait for a reply..
*************************************************************************/
uint_32 RTCS6_ping( sockaddr *ip_addr /* [IN] remote sock addr structure */,
uint_32_ptr timeout /* [IN] Maximum time to wait for reply */
/* [OUT] Round trip time */,
uint_16 id /* [IN] User id for the ping request */,
uint_8 hop_limit /* [IN] Hope limit (optional) */,
pointer data_buffer /* [IN] Pointer to ping data buffer (optional) */,
uint_32 data_buffer_size /* [IN] Size of a ping data buffer (optional) */
)
{
ICMP6_PARM parms;
uint_32 error;
parms.ip_addr = (in6_addr*)(&( ((sockaddr_in6 *)ip_addr)->sin6_addr ));
parms.if_scope_id = ((struct sockaddr_in6 *)ip_addr)->sin6_scope_id;
parms.id = id;
parms.timeout = *timeout;
parms.hop_limit = hop_limit;
parms.data_buffer = data_buffer; /* Pointer to a buffer. */
parms.data_buffer_size = data_buffer_size; /* Size of a buffer. */
error = RTCSCMD_issue(parms, ICMP6_send_echo);
if (error)
return error;
*timeout = parms.timeout;
return RTCS_OK;
}
/*FUNCTION*-------------------------------------------------------------
*
* Function Name : ICMP_expire_echo
* Returned Values :
* Comments :
* Called by the Timer. Expire a ICMP echo request.
*
*END*-----------------------------------------------------------------*/
boolean ICMP6_expire_echo(TCPIP_EVENT_PTR event)
{
ICMP6_PARM_PTR parms = event->PRIVATE;
RTCSCMD_complete(parms, RTCSERR_ICMP_ECHO_TIMEOUT);
return FALSE;
}
/*FUNCTION*-------------------------------------------------------------
*
* Function Name : ICMP_send_echo
* Parameters :
*
* _ip_address ipaddress [IN] destination IP address
* uint_32 timeout [IN/OUT] timeout/rtt
* uint_16 id [IN] identification for echo message.
* uint_16 seq not used
*
* Comments :
* Send an ICMP Echo Request packet.
*
*END*-----------------------------------------------------------------*/
void ICMP6_send_echo(ICMP6_PARM_PTR parms)
{
#if RTCSCFG_ENABLE_IP6
ICMP6_CFG_STRUCT_PTR ICMP6_cfg_ptr = RTCS_getcfg(ICMP6);
RTCSPCB_PTR pcb;
ICMP6_ECHO_HEADER_PTR packet;
_rtcs_if_handle ihandle_dest = NULL;
uint_32 error;
IF_ICMP6_STATS_ENABLED(ICMP6_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);
parms->seq = ICMP6_cfg_ptr->ECHO_SEQ++;
pcb = RTCSPCB_alloc_send();
if (pcb == NULL)
{
IF_ICMP6_STATS_ENABLED(ICMP6_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
RTCSCMD_complete(parms, RTCSERR_PCB_ALLOC);
return;
}
if(parms->data_buffer && parms->data_buffer_size)
{
error = RTCSPCB_append_fragment(pcb, parms->data_buffer_size, parms->data_buffer);
if (error)
{
IF_ICMP6_STATS_ENABLED(ICMP6_cfg_ptr->STATS.COMMON.ST_TX_ERRORS++);
RTCSLOG_PCB_FREE(pcb, error);
RTCSPCB_free(pcb);
RTCSCMD_complete(parms, error);
return;
}
}
error = RTCSPCB_insert_header(pcb, sizeof(ICMP6_ECHO_HEADER));
if (error)
{
IF_ICMP6_STATS_ENABLED(ICMP6_cfg_ptr->STATS.COMMON.ST_TX_ERRORS++);
IF_ICMP6_STATS_ENABLED(RTCS_seterror(&ICMP6_cfg_ptr->STATS.ERR_TX, error, (uint_32)pcb));
RTCSLOG_PCB_FREE(pcb, error);
RTCSPCB_free(pcb);
RTCSCMD_complete(parms, error);
return;
}
RTCSLOG_PCB_WRITE(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_ICMPV6), 0);
packet = (ICMP6_ECHO_HEADER_PTR)RTCSPCB_DATA(pcb);
pcb->TRANSPORT_LAYER = (uchar_ptr)packet;
htonc(packet->HEAD.TYPE, ICMP6_TYPE_ECHO_REQ);
htonc(packet->HEAD.CODE, 0);
htons(packet->HEAD.CHECKSUM, 0);
htons(packet->ID, parms->id);
htons(packet->SEQ, parms->seq);
pcb->IP_SUM = IP_Sum_PCB(RTCSPCB_SIZE(pcb), pcb);
pcb->IP_SUM_PTR = packet->HEAD.CHECKSUM;
if(parms->if_scope_id)
{
ihandle_dest = ip6_if_get_by_scope_id(parms->if_scope_id);
}
parms->EXPIRE.TIME = parms->timeout;
parms->EXPIRE.EVENT = ICMP6_expire_echo;
parms->EXPIRE.PRIVATE = parms;
parms->timeout = RTCS_time_get(); /* get timestamp */
/*TBD add to IP6_send(pcb, IPPROTO_ICMPV6, NULL,...... ipsrc address in depend on scope ID */
/*So, our ping6 should be able procced scope ID and choose right interface source IPv6 address */
error = IP6_send(pcb, IPPROTO_ICMPV6|IPTTL(parms->hop_limit), NULL/*ipsrc*/, parms->ip_addr/*ipdest*/, ihandle_dest, 0);
if (error != RTCS_OK)
{
IF_ICMP6_STATS_ENABLED(ICMP6_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
RTCSCMD_complete(parms, error);
return;
}
/*
** If there is no error add the parm struct to config struct
** and initiate the event timer
*/
IF_ICMP6_STATS_ENABLED(ICMP6_cfg_ptr->STATS.ST_TX_ECHO_REQ++);
/* add the prameter structure to ICMP cfg */
parms->NEXT = ICMP6_cfg_ptr->ECHO_PARM_HEAD;
if (parms->NEXT)
{
parms->NEXT->PREV = &parms->NEXT;
} /* Endif */
ICMP6_cfg_ptr->ECHO_PARM_HEAD = parms;
parms->PREV = &ICMP6_cfg_ptr->ECHO_PARM_HEAD;
TCPIP_Event_add(&parms->EXPIRE);
#else
RTCSCMD_complete(parms, RTCSERR_IP_IS_DISABLED);
#endif /* RTCSCFG_ENABLE_IP6 */
}