Skip to content

Commit

Permalink
Add echo server application (tcpechoserver/udpechoserver)
Browse files Browse the repository at this point in the history
  • Loading branch information
pandax381 committed Mar 9, 2020
1 parent 310b1d0 commit 4e84b9b
Show file tree
Hide file tree
Showing 5 changed files with 283 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ NET_UPROGS=\
_ifset\
_ifup\
_ifdown\
_tcpechoserver\
_udpechoserver\

UPROGS += $(NET_UPROGS)

Expand Down
53 changes: 53 additions & 0 deletions tcpechoserver.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "types.h"
#include "user.h"
#include "socket.h"

int
main (int argc, char *argv[])
{
int soc, acc, peerlen, ret;
struct sockaddr_in self, peer;
unsigned char *addr;
char buf[2048];

printf(1, "Starting TCP Echo Server\n");
soc = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (soc == 1) {
printf(1, "socket: failure\n");
exit();
}
printf(1, "socket: success, soc=%d\n", soc);
self.sin_family = AF_INET;
self.sin_addr = INADDR_ANY;
self.sin_port = hton16(7);
if (bind(soc, (struct sockaddr *)&self, sizeof(self)) == -1) {
printf(1, "bind: failure\n");
close(soc);
exit();
}
addr = (unsigned char *)&self.sin_addr;
printf(1, "bind: success, self=%d.%d.%d.%d:%d\n", addr[0], addr[1], addr[2], addr[3], ntoh16(self.sin_port));
listen(soc, 100);
printf(1, "waiting for connection...\n");
peerlen = sizeof(peer);
acc = accept(soc, (struct sockaddr *)&peer, &peerlen);
if (acc == -1) {
printf(1, "accept: failure\n");
close(soc);
exit();
}
addr = (unsigned char *)&peer.sin_addr;
printf(1, "accept: success, peer=%d.%d.%d.%d:%d\n", addr[0], addr[1], addr[2], addr[3], ntoh16(peer.sin_port));
while (1) {
ret = recv(acc, buf, sizeof(buf));
if (ret <= 0) {
printf(1, "EOF\n");
break;
}
printf(1, "recv: %d bytes data received\n", ret);
hexdump(buf, ret);
send(acc, buf, ret);
}
close(soc);
exit();
}
45 changes: 45 additions & 0 deletions udpechoserver.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "types.h"
#include "user.h"
#include "socket.h"

int
main (int argc, char *argv[])
{
int soc, peerlen, ret;
struct sockaddr_in self, peer;
unsigned char *addr;
char buf[2048];

printf(1, "Starting UDP Echo Server\n");
soc = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (soc == 1) {
printf(1, "socket: failure\n");
exit();
}
printf(1, "socket: success, soc=%d\n", soc);
self.sin_family = AF_INET;
self.sin_addr = INADDR_ANY;
self.sin_port = hton16(7);
if (bind(soc, (struct sockaddr *)&self, sizeof(self)) == -1) {
printf(1, "bind: failure\n");
close(soc);
exit();
}
addr = (unsigned char *)&self.sin_addr;
printf(1, "bind: success, self=%d.%d.%d.%d:%d\n", addr[0], addr[1], addr[2], addr[3], ntoh16(self.sin_port));
printf(1, "waiting for message...\n");
while (1) {
peerlen = sizeof(peer);
ret = recvfrom(soc, buf, sizeof(buf), (struct sockaddr *)&peer, &peerlen);
if (ret <= 0) {
printf(1, "EOF\n");
break;
}
addr = (unsigned char *)&peer.sin_addr;
printf(1, "recvfrom: %d bytes data received, peer=%d.%d.%d.%d:%d\n", ret, addr[0], addr[1], addr[2], addr[3], ntoh16(peer.sin_port));
hexdump(buf, ret);
sendto(soc, buf, ret, (struct sockaddr *)&peer, peerlen);
}
close(soc);
exit();
}
172 changes: 172 additions & 0 deletions ulib.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,175 @@ memmove(void *vdst, const void *vsrc, int n)
*dst++ = *src++;
return vdst;
}

#define isascii(x) ((x >= 0x00) && (x <= 0x7f))
#define isprint(x) ((x >= 0x20) && (x <= 0x7e))

void
hexdump (void *data, size_t size) {
int offset, index;
unsigned char *src;

src = (unsigned char *)data;
printf(1, "+------+-------------------------------------------------+------------------+\n");
for (offset = 0; offset < size; offset += 16) {
printf(1, "| ");
if (offset <= 0x0fff) printf(1, "0");
if (offset <= 0x00ff) printf(1, "0");
if (offset <= 0x000f) printf(1, "0");
printf(1, "%x | ", offset);
for (index = 0; index < 16; index++) {
if(offset + index < (int)size) {
if (src[offset + index] <= 0x0f) printf(1, "0");
printf(1, "%x ", 0xff & src[offset + index]);
} else {
printf(1, " ");
}
}
printf(1, "| ");
for(index = 0; index < 16; index++) {
if(offset + index < (int)size) {
if(isascii(src[offset + index]) && isprint(src[offset + index])) {
printf(1, "%c", src[offset + index]);
} else {
printf(1, ".");
}
} else {
printf(1, " ");
}
}
printf(1, " |\n");
}
printf(1, "+------+-------------------------------------------------+------------------+\n");
}

#ifndef __BIG_ENDIAN
#define __BIG_ENDIAN 4321
#endif
#ifndef __LITTLE_ENDIAN
#define __LITTLE_ENDIAN 1234
#endif

static int endian;

static int
byteorder (void)
{
uint32_t x = 0x00000001;
return *(uint8_t *)&x ? __LITTLE_ENDIAN : __BIG_ENDIAN;
}

static uint16_t
byteswap16(uint16_t v)
{
return (v & 0x00ff) << 8 | (v & 0xff00 ) >> 8;
}

static uint32_t
byteswap32(uint32_t v)
{
return (v & 0x000000ff) << 24 | (v & 0x0000ff00) << 8 | (v & 0x00ff0000) >> 8 | (v & 0xff000000) >> 24;
}

uint16_t
hton16 (uint16_t h)
{
if (!endian)
endian = byteorder();
return endian == __LITTLE_ENDIAN ? byteswap16(h) : h;
}

uint16_t
ntoh16 (uint16_t n)
{
if (!endian)
endian = byteorder();
return endian == __LITTLE_ENDIAN ? byteswap16(n) : n;
}

uint32_t
hton32(uint32_t h)
{
if (!endian)
endian = byteorder();
return endian == __LITTLE_ENDIAN ? byteswap32(h) : h;
}

uint32_t
ntoh32(uint32_t n)
{
if (!endian)
endian = byteorder();
return endian == __LITTLE_ENDIAN ? byteswap32(n) : n;
}

long
strtol(const char *s, char **endptr, int base)
{
int neg = 0;
long val = 0;

// gobble initial whitespace
while (*s == ' ' || *s == '\t')
s++;

// plus/minus sign
if (*s == '+')
s++;
else if (*s == '-')
s++, neg = 1;

// hex or octal base prefix
if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x'))
s += 2, base = 16;
else if (base == 0 && s[0] == '0')
s++, base = 8;
else if (base == 0)
base = 10;

// digits
while (1) {
int dig;

if (*s >= '0' && *s <= '9')
dig = *s - '0';
else if (*s >= 'a' && *s <= 'z')
dig = *s - 'a' + 10;
else if (*s >= 'A' && *s <= 'Z')
dig = *s - 'A' + 10;
else
break;
if (dig >= base)
break;
s++, val = (val * base) + dig;
// we don't properly detect overflow!
}

if (endptr)
*endptr = (char *) s;
return (neg ? -val : val);
}

int
ip_addr_pton (const char *p, ip_addr_t *n) {
char *sp, *ep;
int idx;
long ret;

sp = (char *)p;
for (idx = 0; idx < 4; idx++) {
ret = strtol(sp, &ep, 10);
if (ret < 0 || ret > 255) {
return -1;
}
if (ep == sp) {
return -1;
}
if ((idx == 3 && *ep != '\0') || (idx != 3 && *ep != '.')) {
return -1;
}
((uint8_t *)n)[idx] = ret;
sp = ep + 1;
}
return 0;
}
11 changes: 11 additions & 0 deletions user.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,14 @@ void* memset(void*, int, uint);
void* malloc(uint);
void free(void*);
int atoi(const char*);
// additional functions
void hexdump(void *data, size_t size);
uint16_t hton16(uint16_t h);
uint16_t ntoh16(uint16_t n);
uint32_t hton32(uint32_t h);
uint32_t ntoh32(uint32_t n);
long strtol(const char *s, char **endptr, int base);
int ip_addr_pton(const char *p, ip_addr_t *n);

#define IP_ADDR_LEN 4
#define IP_ADDR_STR_LEN 16 /* "ddd.ddd.ddd.ddd\0" */

0 comments on commit 4e84b9b

Please sign in to comment.