BST_IP_ERR_T BST_IP_BsdSocket( BST_FD_T *pfd, BST_ARG_T *Arg, BST_UINT16 usProtocol )
{
    BST_UINT32                          ulTimeout;
    ulTimeout                           = BST_IP_RX_TIME_OUT;
    if( BST_NULL_PTR == pfd )
    {
        return BST_IP_ERR_ARG;
    }
    switch( usProtocol )
    {
        case BST_IP_PROTOCOL_UDP:
            pfd->lFd                    = lwip_socket( AF_INET, SOCK_DGRAM, 0 );
            break;
        case BST_IP_PROTOCOL_TCP:
            pfd->lFd                    = lwip_socket( AF_INET, SOCK_STREAM, 0 );    //TCP对应SOCK_STREAM
            break;
        default :
            pfd->lFd                    = BST_IP_ERR_MEM;
            return BST_IP_ERR_ARG;
    }

    if( BST_IP_IsBsdFdValid( (*pfd) ) )
    {
        if ( 0 == lwip_setsockopt( pfd->lFd, SOL_SOCKET, SO_RCVTIMEO, &ulTimeout, BST_OS_SIZEOF( ulTimeout ) ) )
        {
            return BST_IP_ERR_OK;
        }

        return BST_IP_ERR_VAL;
    }
    else
    {
        return BST_IP_ERR_MEM;
    }
}
Exemple #2
0
static void
ping_thread(void *arg)
{
  int s;
  int timeout = PING_RCV_TIMEO;
  ip_addr_t ping_target;

  LWIP_UNUSED_ARG(arg);

  if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) {
    return;
  }

  lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

  while (1) {
    ping_target = PING_TARGET;

    if (ping_send(s, &ping_target) == ERR_OK) {
      LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
      ip_addr_debug_print(PING_DEBUG, &ping_target);
      LWIP_DEBUGF( PING_DEBUG, ("\n"));

      ping_time = sys_now();
      ping_recv(s);
    } else {
      LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
      ip_addr_debug_print(PING_DEBUG, &ping_target);
      LWIP_DEBUGF( PING_DEBUG, (" - error\n"));
    }
    sys_msleep(PING_DELAY);
  }
}
Exemple #3
0
int32_t OsNetworkSocketSetMulticastTtl(THandle aHandle, uint8_t aTtl)
{
    if ( OsNetworkHandle_IsInterrupted(aHandle) )
        return -1;
        
    return lwip_setsockopt ( HANDLE_TO_SOCKET(aHandle), IPPROTO_IP, IP_MULTICAST_TTL, &aTtl, sizeof(uint8_t));
}
Exemple #4
0
int socket_connect(int sock, const char* host, int port)
{
    int result;
    int timeout;
    struct hostent *server_host;
    struct sockaddr_in server_addr;

    server_host = gethostbyname(host);
    if (server_host == RT_NULL) 
    {
        rt_kprintf("unknow host: %s\n", host);
        return -1;
    }

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    server_addr.sin_addr = *((struct in_addr *)server_host->h_addr);
    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));

    result = lwip_connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));

    /* set recv timeout */
    timeout = 3000; /* 3 seconds */
    lwip_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

    return result;
}
static void   SC_SetSocketOpt(__SYSCALL_PARAM_BLOCK*  pspb)
{
	pspb->lpRetValue = (LPVOID)lwip_setsockopt(
		(INT)PARAM(0),
		(int)PARAM(1),
		(int)PARAM(2),
		(const void*)PARAM(3),
		(socklen_t)PARAM(4)
		);
}
Exemple #6
0
THandle OsNetworkCreate(OsNetworkSocketType aSocketType)
{
    int s;
    int type;
    OsNetworkHandle* h;

    //LOG(__FUNCTION__);

    switch ( aSocketType )
    {
        case eOsNetworkSocketStream:
            type = SOCK_STREAM;
            break;
        
        case eOsNetworkSocketDatagram:
            type = SOCK_DGRAM;
            break;
        
        default:
            return kHandleNull;
    }

    h = OsNetworkHandle_Create();

    //LOG("  Created %d\n", HANDLE_TO_SOCKET(h));

    if ( h == kHandleNull )
        return kHandleNull;

    s = lwip_socket(AF_INET, type, 0);

    if ( s < 0 )
    {
        OsNetworkHandle_Destroy(h);
        return kHandleNull;
    }

    if ( type == SOCK_DGRAM )
    {
        char loop = 1;
        if (lwip_setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0)
        {
            OsNetworkHandle_Destroy(h);
            return kHandleNull;
        }
    }

    if ( OsNetworkHandle_Initialise(h, s) < 0 )
    {
        OsNetworkHandle_Destroy(h);
        return kHandleNull;
    }
    
    return (THandle) h;
}
int LWIP_SOCKETS_Driver::SetSockOpt( SOCK_SOCKET socket, int level, int optname, const char* optval, int  optlen )
{ 
    NATIVE_PROFILE_PAL_NETWORK();
    int nativeLevel;
    int nativeOptionName;
    int nativeIntValue;
    char *pNativeOptionValue = (char*)optval;

    switch(level)
    {
        case SOCK_IPPROTO_IP:
            nativeLevel = IPPROTO_IP;
            nativeOptionName = GetNativeIPOption(optname);
            break;
        case SOCK_IPPROTO_TCP:    
            nativeLevel = IPPROTO_TCP;
            nativeOptionName = GetNativeTcpOption(optname);
            break;
        case SOCK_IPPROTO_UDP: 
        case SOCK_IPPROTO_ICMP:
        case SOCK_IPPROTO_IGMP:
        case SOCK_IPPROTO_IPV4:
        case SOCK_SOL_SOCKET:
            nativeLevel      = SOL_SOCKET;
            nativeOptionName = GetNativeSockOption(optname);            

            switch(optname)
            {        
                // LINGER and DONTLINGER are not implemented in LWIP
                case SOCK_SOCKO_LINGER:
                    errno = SOCK_ENOPROTOOPT;
                    return SOCK_SOCKET_ERROR;
                case SOCK_SOCKO_DONTLINGER:
                    errno = SOCK_ENOPROTOOPT;
                    return SOCK_SOCKET_ERROR;
				// ignore this item to enable http to work
				case SOCK_SOCKO_REUSEADDRESS:
					return 0;
                
                case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
                    nativeIntValue     = !*(int*)optval;
                    pNativeOptionValue = (char*)&nativeIntValue;
                    break;
                default:
                    break;
            }
            break;
        default:
            nativeLevel         = 0;
            nativeOptionName    = 0;
            break;
    }

    return lwip_setsockopt(socket, nativeLevel, nativeOptionName, pNativeOptionValue, optlen);
}
Exemple #8
0
int32_t OsNetworkSocketSetReceiveTimeout(THandle aHandle, uint32_t aMilliSeconds)
{
    if ( OsNetworkHandle_IsInterrupted(aHandle) )
        return -1;

    struct timeval t;
    t.tv_sec = aMilliSeconds / 1000;
    t.tv_usec = (aMilliSeconds % 1000) * 1000;

    return lwip_setsockopt ( HANDLE_TO_SOCKET(aHandle), SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(struct timeval));
}
Exemple #9
0
/* ------------------------------------------------------------------------------------------------------
 *									   			sockex_app()
 *
 * Description : Handing socket receive data.
 *
 * Argument(s) : none.
 *
 */
void sockex_app(void *arg)
{
	int opt, ret;
	INT8U sock_rxbuf[50];
//	INT8U len;
	
	LWIP_UNUSED_ARG(arg);
	
	for(;;)
	{
		if(connfd > 0)
		{
			
			opt = 100;												/* set recv timeout (100 ms) */
			lwip_setsockopt(connfd, SOL_SOCKET, SO_RCVTIMEO, &opt, sizeof(int));

			
			ret = lwip_read(connfd, sock_rxbuf, 8);
			if(ret == -1)
			{
				OSTimeDly(2);
				continue;
			}
			if((sock_rxbuf[0] == 'C')&&(sock_rxbuf[1] == 'o'))		/* Compare start frame.*/
			{
// 				address_t addr;
// 				INT8U mac[8] = {0x00, 0x12, 0x4B, 0x00, 0x01, 0xC0, 0xB7, 0xE0};
// 				
//				len = sock_rxbuf[8];								/* Set frame length.*/
/*				if(len != 0x0F)
				{
					OSTimeDly(2);
					continue;
				}
				*/
//				addr.mode = LONG_ADDR;								/* Using device long address.*/
//				lwip_setsockopt(connfd, SOL_SOCKET, SO_RCVTIMEO, &opt, sizeof(int));
//				ret = lwip_read(connfd, sock_rxbuf, len);			/* Read other frame data.*/
/*				if(ret == -1)
				{
					OSTimeDly(2);
					continue;
				}
				*/
// 				utilReverseBuf(mac, 8);
// 				memcpy(addr.long_addr, mac, 8);				/* 提取MAC地址*/
// 				
// 				// DOTO: MAC layer send frame. Using deveice MAC address.
// 				mac_tx_handle(&addr, &sock_rxbuf[7], 1, MAC_DATA);	/* Send command frame.*/
			}
		}
		OSTimeDly(2);
	}
}
Exemple #10
0
void tcp_senddata(const char* url, int port, int length)
{
	struct hostent *host;
	int sock, err, result, timeout, index;
	struct sockaddr_in server_addr;
	rt_uint8_t *buffer_ptr;

	/* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
	host = gethostbyname(url);
	/* 创建一个socket,类型是SOCKET_STREAM,TCP类型 */
	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
	{
		/* 创建socket失败 */
		rt_kprintf("Socket error\n");
		return;
	}

	/* 神奇内存 */
	buffer_ptr = rt_malloc(length);
	/* 构造发生数据 */
	for (index = 0; index < length; index ++)
		buffer_ptr[index] = index & 0xff;

	timeout = 100;
	/* 设置发送超时时间100ms */
	lwip_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
	/* 初始化预连接的服务端地址 */
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(port);
	server_addr.sin_addr = *((struct in_addr *)host->h_addr);
	rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));

	/* 连接到服务端 */
	err = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
	rt_kprintf("TCP thread connect error code: %d\n", err);

	while(1)
	{
		/* 发送数据到sock连接 */
		result = send(sock, buffer_ptr, length, MSG_DONTWAIT);
		if(result == -1) //数据发送错误处理
		{
			rt_kprintf("TCP thread send error: %d\n", result);
			lwip_close(sock);	//关闭连接,重新创建连接
			rt_thread_delay(10);
			if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
				rt_kprintf("TCP Socket error:%d\n",sock);
			err = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
			rt_kprintf("TCP thread connect error code: %d\n", err);
		}
	}
}
Exemple #11
0
static void socketCreate(uint16 sockNr)
{
    int sockFd;
    int sockType;
    struct sockaddr_in sLocalAddr;

    if (SocketAdminList[sockNr].SocketProtocolIsTcp) {
    	sockType = SOCK_STREAM;
    } else {
    	sockType = SOCK_DGRAM;
    }


    sockFd = lwip_socket(AF_INET, sockType, 0);
    if (sockFd >= 0) {
    	memset((char *)&sLocalAddr, 0, sizeof(sLocalAddr));

    	int on = 1;
    	lwip_ioctl(sockFd, FIONBIO, &on);
//    	lwip_setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int) );		// shuzhou add
    	lwip_setsockopt(sockFd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(int));	// Set socket to no delay

    	/*Source*/
    	sLocalAddr.sin_family = AF_INET;
    	sLocalAddr.sin_len = sizeof(sLocalAddr);

    	sLocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);		// TODO: Use IP from configuration instead
    	sLocalAddr.sin_port = htons(SocketAdminList[sockNr].SocketConnectionRef->SocketLocalPort);

    	if(lwip_bind(sockFd, (struct sockaddr *)&sLocalAddr, sizeof(sLocalAddr)) >= 0) {

            if (!SocketAdminList[sockNr].SocketProtocolIsTcp) {
            	// Now the UDP socket is ready for receive/transmit
            	SocketAdminList[sockNr].SocketHandle = sockFd;
            	SocketAdminList[sockNr].SocketState = SOCKET_UDP_READY;
            } else {
                if  ( lwip_listen(sockFd, 20) == 0 ){	// TODO: What number of the backlog?
                	// Now the TCP socket is ready for receive/transmit
                	SocketAdminList[sockNr].SocketHandle = sockFd;
                	SocketAdminList[sockNr].SocketState = SOCKET_TCP_LISTENING;
                } else {
                	lwip_close(sockFd);
                }
            }
    	} else {
    		lwip_close(sockFd);
    	}
    } else {
    	// Socket creation failed
    	// Do nothing, try again later
    }
}
Exemple #12
0
Socket::Socket()
{
    int on = 1;

    socket_ = new SocketHandle_t;

    socket_->fd = lwip_socket(PF_INET, SOCK_STREAM, 0);

    lwip_setsockopt(socket_->fd, SOL_SOCKET, SO_REUSEADDR, (char*) &on, sizeof(on));

    /* Set socket non-blocking */
    lwip_ioctl(socket_->fd, FIONBIO, &on);

}
Exemple #13
0
//Entry point of ping application.
void ping_Entry(void *arg)
{
  int s;
  int timeout = PING_RCV_TIMEO;
  __PING_PARAM* pParam = (__PING_PARAM*)arg;

  ping_pkt_seq = 0;  //Reset ping sequence number.
	ping_succ    = 0;

  if((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0)
  {
		PrintLine("  ping : Create raw socket failed,quit.");
    return;
  }

  lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
  _hx_printf("\r\n  Ping %s with %d bytes packet:\r\n",inet_ntoa(pParam->targetAddr),pParam->size);
  while (1)
	{
		//ping_target = PING_TARGET; //ping gw
		//IP4_ADDR(&ping_target, 127,0,0,1); //ping loopback.
    if (ping_send(s, &pParam->targetAddr,pParam->size) == ERR_OK)
		{
			//printf(" ping_Entry : Send out packet,addr = %s,size = %d\r\n",inet_ntoa(pParam->targetAddr),pParam->size);
      ping_time = sys_now();
      ping_recv(s);
	    ping_pkt_seq ++;
    }
	  else
	  {
	    PrintLine("   ping : Send out packet failed.");
    }
    //sys_msleep(PING_DELAY);

	  //Try the specified times.
	  pParam->count --;
	  if(0 == pParam->count)
	  {
		  break;
	  }
  }
	//Show ping statistics.
	_hx_printf("\r\n");
	_hx_printf("  ping statistics: total send = %d,received = %d,%d loss.\r\n",
	  ping_pkt_seq,ping_succ,(ping_pkt_seq - ping_succ));
  //Close socket.
  lwip_close(s);
}
int LWIP_SOCKETS_Driver::SetSockOpt( SOCK_SOCKET socket, int level, int optname, const char* optval, int  optlen )
{ 
    NATIVE_PROFILE_PAL_NETWORK();
    int nativeLevel;
    int nativeOptionName;
    int nativeIntValue;
    char *pNativeOptionValue = (char*)optval;

    switch(level)
    {
        case SOCK_IPPROTO_IP:
            nativeLevel = IPPROTO_IP;
            nativeOptionName = GetNativeIPOption(optname);
            break;
        case SOCK_IPPROTO_TCP:    
            nativeLevel = IPPROTO_TCP;
            nativeOptionName = GetNativeTcpOption(optname);
            break;
        case SOCK_IPPROTO_UDP: 
        case SOCK_IPPROTO_ICMP:
        case SOCK_IPPROTO_IGMP:
        case SOCK_IPPROTO_IPV4:
        case SOCK_SOL_SOCKET:
            nativeLevel      = SOL_SOCKET;
            nativeOptionName = GetNativeSockOption(optname);            

            switch(optname)
            {
                case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
                case SOCK_SOCKO_DONTLINGER:
                    nativeIntValue     = !*(int*)optval;
                    pNativeOptionValue = (char*)&nativeIntValue;
                    break;
                default:
                    break;
            }
            break;
        default:
            nativeLevel         = 0;
            nativeOptionName    = 0;
            break;
    }

    return lwip_setsockopt(socket, nativeLevel, nativeOptionName, pNativeOptionValue, optlen);
}
static void
ping_host_thread(void *arg)
{
  int s,i=0;
  int timeout = PING_RCV_TIMEO;
  ip_addr_t ping_target;
  char *host = (char *)arg;
  //LWIP_UNUSED_ARG(arg);

  if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) {
    return;
  }

  lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

  while (1) {
    //ping_target = PING_TARGET;
	if (i>4) break;
	i++;  
	(ip4_addr_set_u32(&ping_target, ipaddr_addr(host)));

    if (ping_send(s, &ping_target) == ERR_OK) {
      //LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
      //ip_addr_debug_print(PING_DEBUG, &ping_target);
      //LWIP_DEBUGF( PING_DEBUG, ("\n"));
			rt_kprintf("ping: send ");
			ip_addr_debug_print1(&ping_target);
			rt_kprintf("\n");
		
      ping_time = sys_now();
      ping_recv(s);
    } else {
      //LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
      //ip_addr_debug_print(PING_DEBUG, &ping_target);
      //LWIP_DEBUGF( PING_DEBUG, (" - error\n"));
			rt_kprintf("ping: send ");
			ip_addr_debug_print1(&ping_target);
			rt_kprintf(" - error\n");
    }
    sys_msleep(PING_DELAY);
  }
}
Exemple #16
0
static void socketAccept(uint16 sockNr)
{
	uint16 i;
	int clientFd;
	struct sockaddr_in client_addr;
	int addrlen = sizeof(client_addr);

	clientFd = lwip_accept(SocketAdminList[sockNr].SocketHandle, (struct sockaddr*)&client_addr, (socklen_t *)&addrlen);

	if( clientFd != (-1))
	{
		// Check that remote port and ip match
		// TODO: Check remote port and ip with SocketAdminList and select first matching

		// New connection established
		int on = 1;
    	lwip_ioctl(clientFd, FIONBIO, &on);	// Set socket to non block mode

    	lwip_setsockopt(clientFd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(int));	// Set socket to no delay

    	SocketAdminList[sockNr].ConnectionHandle = clientFd;
		SocketAdminList[sockNr].RemotePort = client_addr.sin_port;
		SocketAdminList[sockNr].RemoteIpAddress = client_addr.sin_addr.s_addr;
		SocketAdminList[sockNr].SocketState = SOCKET_TCP_READY;

		// Check if there is any free duplicate of this socket
		for (i = 0; i < SOAD_SOCKET_COUNT; i++) {
			if ((SocketAdminList[i].SocketState == SOCKET_DUPLICATE)
				&& (SoAd_Config.SocketConnection[i].SocketProtocol == SoAd_Config.SocketConnection[sockNr].SocketProtocol)
				&& (SoAd_Config.SocketConnection[i].SocketLocalPort == SoAd_Config.SocketConnection[sockNr].SocketLocalPort)) {
				// Yes, move the old socket to this
				SocketAdminList[i].SocketHandle = SocketAdminList[sockNr].SocketHandle;
				SocketAdminList[i].SocketState = SOCKET_TCP_LISTENING;
//				pi_printf("infor: socket accept "); mini_uart_sendDec(i); pi_printf(" \r\n");
				// SocketAdminList[sockNr].SocketHandle = -1;
				break;
			}
		}
		network_up = true;
	}
}
static void
ping_host(char * host)
{
	int s,i=0;
	int timeout = PING_RCV_TIMEO;
	ip_addr_t ping_target;


	if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) {
		return;
	}

	lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

	while (1) {
		if (i>4) break;
		i++;  
		//ping_target = netif_default->gw;
		//IP4_ADDR(&ping_target,210,82,5,1);
		(ip4_addr_set_u32(&ping_target, ipaddr_addr(host))); 

		if (ping_send(s, &ping_target) == ERR_OK) {
			//LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
			rt_kprintf("ping: send ");
			ip_addr_debug_print1(&ping_target);
			rt_kprintf("\n");

			ping_time = sys_now();
			ping_recv(s);
		} else {
			//LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
			rt_kprintf("ping: send ");
			ip_addr_debug_print1(&ping_target);
			rt_kprintf(" - error\n");
			//LWIP_DEBUGF( PING_DEBUG, (" - error\n"));
		}
		sys_msleep(PING_DELAY);
	}
}
Exemple #18
0
int32_t OsNetworkSocketMulticastAddMembership(THandle aHandle, TIpAddress aInterface, TIpAddress aAddress)
{
    if ( OsNetworkHandle_IsInterrupted(aHandle) )
        return -1;
        
    struct ip_mreq m = {
        .imr_multiaddr.s_addr = aAddress,
        .imr_interface.s_addr = aInterface
    };

    return lwip_setsockopt ( HANDLE_TO_SOCKET(aHandle), IPPROTO_IP, IP_ADD_MEMBERSHIP, &m, sizeof(m) );
}

int32_t OsNetworkSocketMulticastDropMembership(THandle aHandle, TIpAddress aInterface, TIpAddress aAddress)
{
    if ( OsNetworkHandle_IsInterrupted(aHandle) )
        return -1;
        
    struct ip_mreq m = {
        .imr_multiaddr.s_addr = aAddress,
        .imr_interface.s_addr = aInterface
    };

    return lwip_setsockopt ( HANDLE_TO_SOCKET(aHandle), IPPROTO_IP, IP_DROP_MEMBERSHIP, &m, sizeof(m));
}

int32_t OsNetworkListAdapters(OsNetworkAdapter** aAdapters, uint32_t aUseLoopback)
{
    struct netif* n;
    OsNetworkAdapter* start = NULL;
    OsNetworkAdapter* end = NULL;
    
    for ( n = netif_list ; n != NULL ; n = n->next )
    {
        if ( aUseLoopback )
            if ( n->name[0] != 'l' || n->name[1] != 'o' )
                continue;
        
        if ( !netif_is_up(n) )
            continue;
        
        OsNetworkAdapter *a = (OsNetworkAdapter*) malloc(sizeof(OsNetworkAdapter));

        if ( a == NULL )
        {
            OsNetworkFreeInterfaces(start);
            return -1;
        }

        // Stash lwip interface name (2 chars, no termination) in iReserved
        char* name_reserved = (char*) &(a->iReserved);
        name_reserved[0] = n->name[0];
        name_reserved[1] = n->name[1];
        name_reserved[2] = '\0';

        // Copy info
        a->iAddress = (TIpAddress) n->ip_addr.addr;
        a->iNetMask = (TIpAddress) n->netmask.addr;
        a->iName    = name_reserved;
        a->iNext    = NULL;

        // Push on to end of list. We reverse netif_list as loopback is first.
        if ( start == NULL )
            start = end = a;
        else
        {
            end->iNext = a;
            end = a;
        }
    }
    
    *aAdapters = start;
    
    return 0;
}

void OsNetworkFreeInterfaces(OsNetworkAdapter* aAdapters)
{
    while ( aAdapters != NULL )
    {
        OsNetworkAdapter* n = aAdapters;
        aAdapters = aAdapters->iNext;
        free(n);
    }
}

void OsNetworkSetInterfaceChangedObserver(InterfaceListChanged aCallback, void* aArg)
{
}
Exemple #19
0
int setsockopt(int sockfd, int level, int optname,
               const void *optval, socklen_t optlen)
{
  int sock = socket_for_fd(sockfd);
  return lwip_setsockopt(sock, level, optname, optval, optlen);
}
 // timeOut in ms (0 = no timeout)
 void MTD_FLASHMEM Socket::setTimeOut(uint32_t timeOut)
 {
     lwip_setsockopt(m_socket, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeOut, sizeof(timeOut));
 }
 void MTD_FLASHMEM Socket::setNoDelay(bool value)
 {
     int32_t one = (int32_t)value;
     lwip_setsockopt(m_socket, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
 }
Exemple #22
0
int OTAClass::beginLocal(uint16_t port, bool reboot_when_success) {

    int ret = -1;

    // variables for image processing
    flash_t flash;
    uint32_t img2_addr, img2_len, img3_addr, img3_len;
    uint32_t img_upper_bound;
    uint32_t checksum = 0;
    uint32_t signature1, signature2;

    // variables for network processing
    int server_socket = -1;
    int client_socket = -1;
    struct sockaddr_in localHost;
    struct sockaddr_in client_addr;
    int socket_error, socket_timeout;
    socklen_t optlen;

    // variables for OTA
    unsigned char *buf = NULL;
    int read_bytes = 0, processed_len;
    uint32_t file_info[3];
    uint32_t ota_len;
    uint32_t ota_blk_size = 0;

    int i, n;

    do {
        sync_ota_addr();

        get_image_info(&img2_addr, &img2_len, &img3_addr, &img3_len);
        img_upper_bound = img2_addr + 0x10 + img2_len; // image2 base + header + len
        if (img3_len > 0) {
            img_upper_bound += 0x10 + img3_len; // image 3 header + len
        }

        if ((ota_addr & 0xfff != 0) || (ota_addr == ~0x0) || (ota_addr < img_upper_bound)) {
            OTA_PRINTF("Invalid OTA address: %08X\r\n", ota_addr);
            break;
        }

        buf = (unsigned char *) malloc (BUFSIZE);
        if (buf == NULL) {
            OTA_PRINTF("Fail to allocate memory\r\n");
            break;
        }

        server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (server_socket < 0) {
            OTA_PRINTF("Fail to create socket\r\n");
            break;
        }

        memset(&localHost, 0, sizeof(localHost));
        localHost.sin_family = AF_INET;
        localHost.sin_port = htons(port);
        localHost.sin_addr.s_addr = INADDR_ANY;

        if (lwip_bind(server_socket, (struct sockaddr *)&localHost, sizeof(localHost)) < 0) {
            OTA_PRINTF("Bind fail\r\n");
            break;
        }

        if (lwip_listen(server_socket , 1) < 0) {
            OTA_PRINTF("Listen fail\r\n");
            break;
        }

        OTA_PRINTF("Wait for client\r\n");
        n = (int) sizeof( client_addr );
        memset(&client_addr, 0, sizeof(client_addr));
        client_socket = lwip_accept(server_socket, (struct sockaddr *) &client_addr, (socklen_t *)&n);
        OTA_PRINTF("Client connected. IP:%s port:%d\r\n\r\n", inet_ntoa(client_addr.sin_addr.s_addr), ntohs(client_addr.sin_port));

        socket_timeout = DEFAULT_IMAGE_DOWNLOAD_TIMEOUT;
        lwip_setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, &socket_timeout, sizeof(socket_timeout));        

        OTA_PRINTF("Read OTA info...\r\n");
        read_bytes = read(client_socket, file_info, sizeof(file_info));
        if (read_bytes < 0) {
           OTA_PRINTF("Fail to read OTA info\r\n");
           break;
        }

        if (file_info[2] == 0) {
            OTA_PRINTF("OTA image len is 0\r\n");
            break;
        }

        ota_len = file_info[2];
        ota_blk_size = ((ota_len - 1) / 4096) + 1;
        for (i = 0; i < ota_blk_size; i++) {
            flash_erase_sector(&flash, ota_addr + i * 4096);
        }

        OTA_PRINTF("Start download\r\n");

        // Now download OTA image
        processed_len = 0;
        while( processed_len < ota_len ) {
            memset(buf, 0, BUFSIZE);
            read_bytes = read(client_socket, buf, BUFSIZE);

            if (read_bytes < 0) {
                optlen = sizeof(socket_error);
                getsockopt(client_socket, SOL_SOCKET, SO_ERROR, &socket_error, &optlen);
                if (socket_error == EAGAIN) {
                    // socket timeout
                }
                break;
            }

            if (flash_stream_write(&flash, ota_addr + processed_len, read_bytes, buf) < 0) {
                OTA_PRINTF("Write sector fail\r\n");
                break;
            }

            processed_len += read_bytes;
        }

        if (processed_len != ota_len) {
            OTA_PRINTF("Download fail\r\n");
            break;
        }

        // Read OTA image from flash and calculate checksum
        checksum = processed_len = 0;
        while ( processed_len < ota_len ) {
            n = (processed_len + BUFSIZE < ota_len) ? BUFSIZE : (ota_len - processed_len);
            flash_stream_read(&flash, ota_addr + processed_len, n, buf);
            for (i=0; i<n; i++) checksum += (buf[i] & 0xFF);
            processed_len += n;
        }

        if (checksum != file_info[0]) {
            OTA_PRINTF("Bad checksum:%d expected:%d\r\n", checksum, file_info[0]);
            break;
        }

        // Put signature for OTA image
        flash_write_word(&flash, ota_addr +  8, 0x35393138);
        flash_write_word(&flash, ota_addr + 12, 0x31313738);
        flash_read_word(&flash, ota_addr +  8, &signature1);
        flash_read_word(&flash, ota_addr + 12, &signature2);
        if (signature1 != 0x35393138 || signature2 != 0x31313738) {
            OTA_PRINTF("Put signature fail\r\n");
            break;
        }

        // Mark image 2 as old image
        flash_write_word(&flash, img2_addr + 8, 0x35393130);

        ret = 0;
        OTA_PRINTF("OTA success\r\n");

    } while (0);

    if (buf != NULL) {
        free(buf);
    }

    if (server_socket >= 0) {
        close(server_socket);
    }

    if (client_socket >= 0) {
        close(client_socket);
    }

    if (ret < 0) {
        OTA_PRINTF("OTA fail\r\n");
    } else {
        if (reboot_when_success) {
            sys_reset();
        }
    }

    return ret;
}
Exemple #23
0
int udp_client_func(struct iperf_data_t iperf_data)
{
    int                 client_fd;
    struct sockaddr_in  ser_addr;
    char                *buffer = NULL;
    int                 i=0;
    int                 addrlen = sizeof(struct sockaddr_in);
    uint32_t            start_time, end_time, bandwidth_time;
    uint64_t            total_size=0, bandwidth_size=0;

    buffer = pvPortMalloc(iperf_data.buf_size);
    if(NULL == buffer){
        printf("\n\r[ERROR] %s: Allocate client buffer failed",__func__);
        return -1;
    }
    printf("\n\r%s: buf_size = %d",__func__,iperf_data.buf_size);
    memset(buffer, 0, iperf_data.buf_size);
    /*
    //filling the buffer
    for (i = 0; i < iperf_data.buf_size; i++){
        buffer[i] = (char)(i % 10);
    }*/

    //create socket
    if( (client_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){
        printf("\n\r[ERROR] %s: Create UDP socket failed",__func__);
        goto Exit2;
    }

    //initialize value in dest
    memset(&ser_addr, 0, sizeof(ser_addr));
    ser_addr.sin_family = AF_INET;
    ser_addr.sin_port = htons(iperf_data.port);
    ser_addr.sin_addr.s_addr = inet_addr(iperf_data.server_ip);

    printf("\n\r%s: Server IP=%s, port=%d", __func__,iperf_data.server_ip, iperf_data.port);
    printf("\n\r%s: Create socket fd = %d", __func__,client_fd);

    lwip_setsockopt(client_fd,IPPROTO_IP,IP_TOS,&iperf_data.tos_value,sizeof(iperf_data.tos_value));

    if(iperf_data.total_size == 0){
        start_time = xTaskGetTickCount();
        end_time = start_time;
        bandwidth_time = start_time;
        while ( ((end_time - start_time) <= (configTICK_RATE_HZ * iperf_data.time)) && (!g_udp_terminate) ) {
            if( sendto(client_fd, buffer, iperf_data.buf_size,0,(struct sockaddr*)&ser_addr, addrlen) < 0){
                //printf("\n\r[ERROR] %s: UDP client send data error",__func__);
            }else{
                total_size+=iperf_data.buf_size;
                bandwidth_size+=iperf_data.buf_size;
            }

            if((end_time - bandwidth_time) >= (configTICK_RATE_HZ*1)){
                printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__,(uint32_t)( bandwidth_size/KB),(uint32_t)(end_time-bandwidth_time),(uint32_t)((bandwidth_size*8)/(end_time - bandwidth_time)));
                bandwidth_time = end_time;
                bandwidth_size = 0;
            }else{
                if(bandwidth_size >= iperf_data.bandwidth){
                    while((end_time - bandwidth_time) < configTICK_RATE_HZ){
                        end_time = xTaskGetTickCount();
                    }
                    printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(bandwidth_size/KB),(uint32_t)(end_time-bandwidth_time),(uint32_t)((bandwidth_size*8)/(end_time - bandwidth_time)));
                    bandwidth_time = end_time;
                    bandwidth_size = 0;
                }
            }

            end_time = xTaskGetTickCount();
        }
    }
    else{
        end_time = xTaskGetTickCount();
        bandwidth_time = end_time;
        while ( (total_size < iperf_data.total_size) && (!g_udp_terminate) ) {
            if( sendto(client_fd, buffer, iperf_data.buf_size,0,(struct sockaddr*)&ser_addr, addrlen) < 0){
                //printf("\n\r[ERROR] %s: UDP client send data error",__func__);
            }else{
                total_size+=iperf_data.buf_size;
                bandwidth_size+=iperf_data.buf_size;
            }
            if((end_time - bandwidth_time) >= (configTICK_RATE_HZ*1)){
                printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(bandwidth_size/KB),(uint32_t)(end_time-bandwidth_time),(uint32_t)((bandwidth_size*8)/(end_time - bandwidth_time)));
                bandwidth_time = end_time;
                bandwidth_size = 0;
            }else{
                if(bandwidth_size >= iperf_data.bandwidth){
                    while((end_time - bandwidth_time) < (configTICK_RATE_HZ*1)){
                        end_time = xTaskGetTickCount();
                    }
                    printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(bandwidth_size/KB),(uint32_t)(end_time-bandwidth_time),(uint32_t)((bandwidth_size*8)/(end_time - bandwidth_time)));
                    bandwidth_time = end_time;
                    bandwidth_size = 0;
                }
            }
            end_time = xTaskGetTickCount();
        }
    }
    printf("\n\r%s: Send %d KBytes packets",__func__,(uint32_t)(total_size/KB));
Exit1:
    close(client_fd);
Exit2:
    vPortFree(buffer);
    printf("\n\r%s: Close client socket",__func__);

    return 0;
}
Exemple #24
0
/** This is an example function that tests
    the recv function (timeout etc.). */
static void
sockex_testrecv(void *arg)
{
  int s;
  int ret;
  int err;
  int opt;
  struct sockaddr_in addr;
  size_t len;
  char rxbuf[1024];
  fd_set readset;
  fd_set errset;
  struct timeval tv;

  LWIP_UNUSED_ARG(arg);
  /* set up address to connect to */
  memset(&addr, 0, sizeof(addr));
  addr.sin_len = sizeof(addr);
  addr.sin_family = AF_INET;
  addr.sin_port = PP_HTONS(SOCK_TARGET_PORT);
  addr.sin_addr.s_addr = inet_addr(SOCK_TARGET_HOST);

  /* first try blocking: */

  /* create the socket */
  s = lwip_socket(AF_INET, SOCK_STREAM, 0);
  LWIP_ASSERT("s >= 0", s >= 0);

  /* connect */
  ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
  /* should succeed */
  LWIP_ASSERT("ret == 0", ret == 0);

  /* set recv timeout (100 ms) */
  opt = 100;
  ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &opt, sizeof(int));
  LWIP_ASSERT("ret == 0", ret == 0);

  /* write the start of a GET request */
#define SNDSTR1 "G"
  len = strlen(SNDSTR1);
  ret = lwip_write(s, SNDSTR1, len);
  LWIP_ASSERT("ret == len", ret == (int)len);

  /* should time out if the other side is a good HTTP server */
  ret = lwip_read(s, rxbuf, 1);
  LWIP_ASSERT("ret == -1", ret == -1);
  err = errno;
  LWIP_ASSERT("errno == EAGAIN", err == EAGAIN);

  /* write the rest of a GET request */
#define SNDSTR2 "ET / HTTP_1.1\r\n\r\n"
  len = strlen(SNDSTR2);
  ret = lwip_write(s, SNDSTR2, len);
  LWIP_ASSERT("ret == len", ret == (int)len);

  /* wait a while: should be enough for the server to send a response */
  sys_msleep(1000);

  /* should not time out but receive a response */
  ret = lwip_read(s, rxbuf, 1024);
  LWIP_ASSERT("ret > 0", ret > 0);

  /* now select should directly return because the socket is readable */
  FD_ZERO(&readset);
  FD_ZERO(&errset);
  FD_SET(s, &readset);
  FD_SET(s, &errset);
  tv.tv_sec = 10;
  tv.tv_usec = 0;
  ret = lwip_select(s + 1, &readset, NULL, &errset, &tv);
  LWIP_ASSERT("ret == 1", ret == 1);
  LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &errset));
  LWIP_ASSERT("FD_ISSET(s, &readset)", FD_ISSET(s, &readset));

  /* should not time out but receive a response */
  ret = lwip_read(s, rxbuf, 1024);
  /* might receive a second packet for HTTP/1.1 servers */
  if (ret > 0) {
    /* should return 0: closed */
    ret = lwip_read(s, rxbuf, 1024);
    LWIP_ASSERT("ret == 0", ret == 0);
  }

  /* close */
  ret = lwip_close(s);
  LWIP_ASSERT("ret == 0", ret == 0);

  printf("sockex_testrecv finished successfully\n");
}
Exemple #25
0
/**
 * Send an SNTP request via sockets.
 * This is a very minimal implementation that does not fully conform
 * to the SNTPv4 RFC, especially regarding server load and error procesing.
 */
void
sntp_request(void *arg)
{
  int                sock;
  struct sockaddr_in local;
  struct sockaddr_in to;
  int                tolen;
  int                size;
  int                timeout;
  struct sntp_msg    sntpmsg;
  ip_addr_t          sntp_server_address;

  LWIP_UNUSED_ARG(arg);

  /* if we got a valid SNTP server address... */
  if (ipaddr_aton(SNTP_SERVER_ADDRESS, &sntp_server_address)) {
    /* create new socket */
    sock = lwip_socket(AF_INET, SOCK_DGRAM, 0);
    if (sock >= 0) {
      /* prepare local address */
      memset(&local, 0, sizeof(local));
      local.sin_family      = AF_INET;
      local.sin_port        = PP_HTONS(INADDR_ANY);
      local.sin_addr.s_addr = PP_HTONL(INADDR_ANY);

      /* bind to local address */
      if (lwip_bind(sock, (struct sockaddr *)&local, sizeof(local)) == 0) {
        /* set recv timeout */
        timeout = SNTP_RECV_TIMEOUT;
        lwip_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));

        /* prepare SNTP request */
        sntp_initialize_request(&sntpmsg);

        /* prepare SNTP server address */
        memset(&to, 0, sizeof(to));
        to.sin_family      = AF_INET;
        to.sin_port        = PP_HTONS(SNTP_PORT);
        inet_addr_from_ipaddr(&to.sin_addr, &sntp_server_address);
    
        /* send SNTP request to server */
        if (lwip_sendto(sock, &sntpmsg, SNTP_MSG_LEN, 0, (struct sockaddr *)&to, sizeof(to)) >= 0) {
          /* receive SNTP server response */
          tolen = sizeof(to);
          size  = lwip_recvfrom(sock, &sntpmsg, SNTP_MSG_LEN, 0, (struct sockaddr *)&to, (socklen_t *)&tolen);
          /* if the response size is good */
          if (size == SNTP_MSG_LEN) {
            /* if this is a SNTP response... */
            if (((sntpmsg.li_vn_mode & SNTP_MODE_MASK) == SNTP_MODE_SERVER) ||
                ((sntpmsg.li_vn_mode & SNTP_MODE_MASK) == SNTP_MODE_BROADCAST)) {
              /* do time processing */
              sntp_process(sntpmsg.receive_timestamp);
            } else {
              LWIP_DEBUGF( SNTP_DEBUG_WARN, ("sntp_request: not response frame code\n"));
            }
          }
        } else {
          LWIP_DEBUGF( SNTP_DEBUG_WARN, ("sntp_request: not sendto==%i\n", errno));
        }
      }
      /* close the socket */
      closesocket(sock);
    }
  }
}
Exemple #26
0
int tcpSetReadTimeout(int socket, int timeout)
{
  return lwip_setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
}
Exemple #27
0
/* ------------------------------------------------------------------------------------------------------
 *									      sockex_selects()
 *
 * Description : socket selects test.
 *
 * Argument(s) : none.
 *
 */
void sockex_selects(void *arg)
{
	int sock_fd, new_fd;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	socklen_t sin_size;
	int yes;
	INT8U buf[BUF_SIZE];
	int ret;
	int i;
	
	fd_set fdsr;													/* Create file descriptor.*/
	int maxsock;
	struct timeval tv;
	
	conn_amount = 0;
	LWIP_UNUSED_ARG(arg);
	
	sock_fd = lwip_socket(AF_INET, SOCK_STREAM, 0);
	
	yes = 1;
	ret = lwip_setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
	if(ret == -1)
	{
		return;
	}
	
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_len = sizeof(server_addr);
	server_addr.sin_port = PP_HTONS(SOCK_HOSR_PORT);
	server_addr.sin_addr.s_addr = lwIPLocalIPAddrGet();				/* IP_ADDR_ANY is '0.0.0.0'.*/
	
	lwip_bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
	lwip_listen(sock_fd, BACKLOG + 1);								/* MAX TCP client is BACKLOG.*/
	
	sin_size = sizeof(client_addr);
	maxsock = sock_fd;
	

	
	while(1)
	{
		FD_ZERO(&fdsr);												/* Initialize file descriptor set.*/
		FD_SET(sock_fd, &fdsr);

		tv.tv_sec = 10;												/* Timeout setting.*/
		tv.tv_usec = 0;
		
		for (i = 0; i < BACKLOG; i++)								/* Add active connection to fd set.*/
		{								
			if (fd_A[i] != 0) {
				FD_SET(fd_A[i], &fdsr);
			}
		}
		
		ret = lwip_select(maxsock + 1, &fdsr, NULL, NULL, &tv);
		if(ret < 0)
		{
			break;
		}
		else if(ret == 0)
		{
			continue;
		}
		
		for (i = 0; i < conn_amount; i++)							/* Check every fd in the set.*/
		{
			if (FD_ISSET(fd_A[i], &fdsr))
			{
				int opt = 100;										/* set recv timeout (100 ms) */
				lwip_setsockopt(fd_A[i], SOL_SOCKET, SO_RCVTIMEO, &opt, sizeof(int));

				ret = lwip_read(fd_A[i], buf, 8);
				if (ret <= 0)
				{
// 					lwip_close(fd_A[i]);
// 					FD_CLR(fd_A[i], &fdsr);
// 					fd_A[i] = 0;
				}
				else        										/* receive data.*/
				{
					if((buf[0] == 'C')&&(buf[1] == 'o'))
					{
// 						address_t addr;
// 						INT8U mac[8] = {0x00, 0x12, 0x4B, 0x00, 0x01, 0xC0, 0xB7, 0xE0};
// 						addr.mode = LONG_ADDR;
// 						utilReverseBuf(mac, 8);
// 						memcpy(addr.long_addr, mac, 8);
// 						mac_tx_handle(&addr, &buf[7], 1, MAC_DATA);
					}
					if (ret < BUF_SIZE)
						memset(&buf[ret], '\0', 1);
				}
			}
		}

		if(FD_ISSET(sock_fd, &fdsr))								/* Check whether a new connection comes.*/
		{
			new_fd = lwip_accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);
			if(new_fd <= 0)
			{
				continue;
			}
//			lwip_send(new_fd, "con", 4, 0);
			if(conn_amount < BACKLOG)								/* Add to fd queue.*/
			{
				fd_A[conn_amount++] = new_fd;
				
				if(new_fd > maxsock)
					maxsock = new_fd;
			}
			else
			{
//				conn_amount = 0;
				lwip_close(fd_A[conn_amount-1]);
				fd_A[conn_amount-1] = new_fd;
				if(new_fd > maxsock)
					maxsock = new_fd;
//				lwip_send(new_fd, "bye", 4, 0);
//				lwip_close(new_fd);									/* Close larger than 5 socket.*/
			}
		}
		
// 		for (i = 0; i < BACKLOG; i++)								/* Close other connections.*/
// 		{
// 			if (fd_A[i] != 0) {
// 				lwip_close(fd_A[i]);
// 			}
// 		}
	}
}
Exemple #28
0
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) {
	BT_HANDLE hSocket = (BT_HANDLE)s;

	return lwip_setsockopt(hSocket->socket, level, optname, optval, optlen);
}
Exemple #29
0
static int set_socket_option_int(THandle aHandle, int aOptName, int aVal)
{
    return lwip_setsockopt ( HANDLE_TO_SOCKET(aHandle), SOL_SOCKET, aOptName, &aVal, sizeof(int));
}
Exemple #30
0
int netstack_send_echo(u8 *ripaddr, u16 size, u16 seqno, 
			struct netstack_echo_reply *reply)
{
	u64 ts;
	int s, i, err;
	char buf[64];
	size_t fromlen, off, len = sizeof(struct icmp_echo_hdr) + size;
	ip_addr_t to_addr, from_addr;
	struct sockaddr_in sock;
	struct ip_hdr *iphdr;
	struct icmp_echo_hdr *iecho;

	LWIP_ASSERT("ping_size is too big\n", len <= 0xffff);

	/* Prepare target address */
	IP4_ADDR(&to_addr, ripaddr[0],ripaddr[1],ripaddr[2],ripaddr[3]);

	/* Open RAW socket */
	if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) {
		vmm_printf("%s: failed to open ICMP socket\n", __func__);
		return VMM_EFAIL;
	}

	/* Set socket option */
	i = PING_RCV_TIMEO;
	lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &i, sizeof(i));

	/* Prepare socket address */
	sock.sin_len = sizeof(sock);
	sock.sin_family = AF_INET;
	inet_addr_from_ipaddr(&sock.sin_addr, &to_addr);

	/* Prepare ECHO request */
	iecho = (struct icmp_echo_hdr *)vmm_zalloc(len);
	if (!iecho) {
		return VMM_ENOMEM;
	}
	ICMPH_TYPE_SET(iecho, ICMP_ECHO);
	ICMPH_CODE_SET(iecho, 0);
	iecho->chksum = 0;
	iecho->id     = PING_ID;
	iecho->seqno  = htons(seqno);
	for (i = 0; i < size; i++) {
		((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
	}
	iecho->chksum = inet_chksum(iecho, len);

	/* Send ECHO request */
	err = lwip_sendto(s, iecho, len, 0, 
				(struct sockaddr*)&sock, sizeof(sock));
	vmm_free(iecho);
	if (!err) {
		return VMM_EFAIL;
	}

	/* Get reference timestamp */
	ts = vmm_timer_timestamp();

	/* Wait for ECHO reply */
	err = VMM_EFAIL;
	off = lwip_recvfrom(s, buf, sizeof(buf), 0, 
			    (struct sockaddr*)&sock, (socklen_t*)&fromlen);
	if (off >= (sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr))) {
		inet_addr_to_ipaddr(&from_addr, &sock.sin_addr);
		iphdr = (struct ip_hdr *)buf;
		iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4));
		if ((iecho->id == PING_ID) && 
		    (iecho->seqno == htons(seqno))) {
			reply->ripaddr[0] = ip4_addr1(&from_addr);
			reply->ripaddr[1] = ip4_addr2(&from_addr);
			reply->ripaddr[2] = ip4_addr3(&from_addr);
			reply->ripaddr[3] = ip4_addr4(&from_addr);
			reply->ttl = IPH_TTL(iphdr);
			reply->len = len;
			reply->seqno = seqno;
			reply->rtt = 
				udiv64(vmm_timer_timestamp() - ts, 1000);
			err = VMM_OK;
		}
	}
	while (off < len) {
		off = lwip_recvfrom(s, buf, sizeof(buf), 0, 
			(struct sockaddr*)&sock, (socklen_t*)&fromlen);
	}

	/* Close RAW socket */
	lwip_close(s);

	return err;
}