ASAT
Senior Member
A simple HTTP server returns a static 1x1 pixels image. Similar to pixelserv. Written in less than 100 lines of C code. Compiles with the ARM toolchain included with Asuswrt-Merlin firmware. No Optware or Entware required.
nweb23.c
How to cross-compile this C code for the RT-AC68U, RT-AC56U and other ARMv7 Asuswrt-Merlin routers? You must have a working Linux build environment for compiling the Asuswrt-Merlin firmware because you need the ARM toolchain. To compile this program, type:
Then, reduce the size of binary file. After this, the binary file size will be ~71K.
Copy the Nweb binary to the router at /jffs/bin.
To start it, type:
Create a virtual IP address for Nweb. I also run a TOR transparent proxy for some devices on my network. That's why the additional NAT prerouting. And the filter, REJECT tcp-reset, apparently forces browsers to give up sooner on port 443 requests, such as https://1.0.0.1
Try it out. In a web browser, type:
http://1.0.0.1
OR
http://1.0.0.1/sddsf/sdfsd/fsdf/s/dfsd/fsd/fsd/fsd/fsdf/123456.html
You immediately get served with a (GIF Image, 1 x 1 pixels).
Will it work with /etc/hosts file for super fast ad blocking and page rendering?
The original C code was gotten here and modified.
nweb: a tiny, safe Web server (static pages only)
http://www.ibm.com/developerworks/systems/library/es-nweb/index.html
nweb23.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define VERSION 23
#define BUFSIZE 256
char imagedata[] = {0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x21,0xF9,0x04,0x01,0x00,0x00,0x01,0x00,0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x01,0x4C,0x00,0x3B};
/* this is a child web server process, so we can exit on errors */
void web(int fd, int hit)
{
long len=sizeof(imagedata);
static char buffer[BUFSIZE+1]; /* static so zero filled */
(void)sprintf(buffer,"HTTP/1.1 200 OK\nServer: nweb/%d.0\nContent-Length: %ld\nConnection: close\nContent-Type: image/gif\n\n", VERSION, len); /* Header + a blank line */
(void)write(fd,buffer,strlen(buffer));
/* send image data */
(void)write(fd,imagedata,len);
sleep(1); /* allow socket to drain before signalling the socket is closed */
close(fd);
exit(1);
}
int main(int argc, char **argv)
{
int i, port, pid, listenfd, socketfd, hit;
socklen_t length;
static struct sockaddr_in cli_addr; /* static = initialised to zeros */
static struct sockaddr_in serv_addr; /* static = initialised to zeros */
if( argc < 2 || argc > 2 || !strcmp(argv[1], "-?") ) {
(void)printf("hint: nweb Port-Number\t\tversion 23a\n\n"
"\tnweb is a small and very safe mini web server\n"
"\tThere is no fancy features = safe and secure.\n\n"
"\tExample: nweb 8181 &\n\n" );
(void)printf("\n\tNot Supported: URLs including \"..\", Java, Javascript, CGI\n"
"\tNo warranty given or implied\n\tNigel Griffiths nag@uk.ibm.com\n" );
exit(0);
}
/* Become deamon + unstopable and no zombies children (= no wait()) */
if(fork() != 0)
return 0; /* parent returns OK to shell */
(void)signal(SIGCLD, SIG_IGN); /* ignore child death */
(void)signal(SIGHUP, SIG_IGN); /* ignore terminal hangups */
for(i=0;i<32;i++)
(void)close(i); /* close open files */
(void)setpgrp(); /* break away from process group */
/* setup the network socket */
if((listenfd = socket(AF_INET, SOCK_STREAM,0)) <0) {
// logger(ERROR, "system call","socket",0);
}
port = atoi(argv[1]);
if(port < 0 || port >60000) {
// logger(ERROR,"Invalid port number (try 1->60000)",argv[1],0);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(port);
if(bind(listenfd, (struct sockaddr *)&serv_addr,sizeof(serv_addr)) <0) {
// logger(ERROR,"system call","bind",0);
}
if( listen(listenfd,64) <0) {
// logger(ERROR,"system call","listen",0);
}
for(hit=1; ;hit++) {
length = sizeof(cli_addr);
if((socketfd = accept(listenfd, (struct sockaddr *)&cli_addr, &length)) < 0) {
// logger(ERROR,"system call","accept",0);
}
if((pid = fork()) < 0) {
// logger(ERROR,"system call","fork",0);
}
else {
if(pid == 0) { /* child */
(void)close(listenfd);
web(socketfd,hit); /* never returns */
} else { /* parent */
(void)close(socketfd);
}
}
}
}
How to cross-compile this C code for the RT-AC68U, RT-AC56U and other ARMv7 Asuswrt-Merlin routers? You must have a working Linux build environment for compiling the Asuswrt-Merlin firmware because you need the ARM toolchain. To compile this program, type:
Code:
arm-brcm-linux-uclibcgnueabi-gcc -static -ffunction-sections -fdata-sections -O3 -pipe -march=armv7-a -mtune=cortex-a9 -fno-caller-saves -mfloat-abi=soft -Wall -fPIC -D_REENTRANT nweb23.c -o nweb
Then, reduce the size of binary file. After this, the binary file size will be ~71K.
Code:
arm-brcm-linux-uclibcgnueabi-strip nweb
Copy the Nweb binary to the router at /jffs/bin.
To start it, type:
Code:
/jffs/bin/nweb 81 &
# OR
# Start nweb if it is not already running
/bin/pidof nweb > /dev/null 2>&1 || (/jffs/bin/nweb 81 &)
Create a virtual IP address for Nweb. I also run a TOR transparent proxy for some devices on my network. That's why the additional NAT prerouting. And the filter, REJECT tcp-reset, apparently forces browsers to give up sooner on port 443 requests, such as https://1.0.0.1
Code:
iptables -t nat -I PREROUTING -d 1.0.0.1 -j RETURN
iptables -t nat -I PREROUTING -d 1.0.0.1 -p tcp --dport 80 -j REDIRECT --to-ports 81
iptables -I FORWARD -d 1.0.0.1 -j REJECT
iptables -I FORWARD -d 1.0.0.1 -p tcp -j REJECT --reject-with tcp-reset
Try it out. In a web browser, type:
http://1.0.0.1
OR
http://1.0.0.1/sddsf/sdfsd/fsdf/s/dfsd/fsd/fsd/fsd/fsdf/123456.html
You immediately get served with a (GIF Image, 1 x 1 pixels).
Will it work with /etc/hosts file for super fast ad blocking and page rendering?
The original C code was gotten here and modified.
nweb: a tiny, safe Web server (static pages only)
http://www.ibm.com/developerworks/systems/library/es-nweb/index.html
Last edited: