Ethernet shield server test (new code Uno ok)

I am testing my new web server code. It is exposed to the internet, and appears to be fending off most hack attempts, and has not crashed. I'm not asking that you DoS my Arduino, but I would like a few users to test it.
Here is the dynamic page. It does nothing but display your input on my serial monitor.
http://68.99.58.119

Here are the SD pages. These are all stored on the ethernet shield's SD card. The favicon.ico is an upper case blue 'T' on a white background.

This page downloads 3 files (/index.htm, /img/wolver.jpg, and /favicon.ico). The Wolverines image is around 240K.
http://68.99.58.119/index.htm
BTW, I am in the back row second from right. I was really young then. That is a pic of the first AYSO championship team.

This page downloads 4 files (/testhtml.htm, /mycss.css, /img/waterfal.jpg, and /favicon.ico). The background image (waterfal.jpg) is set by the mycss.css file. The background image is about 120K.
http://68.99.58.119/testhtml.htm

Does it work on your end?

it works.

ntruchsess:
it works.

Thanks! :slight_smile: It looked clean from this end too. The only thing I find bothersome is no way to view the client ip and port with the standard ethernet library.

36 hours later, exposed to the internet and 127 file uploads later, it is still running fine.

So much for being nice. Take off the gloves and do your worst. :astonished:
http://68.99.58.119
http://68.99.58.119/index.htm
http://68.99.58.119/testhtml.htm

edit: My only request is if you get it to fail, let me know what you did to it.

You can also download just the pictures.
http://68.99.58.119/img/wolver.jpg
http://68.99.58.119/img/waterfal.jpg

Do not be afraid to attack it. It has already been attacked by a /cgi-bin/ rootkit attack and a php/mysql insertion attack. It brushed off both easily.

Coming up on 60 hours now without a fail. I will run it all day, then I need that Mega back for other stuff. That will be 3 days exposed to the internet without a fail.

Interesting hack attempts tho. Mostly oversized requests to weird directories, like /cgi-bin/.

My ISP went down at 5am this morning for about 30 minutes, but the server didn't notice. It is still running. You can get to it now.

edit: This is the time when I miss being able to access the remote ip/port of the client. You really can't do any kind of effective log without that. :frowning:

Working fine here too. No error at all!

H2SO4:
Working fine here too. No error at all!

I saw you roll through. You didn't try anything except downloading both pages. Here are a couple links that should throw an error:
This should throw a "Bad request" page
http://68.99.58.119/cgi-bin/setup.php
This should throw a "File not found" page
http://68.99.58.119/badpage.htm

edit: I saw you try those also. It worked here.

Just tested and it acts as you said.

OH! NICE TRY!! Commas in the filename. And it brushed you off with a "Bad request" page. At least that is what it showed here.

this is really awesome! are you going to post any example code? i would like to work with storing things on the sd card but dont know where to start.

If it survives the day, I will post the code on the playground. I may do a little testing and modification first. I don't like the way it handled the HEAD requests, so I changed that in my sketch and will test it online later.

The real disadvantage of this is the size of the sketch. It compiles to about 29K on my Mega. That would leave very little operating memory for an Uno.

very nice,

can see the web pages here just fine,
using chrome.

I have checked Chrome, IE, and Firefox. All show those pages just about the same way.

The background image displays different that the embedded image, at least on my browser versions. The embedded image displays as it downloads. The background image does not display until the entire image is downloaded.

I posted the new code on the playground. The new code is the top sketch, and the old code is at the bottom.
http://playground.arduino.cc/Code/WebServerST
There are a lot of "#ifdef ServerDEBUG" statements so you can save about 1.6K by disabling the serial print stuff once your server is working ok.

I recommend using only alphanumerics for your file and directory names. Stay with 8 character directory names and 8.3 file names.

edit: This is the time when I miss being able to access the remote ip/port of the client. You really can't do any kind of effective log without that.

Have you tried the below setup? The remote IP address prints out to the serial monitor.

http://forum.arduino.cc/index.php?topic=82416.msg619420#msg619420

//zoomkat 12-8-11
//simple button GET with iframe code
//for use with IDE 1.0
//open serial monitor to see what the arduino receives
//use the \ slash to escape the " in the html 
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields
//remote IP info
// http://arduino.cc/forum/index.php/topic,82416.0.html 

#include <SPI.h>
#include <Ethernet.h>

byte rip[4];
//byte rip[] = {0,0,0,0};
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port

String readString; 

//////////////////////

void setup(){

  pinMode(5, OUTPUT); //pin selected to control
  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();

  //enable serial data print 
  Serial.begin(9600); 
  Serial.println("server LED test 1.0"); // so I can keep track of what is loaded
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
          //Serial.print(c);
        } 

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 
client.getRemoteIP(rip);
for (int bcount= 0; bcount < 4; bcount++)
     { 
        Serial.print(rip[bcount], DEC); 
        if (bcount<3) Serial.print(".");
     } 

Serial.println();
          //now output HTML data header
             if(readString.indexOf('?') >=0) { //don't send new page
               client.println("HTTP/1.1 204 Zoomkat");
               client.println();
               client.println();  
             }
             else {
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Arduino GET test page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>Zoomkat's simple Arduino button</H1>");
          
          client.println("<a href=\"/?on\" target=\"inlineframe\">ON</a>"); 
          client.println("<a href=\"/?off\" target=\"inlineframe\">OFF</a>"); 

          //client.println("<IFRAME name=inlineframe src=\"res://D:/WINDOWS/dnserror.htm\" width=1 height=1\">");
          client.println("<IFRAME name=inlineframe style=\"display:none\" >");          
          client.println("</IFRAME>");

          client.println("</BODY>");
          client.println("</HTML>");
             }

          delay(1);
          //stopping client
          client.stop();

          ///////////////////// control arduino pin
          if(readString.indexOf("on") >0)//checks for on
          {
            digitalWrite(5, HIGH);    // set pin 5 high
            Serial.println("Led On");
          }
          if(readString.indexOf("off") >0)//checks for off
          {
            digitalWrite(5, LOW);    // set pin 5 low
            Serial.println("Led Off");
          }
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

@zoomkat: The getRemoteIP() function is not in the standard ethernet library. You and I both can modify the library to get that IP, but I meant using the standard library without modifying it.

Yep, worked for me.

Now to go look at your Playground code to see why mine's not working like that!

Ok, I think mine might be a subnet thing.... that's always confused me. Sorry to hijack your thread for a sec ST, but pray indulge me 8)

I know for my router / modem / whatever the hell it's really called, its LAN side IP is 10.0.0.2 and I'm using 10.0.0.200 as a fixed addy for my shield (router dhcp uses .100 to .199). I also know the router LAN side subnet mask is 255.255.255.0 and the WAN side mask is 255.255.255.255.

First bit of advice then please ST... in this section of your code:

// this must be unique
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEC };

// change to your network settings
IPAddress ip( 192,168,2,2 );
IPAddress gateway( 192,168,2,1 );
IPAddress subnet( 255,255,255,0 ); //<<<<<<<<<<<<<<<<<<<<<<<<<<<

EthernetServer server(80);

.... is that subnet (arrowed) the LAN or WAN side? I'm guessing LAN side since it's with other LAN side addys.

And secondly, here:

Ethernet.begin(mac, ip, gateway, gateway, subnet);

.... why does it say gateway, gateway? Why twice?

Hope you can clarify please Tim? (I won't be able to test for a while, we're about to get a huuuuuuuge lightening storm and since we live (literally to with a metre or ten) of Johannesburg's highest point, we unplug when it looks threatening...)

That is the localnet setting. Like I said earlier, I port forward 68.99.58.119/255.255.255.224 through the router to 192.168.2.2/255.255.255.0.

There are two "gateway" values sent in that call because I am not using dns on my server. The actual parameters are this:
Ethernet.begin(mac, ip, dnServer, gateway, subnet);
I use the gateway ip as my dns server, which it will do.

Thanks Tim.... so last question then, since my router tells me its WAN side DNS addy, should I use that?- or should is this also a LAN side thing in which case I should use the same as gateway? Or could I just place-hold with ,, thus: Ethernet.begin(mac, ip, , gateway, subnet);