예제 #1
0
Arc::Socket::Socket( unsigned int socket )

#endif // WINDOWS

	: _address(),
	  _port(), 
	  _type(INVALID_SOCKET_TYPE),
	  _socket(socket),
	  _error(false),
	  _errorMsg()
{
	char buf[INET_ADDRSTRLEN] = "";
	struct sockaddr_in name;
	socklen_t len = sizeof(name);
	int res;

	res = getpeername(socket, (struct sockaddr *)&name, &len);

	if (res == 0)
	{
		inet_ntop(AF_INET, &name.sin_addr, buf, sizeof buf);
	}
	else
	{
		setError("getpeername() failed");
		cleanup();
	}

	_address = IPAddress(inet_ntoa(name.sin_addr));
	_port = name.sin_port;
	_type = SOCKET_TYPE_TCP; // TODO: Get actual socket type when UDP is implemented
}
예제 #2
0
 // if this is the first time calling now() or after 6 hours an NTP update is perfomed
 // warn: now() should be called within 50 days from the last call
 // warn: loses about 3 seconds every 10 hours
 DateTime MTD_FLASHMEM DateTime::now()
 {
     uint32_t currentMillis = millis();
     uint32_t locLastMillis = lastMillis();
     uint32_t diff = (currentMillis < locLastMillis) ? (0xFFFFFFFF - locLastMillis + currentMillis) : (currentMillis - locLastMillis);
     
     if (locLastMillis == 0 || diff > 6 * 3600 * 1000)
     {
         if (lastDateTime().getFromNTPServer())
         {
             lastMillis() = currentMillis;
             return lastDateTime();
         }
     }
     
     DateTime result;
     result.setUnixDateTime( lastDateTime().getUnixDateTime() + (diff / 1000) );
     
     if (s_defaultNTPServer == IPAddress(0, 0, 0, 0))
     {
         // NTP synchronizatin is disabled. Take care for millis overflow.
         if (diff > 10 * 24 * 3600 * 1000)   // past 10 days?
         {
             // reset millis counter to avoid overflow (actually it overflows after 50 days)
             lastMillis()   = currentMillis;
             lastDateTime() = result;
         }
     }
     
     return result;
 }
예제 #3
0
int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult, uint32_t timeout_ms)
{
    ip_addr_t addr;
    aResult = static_cast<uint32_t>(0);

    if(aResult.fromString(aHostname)) {
        // Host name is a IP address use it!
        DEBUG_WIFI_GENERIC("[hostByName] Host: %s is a IP!\n", aHostname);
        return 1;
    }

    DEBUG_WIFI_GENERIC("[hostByName] request IP for: %s\n", aHostname);
    err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult);
    if(err == ERR_OK) {
        aResult = IPAddress(&addr);
    } else if(err == ERR_INPROGRESS) {
        _dns_lookup_pending = true;
        delay(timeout_ms);
        _dns_lookup_pending = false;
        // will return here when dns_found_callback fires
        if(aResult.isSet()) {
            err = ERR_OK;
        }
    }

    if(err != 0) {
        DEBUG_WIFI_GENERIC("[hostByName] Host: %s lookup error: %d!\n", aHostname, (int)err);
    } else {
        DEBUG_WIFI_GENERIC("[hostByName] Host: %s IP: %s\n", aHostname, aResult.toString().c_str());
    }

    return (err == ERR_OK) ? 1 : 0;
}
예제 #4
0
int EthernetClass::begin(uint8_t *mac_address)
{
  static DhcpClass s_dhcp;
  _dhcp = &s_dhcp;


  // Initialise the basic info
  W5100.init();
  W5100.setMACAddress(mac_address);
  W5100.setIPAddress(IPAddress(0,0,0,0).raw_address());

  // Now try to get our config info from a DHCP server
  int ret = _dhcp->beginWithDHCP(mac_address);
  if(ret == 1)
  {
    // We've successfully found a DHCP server and got our configuration info, so set things
    // accordingly
    W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
    W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
    W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
    _dnsServerAddress = _dhcp->getDnsServerIp();
  }

  return ret;
}
예제 #5
0
IPAddresses Dns::Resolve(const std::string& host) {
    IPAddresses list;
    addrinfo hints = { 0 }, *addresses;

    //hints.ai_family = AF_UNSPEC;
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    getaddrinfo(host.c_str(), NULL, &hints, &addresses);

    for (addrinfo *p = addresses; p != NULL; p = p->ai_next) {
#ifdef _WIN32
        //wchar_t straddr[35];
        //char straddr[512];
        //DWORD len;
        //WSAAddressToStringA(p->ai_addr, p->ai_addrlen, NULL, straddr, &len);
        
        char* straddr = inet_ntoa(((sockaddr_in*)p->ai_addr)->sin_addr);

#else
        char straddr[512];

        inet_ntop(p->ai_family, &((sockaddr_in*)p->ai_addr)->sin_addr, straddr, sizeof(straddr));
#endif

        list.push_back(IPAddress(straddr));
    }

    return list;
}
예제 #6
0
파일: Ethernet.cpp 프로젝트: 00alis/Arduino
int EthernetClass::begin(uint8_t *mac_address, unsigned long timeout, unsigned long responseTimeout)
{
  static DhcpClass s_dhcp;
  _dhcp = &s_dhcp;


  // Initialise the basic info
  W5100.init();
  SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
  W5100.setMACAddress(mac_address);
  W5100.setIPAddress(IPAddress(0,0,0,0).raw_address());
  SPI.endTransaction();

  // Now try to get our config info from a DHCP server
  int ret = _dhcp->beginWithDHCP(mac_address, timeout, responseTimeout);
  if(ret == 1)
  {
    // We've successfully found a DHCP server and got our configuration info, so set things
    // accordingly
    SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
    W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
    W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
    W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
    SPI.endTransaction();
    _dnsServerAddress = _dhcp->getDnsServerIp();
  }

  return ret;
}
   bool
   MessageUtilities::RetrieveOriginatingAddress(std::shared_ptr<Message> pMessage, String &hostName, IPAddress &address)
   //---------------------------------------------------------------------------()
   // DESCRIPTION:
   // Tries to determine the IP address / host this email originally comes from.
   //---------------------------------------------------------------------------()
   {
      hostName = "";
      address = IPAddress();

      // Extract Received headers from the message.
      std::shared_ptr<MimeHeader> pHeader = GetMessageHeader_(pMessage);

      std::list<String> receivedHeaders;

      AnsiString sHeaderName = "Received";
      std::vector<MimeField> &lstFields = pHeader->Fields();
      auto iter = lstFields.begin();
      auto iterEnd = lstFields.end();
   
      for (; iter != iterEnd; iter++)
      {
         MimeField& fd = *iter;
         
         if (sHeaderName.CompareNoCase(fd.GetName()) == 0)
         {
            receivedHeaders.push_back(fd.GetValue());
         }
      }

      return RetrieveOriginatingAddress(receivedHeaders, hostName, address);
   }
예제 #8
0
Jatta::Network::IPAddress Jatta::Network::SocketTCP::GetIP()
{
    struct sockaddr_storage _Addr;
    socklen_t _Length = sizeof(_Addr);
    getpeername(sock, (struct sockaddr*)&_Addr, &_Length);
    if (_Addr.ss_family == AF_INET) // ipv4
    {
        return IPAddress((UInt32)((struct sockaddr_in*)&_Addr)->sin_addr.s_addr);
    }
    else // ipv6
    {
        UInt64 address[2];
        memcpy(&address, &((struct sockaddr_in6*)&_Addr)->sin6_addr, sizeof(address));
        return IPAddress(address);
    }
}
예제 #9
0
bool MDNS::processQueries() {
    uint16_t n = udp->parsePacket();

    if (n > 0) {
        buffer->read(udp);

        udp->flush();

        uint16_t responses = getResponses();

        buffer->clear();

        if (responses > 0) {
            writeResponses(responses);
        }

        if (buffer->available() > 0) 
        {
            //Serial.println("buffer->available()");
            udp->beginPacket(IPAddress(224, 0, 0, 251), MDNS_PORT);

            buffer->write(udp);

            udp->endPacket();
        }
    }

    return n > 0;
}
예제 #10
0
void SocketImpl::getOption(int level, int option, IPAddress& value)
{
    char buffer[IPAddress::MAX_ADDRESS_LENGTH];
    pil_socklen_t len = sizeof(buffer);
    getRawOption(level, option, buffer, len);
    value = IPAddress(buffer, len);
}
예제 #11
0
IPAddress IPAddress::operator ~ () const
{
	if (family() == IPv4)
	{
		IPv4AddressImpl self(this->pImpl()->addr());
		return IPAddress((~self).addr(), sizeof(struct in_addr));
	}
#if defined(POCO_HAVE_IPv6)
	else if (family() == IPv6)
	{
		const IPv6AddressImpl self(pImpl()->addr(), pImpl()->scope());
        const IPv6AddressImpl r = ~self;
		return IPAddress(r.addr(), sizeof(struct in6_addr), r.scope());
	}
#endif
	else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
}
예제 #12
0
IPAddress  FishinoUDP::remoteIP()
{
	IPAddress ip;
	bool res = Fishino.udpRemoteIP(_sock, ip);
	if(!res)
		return IPAddress(0, 0, 0, 0);
	return ip;
}
예제 #13
0
void startAP()
{
    WifiAccessPoint.enable(true);
    WifiAccessPoint.config("Sming InternetOfThings", "", AUTH_OPEN);

	// Optional: Change IP addresses (and disable DHCP)
	WifiAccessPoint.setIP(IPAddress(192, 168, 4, 1));    
}
예제 #14
0
 IPAddress IPAddress::AsIPv6Address() const {
     if (family_ != AF_INET) {
         return *this;
     }
     in6_addr v6addr = kV4MappedPrefix;
     ::memcpy(&v6addr.s6_addr[12], &u_.ip4.s_addr, sizeof(u_.ip4.s_addr));
     return IPAddress(v6addr);
 }
예제 #15
0
 bool IPFromString(const std::string& str, IPAddress* out) {
     if (!out) {
         return false;
     }
     in_addr addr;
     if (::inet_pton(AF_INET, str.c_str(), &addr) == 0) {
         in6_addr addr6;
         if (::inet_pton(AF_INET6, str.c_str(), &addr6) == 0) {
             *out = IPAddress();
             return false;
         }
         *out = IPAddress(addr6);
     } else {
         *out = IPAddress(addr);
     }
     return true;
 }
예제 #16
0
void udp_srv::begin()
{
    std::function<void(command_response_packet&)> f = std::bind(&udp_srv::broadcast_ack, this, std::placeholders::_1);
    command_layer::register_udp_ack_func(f);
    udp.connect(IPAddress(192,168,1,255),4140);
    udp.listen(4120);
    udp.onPacket([this](AsyncUDPPacket& packet){this->udp_packet_callback(packet);});
}
   bool
   SpamAssassinTestConnect::TestConnect(const String &hostName, int port, String &message)
   {
     
      String bodyText = 
         "From: [email protected]\r\n"
         "\r\n"
         "XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X.\r\n";

      String tempFile = FileUtilities::GetTempFileName();
      FileUtilities::WriteToFile(tempFile, bodyText, false);

      std::shared_ptr<IOService> pIOService = Application::Instance()->GetIOService();

      bool testCompleted;

      std::shared_ptr<Event> disconnectEvent = std::shared_ptr<Event>(new Event());
      std::shared_ptr<SpamAssassinClient> pSAClient = std::shared_ptr<SpamAssassinClient>(new SpamAssassinClient(tempFile, pIOService->GetIOService(), pIOService->GetClientContext(), disconnectEvent, testCompleted));

      DNSResolver resolver;

      std::vector<String> ip_addresses;
      resolver.GetARecords(hostName, ip_addresses);

      String ip_address;
      if (ip_addresses.size())
      {
         ip_address = *(ip_addresses.begin());
      }
      else
      {
         message = "The IP address for SpamAssassin could not be resolved. Aborting tests.";
         ErrorManager::Instance()->ReportError(ErrorManager::High, 5507, "SpamAssassinTestConnect::TestConnect", message);
         return false;
      }

      // Here we handle of the ownership to the TCPIP-connection layer.
      if (pSAClient->Connect(ip_address, port, IPAddress()))
      {
         // Make sure we keep no references to the TCP connection so that it
         // can be terminated whenever. We're longer own the connection.
         pSAClient.reset();

         disconnectEvent->Wait();
      }

      if (testCompleted)
         message = FileUtilities::ReadCompleteTextFile(tempFile);
      else
      {
         message = "Unable to connect to the specified SpamAssassin server.";
      }

      FileUtilities::DeleteFile(tempFile);

      return testCompleted;

   }
예제 #18
0
   set<boost::shared_ptr<SpamTestResult> >
   SpamTestSpamAssassin::RunTest(boost::shared_ptr<SpamTestData> pTestData)
   {
      set<boost::shared_ptr<SpamTestResult> > setSpamTestResults;
      
      AntiSpamConfiguration& config = Configuration::Instance()->GetAntiSpamConfiguration();

      boost::shared_ptr<Message> pMessage = pTestData->GetMessageData()->GetMessage();
      const String sFilename = PersistentMessage::GetFileName(pMessage);
      
      boost::shared_ptr<SpamAssassinClient> pSAClient = boost::shared_ptr<SpamAssassinClient>(new SpamAssassinClient(sFilename));

      boost::shared_ptr<TCPConnection> pClientConnection = Application::Instance()->GetIOCPServer()->CreateConnection();
      pClientConnection->Start(pSAClient);
      
      String sHost = config.GetSpamAssassinHost();
      int iPort = config.GetSpamAssassinPort();
      // Copy the event so that we know when we've disconnected.
      Event disconnectEvent(pClientConnection->GetConnectionTerminationEvent());

      // Here we handle of the ownership to the TCPIP-connection layer.
      if (pClientConnection->Connect(sHost, iPort, IPAddress()))
      {
         // Make sure we keep no references to the TCP connection so that it
         // can be terminated whenever. We're longer own the connection.
         pClientConnection.reset();

         disconnectEvent.Wait();
      }

      // Copy back the file...
      pSAClient->FinishTesting();
      
       
      // Check if the message is tagged as spam.
      boost::shared_ptr<MessageData> pMessageData = pTestData->GetMessageData();
      pMessageData->RefreshFromMessage();

      bool bIsSpam = false;
      AnsiString sSpamStatus = pMessageData->GetFieldValue("X-Spam-Status");
      if (sSpamStatus.Mid(0, 3).ToUpper() == "YES")
         bIsSpam = true;

      if (bIsSpam)
      {
         int iScore = 0;
         if (config.GetSpamAssassinMergeScore())
            iScore = _ParseSpamAssassinScore(sSpamStatus);
         else
            iScore = config.GetSpamAssassinScore();

         String sMessage = "Tagged as Spam by SpamAssassin";
         boost::shared_ptr<SpamTestResult> pResult = boost::shared_ptr<SpamTestResult>(new SpamTestResult(GetName(), SpamTestResult::Fail, iScore, sMessage));
         setSpamTestResults.insert(pResult);   
      }
      
      return setSpamTestResults;
   }
AppWIFI::AppWIFI() {
	_ApIP = IPAddress(String(DEFAULT_AP_IP));
	_client_err_msg = "";
	_con_ctr = 0;
	_scanning = false;
	_dns_active = false;
	_new_connection = false;
	_client_status = CONNECTION_STATUS::IDLE;
}
예제 #20
0
// ret 1 = error
int32_t MTD_FLASHMEM Socket::read(void *buffer, uint32_t maxLength, IPAddress *sourceAddress, uint16_t *sourcePort) {
  sockaddr_in from;
  int fromlen;
  int32_t bytesRecv = lwip_recvfrom(m_socket, buffer, maxLength, 0, (sockaddr *)&from, (socklen_t *)&fromlen);
  if (bytesRecv > 0) {
    *sourceAddress = IPAddress(from.sin_addr.s_addr);
    *sourcePort = ntohs(from.sin_port);
  }
  return bytesRecv;
}
예제 #21
0
파일: IPAddress.cpp 프로젝트: Zethes/CGUL
/** @details A network address defines the "bottom-most" address for a given network.
 *  @param ip An IP address on the network.
 *  @param netmask The netmask defining the network range.
 *  @returns The network address.
 */
_CGUL_EXPORT CGUL::Network::IPAddress CGUL::Network::IPAddress::CalculateNetwork(const IPAddress& ip, const IPAddress& netmask)
{
    if (!ip.IsValid() || ip.GetType() != netmask.GetType())
    {
        throw NetworkException(NetworkExceptionCode::FAILED_CALCULATE_ADDRESS, NetworkExceptionReason::ADDRESS_MISMATCH);
    }

    if (ip.GetType() == IPAddressType::IPV4)
    {
        return IPAddress(ip.ToUInt32() & netmask.ToUInt32());
    }
    else
    {
        UInt64 network[2];
        network[0] = ip.address[0] & netmask.address[0];
        network[1] = ip.address[1] & netmask.address[1];
        return IPAddress(network);
    }
}
예제 #22
0
int TunManager::getAddrRespParser(const struct sockaddr_nl *who,
                                  struct nlmsghdr *n,
                                  void *arg) {
  // only cares about RTM_NEWADDR
  if (n->nlmsg_type != RTM_NEWADDR) {
    return 0;
  }
  struct ifaddrmsg *ifa = static_cast<struct ifaddrmsg *>(NLMSG_DATA(n));
  struct rtattr *tb[IFA_MAX + 1];
  int len = n->nlmsg_len;
  len -= NLMSG_LENGTH(sizeof(*ifa));
  if (len < 0) {
    throw FbossError("Wrong length for RTM_GETADDR response ", len, " vs ",
                     NLMSG_LENGTH(sizeof(*ifa)));
  }
  // only care about v4 and v6 address
  if (ifa->ifa_family != AF_INET && ifa->ifa_family != AF_INET6) {
    VLOG(3) << "Skip address from device @ index "
            << static_cast<int>(ifa->ifa_index)
            << " because of its address family "
            << static_cast<int>(ifa->ifa_family);
    return 0;
  }

  parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), len);
  if (tb[IFA_ADDRESS] == nullptr) {
    VLOG(3) << "Device @ index " << static_cast<int>(ifa->ifa_index)
            << " does not have address at family "
            << static_cast<int>(ifa->ifa_family);
    return 0;
  }
  IPAddress addr;
  const void *data = RTA_DATA(tb[IFA_ADDRESS]);
  if (ifa->ifa_family == AF_INET) {
    addr = IPAddress(*static_cast<const in_addr *>(data));
  } else {
    addr = IPAddress(*static_cast<const in6_addr *>(data));
  }

  TunManager *mgr = static_cast<TunManager *>(arg);
  mgr->addProbedAddr(ifa->ifa_index, addr, ifa->ifa_prefixlen);
  return 0;
}
예제 #23
0
파일: SocketSpec.cpp 프로젝트: liveck/x0
void SocketSpec::clear()
{
	type_ = Unknown;

	ipaddr_ = IPAddress();
	local_.clear();

	port_ = -1;
	backlog_ = -1;
}
예제 #24
0
/**
 * get an IP for a client
 * @param num uint8_t client id
 * @return IPAddress
 */
IPAddress WebSocketsServer::remoteIP(uint8_t num) {
    if(num < WEBSOCKETS_SERVER_CLIENT_MAX) {
        WSclient_t * client = &_clients[num];
        if(clientIsConnected(client)) {
            return client->tcp.remoteIP();
        }
    }

    return IPAddress();
}
예제 #25
0
bool wxIPV6address::IsLocalHost() const
{
    if ( Hostname() == "localhost" )
        return true;

    wxString addr = IPAddress();
    return addr == wxT("::1") ||
                addr == wxT("0:0:0:0:0:0:0:1") ||
                    addr == wxT("::ffff:127.0.0.1");
}
예제 #26
0
/**
 * DNS callback
 * @param name
 * @param ipaddr
 * @param callback_arg
 */
void wifi_dns_found_callback(const char *name, CONST ip_addr_t *ipaddr, void *callback_arg)
{
    (void) name;
    if (!_dns_lookup_pending) {
        return;
    }
    if(ipaddr) {
        (*reinterpret_cast<IPAddress*>(callback_arg)) = IPAddress(ipaddr);
    }
    esp_schedule(); // resume the hostByName function
}
예제 #27
0
/* Start WiFiUDP socket, listening at local port */
uint8_t WiFiUDP::begin(uint16_t port)
{
    if (_ctx) {
        _ctx->unref();
        _ctx = 0;
    }

    _ctx = new UdpContext;
    _ctx->ref();
    return (_ctx->listen(IPAddress(), port)) ? 1 : 0;
}
예제 #28
0
파일: IPAddress.cpp 프로젝트: fjz13/Medusa
IPAddress IPAddress::Remote(SOCKET socket)
{
	sockaddr_in6 localaddr;
	Memory::ClearZero(&localaddr);
	socklen_t addrlen = static_cast<socklen_t>(sizeof(localaddr));
	if (::getpeername(socket, (sockaddr*)(&localaddr), &addrlen) < 0)
	{
		Log::AssertFailed("Failed to IPAddress::Local");
	}
	return IPAddress(localaddr);
}
예제 #29
0
IPAddress IPAddress::Parse(RCString ipString) {
	uint8_t buf[16];
	if (CCheck(::inet_pton(AF_INET, ipString, buf)))
		return IPAddress(Span(buf, 4));
	if (CCheck(::inet_pton(AF_INET6, ipString, buf)))
		return IPAddress(Span(buf, 16));
	/*!!!R
#if UCFG_USE_REGEX
#	if UCFG_WIN32
	if (regex_search(ipString, *s_reDomainName)) {
#	else
	if (regex_search(ipString.c_str(), s_reDomainName)) {
#	endif
		IPAddress r;
		r.AddressFamily = Ext::AddressFamily(AF_DOMAIN_NAME);
		r.m_domainname = ipString;
		return r;
	}
#endif */
	Throw(HRESULT_FROM_WIN32(DNS_ERROR_INVALID_IP_ADDRESS));
}
예제 #30
0
void setupMode() {
    digitalWrite(RETPIN, HIGH);
    Serial.println("Setup mode started");
    setupModeStatus = (boolean) true;

    //WiFI start in client mode
    blinkLed.violet(&led, 100, 1);
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    delay(200);

    //Write SSID_LIST in html
    blinkLed.violet(&led, 100, 1);
    Serial.println("Scan WiFi networks");
    SSID_LIST = ssidList();
    delay(100);

    //WiFi start in access point mode
    blinkLed.violet(&led, 100, 1);
    WiFi.mode(WIFI_AP);
    WiFi.softAPConfig(AP_IP, AP_IP, IPAddress(255, 255, 255, 0));
    WiFi.softAP(AP_SSID.c_str());
    DNS_SERVER.start(53, "*", AP_IP);
    Serial.print("Starting Access Point at ");
    Serial.println(WiFi.softAPIP());
    if (!MDNS.begin("airbutton")) {
        Serial.println("Error setting up MDNS responder!");
        delay(1000);
    }
    Serial.println("mDNS responder started");
    blinkLed.violet(&led, 100, 2);

    // Settings Page
    WEB_SERVER.on("/wifi.html", handleWiFi);
    WEB_SERVER.on("/ifttt.html", handleIFTTT);
    WEB_SERVER.on("/customurl.html", handleCustomURL);
    WEB_SERVER.on("/mqtt.html",handleMQTT);

    WEB_SERVER.on("/setwifi.html", handleSetWiFi);
    WEB_SERVER.on("/setifttt.html", handleSetIFTTT);
    WEB_SERVER.on("/setcustomurl.html", handleSetCustomURL);
    WEB_SERVER.on("/setmqtt.html", handleSetMQTT);

    WEB_SERVER.on("/reboot.html", handleReboot);
    WEB_SERVER.serveStatic("/css/basic.css",SPIFFS,"/css/basic.css");
    WEB_SERVER.serveStatic("/css/custom.css",SPIFFS,"/css/custom.css");
    WEB_SERVER.serveStatic("/css/simple.css",SPIFFS,"/css/simple.css");
    WEB_SERVER.serveStatic("/img/logo_color_small.png",SPIFFS,"/img/logo_color_small.png");
    WEB_SERVER.onNotFound(handleNotFound);
    WEB_SERVER.begin();
    MDNS.addService("http", "tcp", 80);
    startTime = millis();
}