Skip to content

Commit b97c95b

Browse files
authored
Merge pull request #2538 from ghaerr/arp
[net] Cleanup arp, netstat, httpd source. Reduce executable and memory sizes also
2 parents 5d3bf09 + 96b60d3 commit b97c95b

File tree

5 files changed

+200
-195
lines changed

5 files changed

+200
-195
lines changed

elkscmd/inet/httpd/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ include $(BASEDIR)/Makefile-rules
55
###############################################################################
66

77
LOCALFLAGS=-I$(ELKSCMD_DIR)
8-
LDFLAGS += -maout-heap=1024 -maout-stack=1024
8+
LDFLAGS += -maout-heap=256 -maout-stack=2048
99

1010
###############################################################################
1111

elkscmd/inet/httpd/httpd.c

Lines changed: 143 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -36,177 +36,179 @@
3636
#include <arpa/inet.h>
3737
#include <sys/wait.h>
3838

39-
#define DEF_PORT 80
40-
#define DEF_CONTENT "text/html"
39+
#define DEF_PORT 80
40+
#define DEF_CONTENT "text/html"
4141

42-
#define WS(c) ( ((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n') )
42+
#define WS(c) ( ((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n') )
4343

44-
int listen_sock;
45-
char buf[1536];
44+
#define errmsg(str) write(STDERR_FILENO, str, sizeof(str) - 1)
4645

4746
char* get_mime_type(char *name)
4847
{
49-
char* dot;
48+
char *dot;
5049

5150
dot = strrchr( name, '.' );
5251
if ( dot == (char*) 0 )
53-
return "text/plain";
52+
return "text/plain";
5453
if ( strcmp( dot, ".html" ) == 0 || strcmp( dot, ".htm" ) == 0 )
55-
return "text/html";
54+
return "text/html";
5655
if ( strcmp( dot, ".jpg" ) == 0 || strcmp( dot, ".jpeg" ) == 0 )
57-
return "image/jpeg";
56+
return "image/jpeg";
5857
if ( strcmp( dot, ".gif" ) == 0 )
59-
return "image/gif";
58+
return "image/gif";
6059
if ( strcmp( dot, ".png" ) == 0 )
61-
return "image/png";
60+
return "image/png";
6261
if ( strcmp( dot, ".css" ) == 0 )
63-
return "text/css";
62+
return "text/css";
6463
if ( strcmp( dot, ".vrml" ) == 0 || strcmp( dot, ".wrl" ) == 0 )
65-
return "model/vrml";
64+
return "model/vrml";
6665
if ( strcmp( dot, ".midi" ) == 0 || strcmp( dot, ".mid" ) == 0 )
67-
return "audio/midi";
66+
return "audio/midi";
6867
return "text/plain";
6968
}
7069

7170
void send_header(int fd, char *ct)
7271
{
73-
buf[0] = 0;
74-
sprintf(buf, "HTTP/1.0 200 OK\r\nServer: nanoHTTPd/0.1\r\nDate: Thu Apr 26 15:37:46 GMT 2001\r\nContent-Type: %s\r\n",ct);
75-
write(fd, buf, strlen(buf));
72+
char buf[128];
73+
74+
sprintf(buf, "HTTP/1.0 200 OK\r\nServer: nanoHTTPd/0.1\r\n"
75+
"Date: Thu Apr 26 15:37:46 GMT 2001\r\n"
76+
"Content-Type: %s\r\n",ct);
77+
write(fd, buf, strlen(buf));
7678
}
7779

7880
void send_error(int fd, int errnum, char *str)
7981
{
80-
sprintf(buf,"HTTP/1.0 %d %s\r\nContent-type: %s\r\n", errnum, str, DEF_CONTENT);
81-
write(fd, buf, strlen(buf));
82-
sprintf(buf,"Connection: close\r\nDate: Thu Apr 26 15:37:46 GMT 2001\r\n\r\n%s\r\n",str);
83-
write(fd, buf, strlen(buf));
82+
char buf[128];
83+
84+
sprintf(buf,"HTTP/1.0 %d %s\r\nContent-type: %s\r\n", errnum, str, DEF_CONTENT);
85+
write(fd, buf, strlen(buf));
86+
sprintf(buf,"Connection: close\r\n"
87+
"Date: Thu Apr 26 15:37:46 GMT 2001\r\n"
88+
"\r\n%s\r\n", str);
89+
write(fd, buf, strlen(buf));
8490
}
8591

8692
void process_request(int fd)
8793
{
88-
int fin, ret;
89-
off_t size;
90-
char *c, *file, fullpath[PATH_MAX];
91-
struct stat st;
92-
93-
ret = read(fd, buf, sizeof(buf));
94-
95-
c = buf;
96-
while (*c && !WS(*c) && c < (buf + sizeof(buf))){
97-
c++;
98-
}
99-
*c = 0;
100-
101-
if (strcasecmp(buf, "get")){
102-
send_error(fd, 404, "Method not supported");
103-
return;
104-
}
105-
106-
file = ++c;
107-
while (*c && !WS(*c) && c < (buf + sizeof(buf))){
108-
c++;
109-
}
110-
*c = 0;
111-
112-
/* TODO : Use strncat when security is the only problem of this server! */
113-
strcpy(fullpath, _PATH_DOCBASE);
114-
strcat(fullpath, file);
115-
116-
if (!stat(fullpath, &st) && (st.st_mode & S_IFMT) == S_IFDIR) {
117-
if (file[strlen(fullpath) - 1] != '/'){
118-
strcat(fullpath, "/");
119-
}
120-
strcat(fullpath, "index.html");
121-
}
122-
123-
fin = open(fullpath, O_RDONLY);
124-
if (fin < 0){
125-
send_error(fd, 404, "Document (probably) not found");
126-
return;
127-
}
128-
size = lseek(fin, (off_t)0, SEEK_END);
129-
lseek(fin, (off_t)0, SEEK_SET);
130-
send_header(fd, get_mime_type(fullpath));
131-
sprintf(buf,"Content-Length: %ld\r\n\r\n", size);
132-
write(fd, buf, strlen(buf));
133-
134-
do {
135-
ret = read(fin, buf, sizeof(buf));
136-
if (ret > 0)
137-
ret = write(fd, buf, ret);
138-
} while (ret == sizeof(buf));
139-
140-
close(fin);
141-
94+
int fin, ret;
95+
char *c, *file;
96+
off_t size;
97+
struct stat st;
98+
char fullpath[PATH_MAX];
99+
char buf[1536+1];
100+
101+
if ((ret = read(fd, buf, sizeof(buf)-1)) <= 0)
102+
return;
103+
c = buf;
104+
while (*c && !WS(*c) && (c - buf) < ret)
105+
c++;
106+
*c = '\0';
107+
108+
if (strcasecmp(buf, "get")) {
109+
send_error(fd, 404, "Method not supported");
110+
return;
111+
}
112+
113+
file = ++c;
114+
while (*c && !WS(*c) && (c - buf) < ret)
115+
c++;
116+
*c = '\0';
117+
118+
/* TODO : Use strncat when security is the only problem of this server! */
119+
strcpy(fullpath, _PATH_DOCBASE);
120+
strcat(fullpath, file);
121+
122+
if (!stat(fullpath, &st) && (st.st_mode & S_IFMT) == S_IFDIR) {
123+
if (file[strlen(fullpath) - 1] != '/')
124+
strcat(fullpath, "/");
125+
strcat(fullpath, "index.html");
126+
}
127+
128+
fin = open(fullpath, O_RDONLY);
129+
if (fin < 0) {
130+
send_error(fd, 404, "Document (probably) not found");
131+
return;
132+
}
133+
size = lseek(fin, 0, SEEK_END);
134+
lseek(fin, 0, SEEK_SET);
135+
send_header(fd, get_mime_type(fullpath));
136+
sprintf(buf,"Content-Length: %ld\r\n\r\n", size);
137+
write(fd, buf, strlen(buf));
138+
139+
do {
140+
ret = read(fin, buf, sizeof(buf));
141+
if (ret > 0)
142+
ret = write(fd, buf, ret);
143+
} while (ret == sizeof(buf));
144+
close(fin);
142145
}
143146

144147
int main(int argc, char **argv)
145148
{
146-
int ret, conn_sock;
147-
struct sockaddr_in localadr;
148-
149-
if ((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
150-
perror("httpd");
151-
return -1;
152-
}
153-
154-
/* set local port reuse, allows server to be restarted in less than 10 secs */
155-
ret = 1;
156-
if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &ret, sizeof(int)) < 0)
157-
perror("SO_REUSEADDR");
158-
159-
/* set small listen buffer to save ktcp memory */
160-
ret = SO_LISTEN_BUFSIZ;
161-
if (setsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, &ret, sizeof(int)) < 0)
162-
perror("SO_RCVBUF");
163-
164-
localadr.sin_family = AF_INET;
165-
localadr.sin_port = htons(DEF_PORT);
166-
localadr.sin_addr.s_addr = INADDR_ANY;
167-
168-
if (bind(listen_sock, (struct sockaddr *)&localadr, sizeof(struct sockaddr_in)) < 0) {
169-
fprintf(stderr, "httpd: bind error (may already be running)\n");
170-
return 1;
171-
}
172-
if (listen(listen_sock, 5) < 0) {
173-
perror("listen");
174-
return 1;
175-
}
176-
177-
/* become daemon, debug output on 1 and 2*/
178-
if ((ret = fork()) == -1) {
179-
perror("httpd");
180-
return 1;
181-
}
182-
if (ret) exit(0);
183-
ret = open("/dev/null", O_RDWR); /* our log file! */
184-
dup2(ret, 0);
185-
dup2(ret, 1);
186-
dup2(ret, 2);
187-
if (ret > 2)
188-
close(ret);
189-
setsid();
190-
191-
while (1) {
192-
conn_sock = accept(listen_sock, NULL, NULL);
193-
194-
if (conn_sock < 0) {
195-
if (errno == ENOTSOCK)
196-
exit(1);
197-
continue;
198-
}
199-
200-
if ((ret = fork()) == -1)
201-
perror("httpd");
202-
else if (ret == 0) {
203-
close(listen_sock);
204-
process_request(conn_sock);
205-
close(conn_sock);
206-
exit(0);
207-
} else {
208-
close(conn_sock);
209-
waitpid(ret, NULL, 0);
210-
}
211-
}
149+
int ret, conn_sock, listen_sock;
150+
struct sockaddr_in localadr;
151+
152+
if ((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
153+
errmsg("httpd: Network is down\n");
154+
return -1;
155+
}
156+
157+
/* set local port reuse, allows server to be restarted in less than 10 secs */
158+
ret = 1;
159+
if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &ret, sizeof(int)) < 0)
160+
errmsg("http: SO_REUSEADDR");
161+
162+
/* set small listen buffer to save ktcp memory */
163+
ret = SO_LISTEN_BUFSIZ;
164+
if (setsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, &ret, sizeof(int)) < 0)
165+
errmsg("httpd: SO_RCVBUF");
166+
167+
localadr.sin_family = AF_INET;
168+
localadr.sin_port = htons(DEF_PORT);
169+
localadr.sin_addr.s_addr = INADDR_ANY;
170+
if (bind(listen_sock, (struct sockaddr *)&localadr, sizeof(struct sockaddr_in)) < 0) {
171+
errmsg("httpd: bind error (may already be running)\n");
172+
return 1;
173+
}
174+
if (listen(listen_sock, 5) < 0) {
175+
errmsg("httpd: listen\n");
176+
return 1;
177+
}
178+
179+
/* become daemon, debug output on 1 and 2*/
180+
if ((ret = fork()) == -1) {
181+
errmsg("httpd: No more processes\n");
182+
return 1;
183+
}
184+
if (ret) exit(0);
185+
ret = open("/dev/null", O_RDWR); /* our log file! */
186+
dup2(ret, 0);
187+
dup2(ret, 1);
188+
dup2(ret, 2);
189+
if (ret > 2)
190+
close(ret);
191+
setsid();
192+
193+
while (1) {
194+
conn_sock = accept(listen_sock, NULL, NULL);
195+
if (conn_sock < 0) {
196+
if (errno == ENOTSOCK)
197+
exit(1);
198+
continue;
199+
}
200+
201+
if ((ret = fork()) == -1) {
202+
close(conn_sock);
203+
errmsg("httpd: No more processes\n");
204+
} else if (ret) {
205+
close(conn_sock);
206+
waitpid(ret, NULL, 0);
207+
} else {
208+
close(listen_sock);
209+
process_request(conn_sock);
210+
close(conn_sock);
211+
exit(0);
212+
}
213+
}
212214
}

elkscmd/inet/nettools/arp.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include <ktcp/arp.h>
2020
#include <arpa/inet.h>
2121

22+
#define errmsg(str) write(STDERR_FILENO, str, sizeof(str) - 1)
23+
2224
struct arp_cache arp_cache[ARP_CACHE_MAX];
2325

2426
char *mac_ntoa(eth_addr_t eth_addr)
@@ -37,38 +39,38 @@ int main(int ac, char **av)
3739
struct sockaddr_in localadr, remaddr;
3840

3941
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
40-
perror("arp");
41-
return 1;
42+
errmsg("arp: Network is down\n");
43+
return 1;
4244
}
4345

4446
localadr.sin_family = AF_INET;
4547
localadr.sin_port = PORT_ANY;
4648
localadr.sin_addr.s_addr = INADDR_ANY;
4749
if (bind(s, (struct sockaddr *)&localadr, sizeof(struct sockaddr_in)) < 0) {
48-
perror("bind");
49-
return 1;
50+
errmsg("arp: bind failure\n");
51+
return 1;
5052
}
5153

5254
remaddr.sin_family = AF_INET;
5355
remaddr.sin_port = htons(NETCONF_PORT);
5456
remaddr.sin_addr.s_addr = 0;
5557
if (connect(s, (struct sockaddr *)&remaddr, sizeof(struct sockaddr_in)) < 0) {
56-
perror("connect");
57-
return 1;
58+
errmsg("arp: Can't connect to ktcp\n");
59+
return 1;
5860
}
5961

6062
sr.type = NS_ARP;
61-
write(s, &sr, sizeof(sr));
63+
write(s, &sr, sizeof(sr));
6264
ret = read(s, arp_cache, ARP_CACHE_MAX*sizeof(struct arp_cache));
6365
if (ret != ARP_CACHE_MAX*sizeof(struct arp_cache)) {
64-
perror("read");
65-
return 1;
66+
errmsg("arp: Can't read ARP cache\n");
67+
return 1;
6668
}
6769

6870
for(i=0; i<ARP_CACHE_MAX; i++) {
69-
if (arp_cache[i].ip_addr)
70-
printf("%-15s %s\n", in_ntoa(arp_cache[i].ip_addr),
71-
mac_ntoa(arp_cache[i].eth_addr));
71+
if (arp_cache[i].ip_addr)
72+
printf("%-15s %s\n", in_ntoa(arp_cache[i].ip_addr),
73+
mac_ntoa(arp_cache[i].eth_addr));
7274
}
7375
return 1;
7476
}

0 commit comments

Comments
 (0)