void TcpClientBase::connect(const IpAddress& remote_ip, uint16_t remote_port)
{
  con->setRemoteAddr(remote_ip);
  remote_host = remote_ip.toString();
  con->setRemotePort(remote_port);
  connect();
} /* TcpClientBase::connect */
TcpClient::TcpClient(const IpAddress& remote_ip, uint16_t remote_port,
    size_t recv_buf_len)
  : TcpConnection(recv_buf_len), dns(0), remote_host(remote_ip.toString()),
    sock(-1), wr_watch(0)
{
  setRemoteAddr(remote_ip);
  setRemotePort(remote_port);
} /* TcpClient::TcpClient */
TcpClientBase::TcpClientBase(TcpConnection *con, const IpAddress& remote_ip,
                             uint16_t remote_port)
  : con(con), dns(0), remote_host(remote_ip.toString()), sock(-1), wr_watch(0)
{
  con->setRemoteAddr(remote_ip);
  con->setRemotePort(remote_port);
  wr_watch = new FdWatch;
  wr_watch->activity.connect(mem_fun(*this, &TcpClientBase::connectHandler));
} /* TcpClientBase::TcpClientBase */
Beispiel #4
0
	MacAddress MacAddress::lookup_from_ip_with_arp_table(const IpAddress& ipAddress,
		bool ping) {

	  if(!ipAddress.isValid()) {
		return MacAddress();
	  }

	  char line[500];
	  char ip_address[500];
	  int hw_type;
	  int flags;
	  char mac_address[500];
	  char mask[500];
	  char device[500];

	  MacAddress foundMac;

	  if (ping) {
		ipAddress.ping(1000);
	  }

	  // ARP Table Reading Suggestion From
	  // http://stackoverflow.com/a/21031888

	  FILE *fp = fopen("/proc/net/arp", "r");
	  fgets(line, sizeof(line), fp);    // Skip the first line (column headers).

	  while(fgets(line, sizeof(line), fp)) {
		  sscanf(line, "%s 0x%x 0x%x %s %s %s\n",
				ip_address,
				&hw_type,
				&flags,
				mac_address,
				mask,
				device);

		  if (ipAddress.toString().compare(ip_address) == 0) {
			foundMac = MacAddress(mac_address);
			break;
		  } 
	  }

	  fclose(fp);
	  return foundMac;
	}
Beispiel #5
0
bool TcpServer::listen(const IpAddress& address, uint16_t port)	
{
	if(address.isNull())
		return false;

	int fd = socket(AF_INET, SOCK_STREAM, 0);

	struct sockaddr_in addr;
	bzero(&addr, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	inet_pton(AF_INET, address.toString().c_str(), &addr.sin_addr);	
	
	if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == 0)
	{
		setServerAddress(address); 
	 	setServerPort(port);
		setSocketDescriptor(fd);
		if(::listen(fd, SOMAXCONN) == 0)
			return true;
	}

	return false;
}
Beispiel #6
0
    void run() {

      // declare an instance of the USART and the stream that we'll use to write to it

      _usart=new MyUsart(57600);
      _outputStream=new UsartPollingOutputStream(*_usart);

      // declare the RTC that that stack requires. it's used for cache timeouts, DHCP lease expiry
      // and such like so it does not have to be calibrated for accuracy. A few seconds here or there
      // over a 24 hour period isn't going to make any difference.  Start it ticking at zero which is
      // some way back in 2000 but that doesn't matter to us

      Rtc<RtcLsiClockFeature<Rtc32kHzLsiFrequencyProvider>,RtcSecondInterruptFeature> rtc;
      rtc.setTick(0);

      // declare an instance of the network stack

      MyNetworkStack::Parameters params;
      _net=new MyNetworkStack;

      // the stack requires the RTC

      params.base_rtc=&rtc;

      // It's nice to give the DHCP client a host name because then it'll show up in DHCP
      // 'active leases' page. In a home router this is often called 'attached devices'

      params.dhcp_hostname="stm32plus";

      // spy on the DHCP announcements for DNS servers
      // by subscribing to the notification events passed around the network stack

      _net->NetworkNotificationEventSender.insertSubscriber(
          NetworkNotificationEventSourceSlot::bind(this,&NetDnsTest::onNotification)
        );

      // subscribe to error events from the network stack

      _net->NetworkErrorEventSender.insertSubscriber(
          NetworkErrorEventSourceSlot::bind(this,&NetDnsTest::onError)
        );

      // Initialise the stack. This will reset the PHY, initialise the MAC
      // and attempt to create a link to our link partner. Ensure your cable
      // is plugged in when you run this or be prepared to handle the error

      if(!_net->initialise(params))
        error();

      // start the ethernet MAC Tx/Rx DMA channels
      // this will trigger the DHCP transaction

      if(!_net->startup())
        error();

      // now query for google UK's host name (the default timeout is 5000ms,
      // configurable with 'dns_timeout' in the stack's parameters

      IpAddress ipAddress;
      char buf[30];

      if(!_net->dnsHostnameQuery("www.google.co.uk",ipAddress))
        error();

      // write out the results

      ipAddress.toString(buf);
      *_outputStream << "www.google.co.uk = " << buf << "\r\n";

      for(;;);
    }
Beispiel #7
0
Socket::Status TcpSocket::connect(const IpAddress& remoteAddress, unsigned short remotePort, Time timeout)
{
    // Create the internal socket if it doesn't exist
    create();

    if (isSecure())
    {
        char port[5];
        sprintf(port, "%d", remotePort);
        if (mbedtls_net_connect(&getSecureData().socket, remoteAddress.toString().c_str(), port, MBEDTLS_NET_PROTO_TCP) != 0)
            return priv::SocketImpl::getErrorStatus();

        int ret;
        while((ret = mbedtls_ssl_handshake(&getSecureData().ssl)) != 0)
            if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
                return Error;
    }
    else
    {
        // Create the remote address
        sockaddr_in address = priv::SocketImpl::createAddress(remoteAddress.toInteger(), remotePort);

        if (timeout <= Time::Zero)
        {
            // ----- We're not using a timeout: just try to connect -----

            // Connect the socket
            if (::connect(getHandle(), reinterpret_cast<sockaddr*>(&address), sizeof(address)) == -1)
                return priv::SocketImpl::getErrorStatus();

            // Connection succeeded
            return Done;
        }
        else
        {
            // ----- We're using a timeout: we'll need a few tricks to make it work -----

            // Save the previous blocking state
            bool blocking = isBlocking();

            // Switch to non-blocking to enable our connection timeout
            if (blocking)
                setBlocking(false);

            // Try to connect to the remote address
            if (::connect(getHandle(), reinterpret_cast<sockaddr*>(&address), sizeof(address)) >= 0)
            {
                // We got instantly connected! (it may no happen a lot...)
                setBlocking(blocking);
                return Done;
            }

            // Get the error status
            Status status = priv::SocketImpl::getErrorStatus();

            // If we were in non-blocking mode, return immediately
            if (!blocking)
                return status;

            // Otherwise, wait until something happens to our socket (success, timeout or error)
            if (status == Socket::NotReady)
            {
                // Setup the selector
                fd_set selector;
                FD_ZERO(&selector);
                FD_SET(getHandle(), &selector);

                // Setup the timeout
                timeval time;
                time.tv_sec  = static_cast<long>(timeout.asMicroseconds() / 1000000);
                time.tv_usec = static_cast<long>(timeout.asMicroseconds() % 1000000);

                // Wait for something to write on our socket (which means that the connection request has returned)
                if (select(static_cast<int>(getHandle() + 1), NULL, &selector, NULL, &time) > 0)
                {
                    // At this point the connection may have been either accepted or refused.
                    // To know whether it's a success or a failure, we must check the address of the connected peer
                    if (getRemoteAddress() != cpp3ds::IpAddress::None)
                    {
                        // Connection accepted
                        status = Done;
                    }
                    else
                    {
                        // Connection refused
                        status = priv::SocketImpl::getErrorStatus();
                    }
                }
                else
                {
                    // Failed to connect before timeout is over
                    status = priv::SocketImpl::getErrorStatus();
                }
            }

            // Switch back to blocking mode
            setBlocking(true);

            return status;
        }
    }
}