The originial uIP 0.6 sources

This commit is contained in:
Adam Dunkels
2013-03-27 21:29:27 +01:00
parent 7c0c5eee8f
commit 8ba1ecb51b
35 changed files with 1770 additions and 2433 deletions

View File

@@ -1,5 +1,3 @@
Most of the code for uIP falls under the following copyright license:
/*
* Copyright (c) 2001, Adam Dunkels.
* All rights reserved.
@@ -33,43 +31,6 @@ Most of the code for uIP falls under the following copyright license:
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: COPYRIGHT,v 1.2 2001/10/11 08:29:40 adam Exp $
*
*/
The H8S/2148 port (in the h8/ subdirectory) was done by Paul Clarke
and his code falls under the following license:
/*
* Copyright (c) 2001, Paul Clarke.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: COPYRIGHT,v 1.2 2001/10/11 08:29:40 adam Exp $
* $Id: COPYRIGHT,v 1.3 2002/01/15 18:08:43 adam Exp $
*
*/

7
README
View File

@@ -2,12 +2,11 @@ uIP is a very small implementation of the TCP/IP stack that is written
by Adam Dunkels <adam@dunkels.com>. More information can be obtained
at the uIP homepage at <http://dunkels.com/adam/uip/>.
This is version $Name: uip-0-5-0 $.
This is version $Name: uip-0-6 $.
The directory structure look as follows:
apps/ - contains some sample applications
bsd/ - uIP as a user space process under FreeBSD
cc65/ - uIP for the 6502 CPU
h8/ - uIP for the H8S2144 CPU
uip/ - actual uIP code
uip/ - actual uIP TCP/IP and ARP code
unix - uIP as a user space process under FreeBSD or Linux

View File

@@ -31,7 +31,7 @@
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: cgi.c,v 1.14 2001/11/25 18:48:38 adam Exp $
* $Id: cgi.c,v 1.21 2002/01/13 21:12:40 adam Exp $
*
*/
@@ -66,8 +66,11 @@ cgifunction cgitab[] = {
static const char closed[] = /* "CLOSED",*/
{0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0};
static const char syn_rcvd[] = /* "SYN-RCVD",*/
{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49,
0x54, 0x2d, 0x31, 0};
{0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56,
0x44, 0};
static const char syn_sent[] = /* "SYN-SENT",*/
{0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e,
0x54, 0};
static const char established[] = /* "ESTABLISHED",*/
{0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48,
0x45, 0x44, 0};
@@ -90,6 +93,7 @@ static const char last_ack[] = /* "LAST-ACK"*/
static const char *states[] = {
closed,
syn_rcvd,
syn_sent,
established,
fin_wait_1,
fin_wait_2,
@@ -99,20 +103,32 @@ static const char *states[] = {
/*-----------------------------------------------------------------------------------*/
/* print_stats:
*
* Prints out a part of the uIP statistics. The statistics data is
* written into the uip_appdata buffer. It overwrites any incoming
* packet.
*/
static u8_t
print_stats(void)
{
#if UIP_STATISTICS
u16_t i, j;
u8_t *buf;
u16_t *databytes;
if(uip_flags & UIP_ACKDATA) {
if(uip_acked()) {
/* If our last data has been acknowledged, we move on the next
chunk of statistics. */
hs->count = hs->count + 4;
if(hs->count >= sizeof(struct uip_stats)/sizeof(u16_t)) {
/* We have printed out all statistics, so we return 1 to
indicate that we are done. */
return 1;
}
}
/* Write part of the statistics into the uip_appdata buffer. */
databytes = (u16_t *)&uip_stat + hs->count;
buf = (u8_t *)uip_appdata;
@@ -125,52 +141,64 @@ print_stats(void)
++i;
}
uip_len = buf - uip_appdata;
/* Send the data. */
uip_send(uip_appdata, buf - uip_appdata);
return 0;
#else
return 1;
#endif /* UIP_STATISTICS */
}
/*-----------------------------------------------------------------------------------*/
static u8_t
file_stats(void)
{
if(uip_flags & UIP_ACKDATA) {
{
/* We use sprintf() to print the number of file accesses to a
particular file (given as an argument to the function in the
script). We then use uip_send() to actually send the data. */
if(uip_acked()) {
return 1;
}
sprintf((char *)uip_appdata, "%d", fs_count(&hs->script[4]));
uip_len = strlen((char *)uip_appdata);
uip_send(uip_appdata, sprintf((char *)uip_appdata, "%5u", fs_count(&hs->script[4])));
return 0;
}
/*-----------------------------------------------------------------------------------*/
static u8_t
tcp_stats(void)
{
struct uip_conn *conn;
struct uip_conn *conn;
if(uip_flags & UIP_ACKDATA) {
if(uip_acked()) {
/* If the previously sent data has been acknowledged, we move
forward one connection. */
if(++hs->count == UIP_CONNS) {
/* If all connections has been printed out, we are done and
return 1. */
return 1;
}
}
conn = &uip_conns[hs->count];
if((conn->tcpstateflags & TS_MASK) == CLOSED) {
uip_len = sprintf((char *)uip_appdata, "<tr align=\"center\"><td>-</td><td>-</td><td>%d</td><td>%d</td><td>%c</td></tr>\r\n",
conn->nrtx,
conn->timer,
(conn->tcpstateflags & UIP_OUTSTANDING)? '*':' ');
uip_send(uip_appdata, sprintf((char *)uip_appdata,
"<tr align=\"center\"><td>-</td><td>-</td><td>%d</td><td>%d</td><td>%c %c</td></tr>\r\n",
conn->nrtx,
conn->timer,
(conn->tcpstateflags & UIP_OUTSTANDING)? '*':' ',
(conn->tcpstateflags & UIP_STOPPED)? '!':' '));
} else {
uip_len = sprintf((char *)uip_appdata, "<tr align=\"center\"><td>%d.%d.%d.%d:%d</td><td>%s</td><td>%d</td><td>%d</td><td>%c</td></tr>\r\n",
ntohs(conn->ripaddr[0]) >> 8,
ntohs(conn->ripaddr[0]) & 0xff,
ntohs(conn->ripaddr[1]) >> 8,
ntohs(conn->ripaddr[1]) & 0xff,
ntohs(conn->rport),
states[conn->tcpstateflags & TS_MASK],
conn->nrtx,
conn->timer,
(conn->tcpstateflags & UIP_OUTSTANDING)? '*':' ');
uip_send(uip_appdata, sprintf((char *)uip_appdata,
"<tr align=\"center\"><td>%d.%d.%d.%d:%d</td><td>%s</td><td>%d</td><td>%d</td><td>%c %c</td></tr>\r\n",
ntohs(conn->ripaddr[0]) >> 8,
ntohs(conn->ripaddr[0]) & 0xff,
ntohs(conn->ripaddr[1]) >> 8,
ntohs(conn->ripaddr[1]) & 0xff,
ntohs(conn->rport),
states[conn->tcpstateflags & TS_MASK],
conn->nrtx,
conn->timer,
(conn->tcpstateflags & UIP_OUTSTANDING)? '*':' ',
(conn->tcpstateflags & UIP_STOPPED)? '!':' '));
}
return 0;
}

View File

@@ -31,7 +31,7 @@
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: cgi.h,v 1.1 2001/10/19 07:46:01 adam Exp $
* $Id: cgi.h,v 1.3 2002/01/10 19:18:12 adam Exp $
*
*/

View File

@@ -15,5 +15,5 @@
<center>
<table width="80%" cellspacing="10">
<tr><th>Remote</th><th>State</th><th>Retransmissions</th><th>Timer</th><th>Outstanding</th></tr>
<tr><th>Remote</th><th>State</th><th>Retransmissions</th><th>Timer</th><th>Flags</th></tr>

View File

@@ -492,10 +492,9 @@ static const char data_tcp_header_html[] = {
0x3e, 0x52, 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69,
0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x74, 0x68,
0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x54, 0x69, 0x6d, 0x65, 0x72,
0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x4f,
0x75, 0x74, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67,
0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e,
0xa, 0xa, };
0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x46,
0x6c, 0x61, 0x67, 0x73, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c,
0x2f, 0x74, 0x72, 0x3e, 0xa, 0xa, };
static const char data_files_footer_plain[] = {
/* /files_footer.plain */

View File

@@ -31,7 +31,7 @@
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: httpd.c,v 1.19 2001/11/20 20:51:58 adam Exp $
* $Id: httpd.c,v 1.27 2002/01/15 17:22:08 adam Exp $
*
*/
@@ -51,11 +51,14 @@
#define HTTP_FUNC 3
#define HTTP_END 4
#ifdef DEBUG
#include <stdio.h>
#define PRINT(x) printf("%s", x)
#define PRINTLN(x) printf("%s\n", x)
/*#define PRINT(x)
#define PRINTLN(x)*/
#else /* DEBUG */
#define PRINT(x)
#define PRINTLN(x)
#endif /* DEBUG */
struct httpd_state *hs;
@@ -86,7 +89,7 @@ httpd_init(void)
{
fs_init();
/* Set up a web server. */
/* Listen to port 80. */
uip_listen(80);
}
/*-----------------------------------------------------------------------------------*/
@@ -99,17 +102,17 @@ httpd(void)
switch(uip_conn->lport) {
/* This is the web server: */
case htons(80):
uip_len = 0;
/* Pick out the application state from the uip_conn structure. */
hs = (struct httpd_state *)(uip_conn->appstate);
/* We use the uip_flags variable to deduce why we were called. If
uip_flags & UIP_ACCEPT is non-zero, we were called because a
remote host has connected to us. If uip_flags & UIP_NEWDATA is
non-zero, we were called because the remote host has sent us
new data, and if uip_flags & UIP_ACKDATA is non-zero, the
remote host has acknowledged the data we previously sent to
it. */
if(uip_flags & UIP_ACCEPT) {
/* We use the uip_ test functions to deduce why we were
called. If uip_connected() is non-zero, we were called
because a remote host has connected to us. If
uip_newdata() is non-zero, we were called because the
remote host has sent us new data, and if uip_acked() is
non-zero, the remote host has acknowledged the data we
previously sent to it. */
if(uip_connected()) {
/* Since we have just been connected with the remote host, we
reset the state for this connection. The ->count variable
contains the amount of data that is yet to be sent to the
@@ -118,18 +121,20 @@ httpd(void)
connection yet. */
hs->state = HTTP_NOGET;
hs->count = 0;
uip_len = 0;
/* Don't send any data in return; we wait for the HTTP request
instead. */
uip_send(uip_appdata, 0);
return;
} else if(uip_flags & UIP_POLL) {
} else if(uip_poll()) {
/* If we are polled ten times, we abort the connection. This is
because we don't want connections lingering indefinately in
the system. */
if(hs->count++ == 10) {
uip_flags = UIP_ABORT;
if(hs->count++ >= 10) {
uip_abort();
}
return;
} else if(uip_flags & UIP_NEWDATA && hs->state == HTTP_NOGET) {
} else if(uip_newdata() && hs->state == HTTP_NOGET) {
/* This is the first data we receive, and it should contain a
GET. */
@@ -138,7 +143,8 @@ httpd(void)
uip_appdata[1] != ISO_E ||
uip_appdata[2] != ISO_T ||
uip_appdata[3] != ISO_space) {
uip_flags = UIP_ABORT;
/* If it isn't a GET, we abort the connection. */
uip_abort();
return;
}
@@ -188,13 +194,12 @@ httpd(void)
/* Check if the client (remote end) has acknowledged any data that
we've previously sent. If so, we move the file pointer further
into the file and send back more data. If we are out of data to
send, we set the UIP_CLOSE flag in the uip_flags variable to
tell uIP that the connection should be closed. */
if(uip_flags & UIP_ACKDATA) {
send, we close the connection. */
if(uip_acked()) {
if(hs->count >= UIP_TCP_MSS) {
hs->count -= UIP_TCP_MSS;
hs->dataptr += UIP_TCP_MSS;
if(hs->count >= uip_mss()) {
hs->count -= uip_mss();
hs->dataptr += uip_mss();
} else {
hs->count = 0;
}
@@ -204,7 +209,7 @@ httpd(void)
next_scriptline();
next_scriptstate();
} else {
uip_flags = UIP_CLOSE;
uip_close();
}
}
}
@@ -220,30 +225,27 @@ httpd(void)
}
}
if(hs->state != HTTP_FUNC && !(uip_flags & UIP_POLL)) {
/* The uip_len variable should contain the length of the
outbound packet. */
if(hs->count > UIP_TCP_MSS) {
uip_len = UIP_TCP_MSS;
} else {
uip_len = hs->count;
}
/* Set the uip_appdata pointer to point to the data we wish to
send. */
uip_appdata = hs->dataptr;
if(hs->state != HTTP_FUNC && !uip_poll()) {
/* Send a piece of data, but not more than the MSS of the
connection. */
uip_send(hs->dataptr,
hs->count > uip_mss()? uip_mss(): hs->count);
}
/* Finally, return to uIP. Our outgoing packet will soon be on its
way... */
return;
default:
/* Should never happen. */
uip_abort();
break;
}
}
/*-----------------------------------------------------------------------------------*/
/* next_scriptline():
*
* Reads the script until it finds a newline. */
static void
next_scriptline(void)
{
@@ -256,6 +258,10 @@ next_scriptline(void)
++(hs->script);
}
/*-----------------------------------------------------------------------------------*/
/* next_sciptstate:
*
* Reads one line of script and decides what to do next.
*/
static void
next_scriptstate(void)
{
@@ -278,13 +284,13 @@ next_scriptstate(void)
hs->state = HTTP_FUNC;
hs->dataptr = NULL;
hs->count = 0;
uip_flags = 0;
uip_reset_acked();
break;
case ISO_i:
/* Include a file. */
hs->state = HTTP_FILE;
if(!fs_open(&hs->script[2], &fsfile)) {
uip_flags = UIP_ABORT;
uip_abort();
}
hs->dataptr = fsfile.data;
hs->count = fsfile.len;
@@ -297,10 +303,10 @@ next_scriptstate(void)
case ISO_period:
/* End of script. */
hs->state = HTTP_END;
uip_flags = UIP_CLOSE;
uip_close();
break;
default:
uip_flags = UIP_ABORT;
uip_abort();
break;
}
}

View File

@@ -31,7 +31,7 @@
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: httpd.h,v 1.2 2001/10/19 07:46:01 adam Exp $
* $Id: httpd.h,v 1.3 2002/01/15 17:22:08 adam Exp $
*
*/
@@ -55,8 +55,7 @@ struct httpd_state {
/* UIP_APPSTATE_SIZE: The size of the application-specific state
stored in the uip_conn structure. See the file "uipstruct.h" for
more information. */
stored in the uip_conn structure. */
#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state))
#define FS_STATISTICS 1

View File

@@ -1,32 +0,0 @@
This directory includes example code of how to use the uIP TCP/IP
stack. The code is used for testing uIP as a user process under
FreeBSD.
Follow these steps to test uIP under FreeBSD:
1) Compile the code using GNU make (gmake):
> gmake
2) su to root:
> su
(type password for the root account)
3) run the "uip" binary:
# ./uip
4) uIP is now up and running with IP address 192.168.0.2. You can now
test uIP by firing up another window and issue the following
commands:
> ping 192.168.0.2
> telnet 192.168.0.2 http
It it also possible to connect to the small web server using
Netscape and the URL <http://192.168.0.2/>. Be sure to turn off any
proxies first.
Please see the files "uipopt.h" and "main.c" for more information.

View File

@@ -1,243 +0,0 @@
/*
* Copyright (c) 2001, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: tundev.c,v 1.6 2001/11/23 05:59:41 adam Exp $
*/
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/socket.h>
#ifndef linux
#include <net/if_tun.h>
#endif
#include "uip.h"
static int drop = 0;
static int fd;
struct tcpip_hdr {
unsigned char vhl,
tos,
len[2],
id[2],
ipoffset[2],
ttl,
proto;
unsigned short ipchksum;
unsigned long srcipaddr,
destipaddr;
unsigned char srcport[2],
destport[2],
seqno[4],
ackno[4],
tcpoffset,
flags,
wnd[2],
tcpchksum[2],
urgp[2];
unsigned char data[0];
};
/*-----------------------------------------------------------------------------------*/
static unsigned short
chksum(void *data, int len)
{
unsigned short *sdata = data;
unsigned long acc;
unsigned long sum;
for(acc = 0; len > 1; len -= 2) {
acc += *sdata++;
}
/* add up any odd byte */
if(len == 1) {
acc += (unsigned short)(*(unsigned char *)sdata);
}
sum = (acc & 0xffff) + (acc >> 16);
sum += (sum >> 16);
return ~(sum & 0xffff);
}
/*-----------------------------------------------------------------------------------*/
static unsigned short
chksum_pseudo(void *data, int len, unsigned long ipaddr1,
unsigned long ipaddr2,
unsigned char proto,
unsigned short protolen)
{
unsigned long sum;
unsigned short *sdata = data;
for(sum = 0; len > 1; len -= 2) {
sum += *sdata++;
}
/* add up any odd byte */
if(len == 1) {
sum += (unsigned short)(*(unsigned char *)sdata);
}
sum += (ipaddr1 & 0xffff);
sum += ((ipaddr1 >> 16) & 0xffff);
sum += (ipaddr2 & 0xffff);
sum += ((ipaddr2 >> 16) & 0xffff);
sum += (unsigned short)htons((unsigned short)proto);
sum += (unsigned short)htons(protolen);
while(sum >> 16) {
sum = (sum & 0xffff) + (sum >> 16);
}
return ~sum & 0xffff;
}
/*-----------------------------------------------------------------------------------*/
static void
check_checksum(void *data, int len)
{
struct tcpip_hdr *hdr;
unsigned short sum;
hdr = data;
sum = chksum(data, 20);
printf("IP header checksum check 0x%x\n", sum);
sum = chksum_pseudo(&(hdr->srcport[0]), len - 20,
hdr->srcipaddr, hdr->destipaddr,
hdr->proto, len - 20);
printf("TCP checksum check 0x%x len %d protolen %d\n", sum, len,
len - 20);
}
/*-----------------------------------------------------------------------------------*/
void
tundev_init(void)
{
int val;
fd = open("/dev/tun0", O_RDWR);
if(fd == -1) {
perror("tun_dev: tundev_init: open");
exit(1);
}
#ifdef linux
system("ifconfig tun0 inet 192.168.0.2 192.168.0.1");
system("route add -net 192.168.0.0 netmask 255.255.255.0 dev tun0");
#else
system("ifconfig tun0 inet 192.168.0.1 192.168.0.2");
val = 0;
ioctl(fd, TUNSIFHEAD, &val);
#endif /* linux */
}
/*-----------------------------------------------------------------------------------*/
unsigned int
tundev_read(void)
{
fd_set fdset;
struct timeval tv;
int ret;
tv.tv_sec = 0;
tv.tv_usec = 500000;
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
ret = select(fd + 1, &fdset, NULL, NULL, &tv);
if(ret == 0) {
return 0;
}
ret = read(fd, uip_buf, UIP_BUFSIZE);
if(ret == -1) {
perror("tun_dev: tundev_read: read");
}
/*printf("--- tun_dev: tundev_read: read %d bytes\n", ret);*/
/* {
int i;
for(i = 0; i < 20; i++) {
printf("%x ", uip_buf[i]);
}
printf("\n");
}*/
/* check_checksum(uip_buf, ret);*/
return ret;
}
/*-----------------------------------------------------------------------------------*/
void
tundev_send(void)
{
int ret;
int i;
char tmpbuf[UIP_BUFSIZE];
/* printf("tundev_send: sending %d bytes\n", uip_len);*/
/* check_checksum(uip_buf, size);*/
/* drop++;
if(drop % 8 == 7) {
printf("Dropped a packet!\n");
return;
}*/
/* {
int i;
for(i = 0; i < 20; i++) {
printf("%x ", uip_buf[i]);
}
printf("\n");
}*/
for(i = 0; i < 40; i++) {
tmpbuf[i] = uip_buf[i];
}
for(i = 40; i < uip_len; i++) {
tmpbuf[i] = uip_appdata[i - 40];
}
ret = write(fd, tmpbuf, uip_len);
if(ret == -1) {
perror("tun_dev: tundev_done: write");
exit(1);
}
}
/*-----------------------------------------------------------------------------------*/

View File

@@ -1,112 +0,0 @@
/*
* Copyright (c) 2001, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Adam Dunkels.
* 4. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uipopt.h,v 1.14 2001/11/24 15:30:08 adam Exp $
*
*/
#ifndef __UIPOPT_H__
#define __UIPOPT_H__
/* This file is used for tweaking various configuration options for
uIP. You should make a copy of this file into one of your project's
directories instead of editing this example "uipopt.h" file that
comes with the uIP distribution. */
/* The following typedefs may have to be tweaked for your particular
compiler. The uX_t types are unsigned integer types, where the X is
the number of bits in the integer type. */
typedef unsigned char u8_t;
typedef unsigned short u16_t;
/* This is where you configure if your CPU architecture is big or
little endian. Most CPUs today are little endian. The most notable
exception are the Motorolas which are big endian. Tweak the
definition of the BYTE_ORDER macro to configure uIP for your
project. */
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 3412
#endif /* LITTLE_ENDIAN */
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 1234
#endif /* BIGE_ENDIAN */
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif /* BYTE_ORDER */
/* Include the header file for the application program that should be
used. */
#include "httpd.h"
/* UIP_CONNS: The maximum number of simultaneously active
connections. */
#define UIP_CONNS 10
/* UIP_LISTENPORTS: The maximum number of simultaneously listening TCP
ports. */
#define UIP_LISTENPORTS 1
/* UIP_BUFSIZE: The size of the buffer that holds incoming and
outgoing packets. In this version of uIP, this can be more than
255 bytes. */
#define UIP_BUFSIZE 200
/* UIP_IPADDR: The IP address of this uIP node. */
#define UIP_IPADDR0 192
#define UIP_IPADDR1 168
#define UIP_IPADDR2 0
#define UIP_IPADDR3 2
/* UIP_LLH_LEN: The link level header length; this is the offset into
the uip_buf where the IP header can be found. For Ethernet, this
should be set to 14. */
#define UIP_LLH_LEN 0
/* UIP_TCP_MSS: The TCP maximum segment size. This should be set to
at most UIP_BUFSIZE - UIP_LLH_LEN - 40. */
#define UIP_TCP_MSS UIP_BUFSIZE - UIP_LLH_LEN - 40
/* UIP_TTL: The IP TTL (time to live) of IP packets sent by uIP. */
#define UIP_TTL 128
/* UIP_RTO: The retransmission timeout counted in timer pulses (i.e.,
the speed of the periodic timer). */
#define UIP_RTO 3
#define UIP_STATISTICS 1
#define UIP_LOGGING 0
#define UIP_TIME_WAIT_TIMEOUT 120
#endif /* __UIPOPT_H__ */

View File

@@ -31,7 +31,7 @@
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uipopt.h,v 1.3 2001/11/25 18:47:36 adam Exp $
* $Id: uipopt.h,v 1.6 2002/01/11 12:43:14 adam Exp $
*
*/
@@ -40,20 +40,141 @@
/* This file is used for tweaking various configuration options for
uIP. You should make a copy of this file into one of your project's
directories instead of editing the example "uipopt.h" file that
come with the uIP distribution. */
directories instead of editing this example "uipopt.h" file that
comes with the uIP distribution. */
/* The following typedefs may have to be tweaked for your particular
/*-----------------------------------------------------------------------------------*/
/* First, two typedefs that may have to be tweaked for your particular
compiler. The uX_t types are unsigned integer types, where the X is
the number of bits in the integer type. */
the number of bits in the integer type. Most compilers use
"unsigned char" and "unsigned short" for those two,
respectively. */
typedef unsigned char u8_t;
typedef unsigned short u16_t;
/*-----------------------------------------------------------------------------------*/
/* The configuration options for a specific node. This includes IP
* address, netmask and default router as well as the Ethernet
* address. The netmask, default router and Ethernet address are
* appliciable only if uIP should be run over Ethernet.
*
* All of these should be changed to suit your project.
*/
/* UIP_IPADDR: The IP address of this uIP node. */
#define UIP_IPADDR0 192
#define UIP_IPADDR1 168
#define UIP_IPADDR2 0
#define UIP_IPADDR3 2
/* UIP_NETMASK: The netmask. */
#define UIP_NETMASK0 255
#define UIP_NETMASK1 255
#define UIP_NETMASK2 255
#define UIP_NETMASK3 0
/* UIP_DRIPADDR: IP address of the default router. */
#define UIP_DRIPADDR0 192
#define UIP_DRIPADDR1 168
#define UIP_DRIPADDR2 0
#define UIP_DRIPADDR3 1
/* UIP_ETHADDR: The Ethernet address. */
#define UIP_ETHADDR0 0x00
#define UIP_ETHADDR1 0xbd
#define UIP_ETHADDR2 0x3b
#define UIP_ETHADDR3 0x33
#define UIP_ETHADDR4 0x05
#define UIP_ETHADDR5 0x71
/*-----------------------------------------------------------------------------------*/
/* The following options are used to configure application specific
* setting such as how many TCP ports that should be avaliable and if
* the uIP should be configured to support active opens.
*
* These should probably be tweaked to suite your project.
*/
/* Include the header file for the application program that should be
used. If you don't use the example web server, you should change
this. */
#include "httpd.h"
/* UIP_CONNS: The maximum number of simultaneously active
connections. */
#define UIP_CONNS 10
/* UIP_LISTENPORTS: The maximum number of simultaneously listening TCP
ports. */
#define UIP_LISTENPORTS 1
/* UIP_ACTIVE_OPEN: Determines if support for opening connections from
uIP should be compiled in. If this isn't needed for your
application, don't turn it on. (A web server doesn't need this, for
instance.) */
#define UIP_ACTIVE_OPEN 0
/* UIP_BUFSIZE: The size of the buffer that holds incoming and
outgoing packets. */
#define UIP_BUFSIZE 160
/* UIP_STATISTICS: Determines if statistics support should be compiled
in. The statistics is useful for debugging and to show the user. */
#define UIP_STATISTICS 1
/* UIP_LOGGING: Determines if logging of certain events should be
compiled in. Useful mostly for debugging. The function uip_log(char
*msg) must be implemented to suit your architecture if logging is
turned on. */
#define UIP_LOGGING 0
/* UIP_LLH_LEN: The link level header length; this is the offset into
the uip_buf where the IP header can be found. For Ethernet, this
should be set to 14. For SLIP, this should be set to 0. */
#define UIP_LLH_LEN 0
/*-----------------------------------------------------------------------------------*/
/* The following configuration options can be tweaked for your
* project, but you are probably safe to use the default values. The
* options are listed in order of importance.
*/
/* UIP_MAXRTX: The maximum number of times a segment should be
retransmitted before the connection should be aborted. */
#define UIP_MAXRTX 8
/* UIP_ARPTAB_SIZE: The size of the ARP table - use a larger value if
this uIP node will have many connections from the local network. */
#define UIP_ARPTAB_SIZE 8
/* The maxium age of ARP table entries measured in 10ths of
seconds. An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
default). */
#define UIP_ARP_MAXAGE 120
/* UIP_RTO: The retransmission timeout counted in timer pulses (i.e.,
the speed of the periodic timer, usually one second). */
#define UIP_RTO 3
/* UIP_TCP_MSS: The TCP maximum segment size. This should be set to
at most UIP_BUFSIZE - UIP_LLH_LEN - 40. */
#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - 40)
/* UIP_TTL: The IP TTL (time to live) of IP packets sent by uIP. */
#define UIP_TTL 255
/* UIP_TIME_WAIT_TIMEOUT: How long a connection should stay in the
TIME_WAIT state. Has no real implication, so it should be left
untouched. */
#define UIP_TIME_WAIT_TIMEOUT 120
/*-----------------------------------------------------------------------------------*/
/* This is where you configure if your CPU architecture is big or
little endian. Most CPUs today are little endian. The most notable
exception are the Motorolas which are big endian. Tweak the
definition of the BYTE_ORDER macro to configure uIP for your
project. */
* little endian. Most CPUs today are little endian. The most notable
* exception are the Motorolas which are big endian. Tweak the
* definition of the BYTE_ORDER macro to configure uIP for your
* project.
*/
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 3412
#endif /* LITTLE_ENDIAN */
@@ -65,48 +186,4 @@ typedef unsigned short u16_t;
#define BYTE_ORDER LITTLE_ENDIAN
#endif /* BYTE_ORDER */
/* This is the header of the application program that should be
used. */
#include "httpd.h"
/* UIP_CONNS: The maximum number of simultaneously active
connections. */
#define UIP_CONNS 10
/* UIP_LISTENPORTS: The maximum number of simultaneously listening TCP
ports. */
#define UIP_LISTENPORTS 1
/* UIP_BUFSIZE: The size of the buffer that holds incoming and
outgoing packets. In this version of uIP, this can be more than
255 bytes. */
#define UIP_BUFSIZE 240
/* UIP_IPADDR: The IP address of this uIP node. */
#define UIP_IPADDR0 192
#define UIP_IPADDR1 168
#define UIP_IPADDR2 0
#define UIP_IPADDR3 2
/* UIP_LLH_LEN: The link level header length; this is the offset into
the uip_buf where the IP header can be found. For Ethernet, this
should be set to 14. */
#define UIP_LLH_LEN 0
/* UIP_TCP_MSS: The TCP maximum segment size. This should be set to
at most UIP_BUFSIZE - 40. */
#define UIP_TCP_MSS UIP_BUFSIZE - 40
/* UIP_TTL: The IP TTL (time to live) of IP packets sent by uIP. */
#define UIP_TTL 128
/* UIP_RTO: The retransmission timeout counted in timer pulses (i.e.,
the speed of the periodic timer). */
#define UIP_RTO 3
#define UIP_STATISTICS 1
#define UIP_LOGGING 0
#define UIP_TIME_WAIT_TIMEOUT 120
#endif /* __UIPOPT_H__ */

View File

@@ -1,95 +0,0 @@
# Copyright (c) 2001, Adam Dunkels.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by Adam Dunkels.
# 4. The name of the author may not be used to endorse or promote
# products derived from this software without specific prior
# written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# This file is part of the uIP TCP/IP stack.
#
# $Id: Makefile,v 1.3 2001/10/25 18:55:57 adam Exp $
#
ARCH=s
CC=h8300-hms-gcc
AS=h8300-hms-as
AR=h8300-hms-ar
ARFLAGS=a
CFLAGS=-g -m$(ARCH) -O0 -fsigned-char -malign-300 -fno-common -fshort-enums -I- -I../uip -I../apps/httpd -I. -fomit-frame-pointer -Wall
ASFLAGS=-ahld=$*.lst,-L
LD=$(CC)
LD_FLAGS=-m$(ARCH) -nostartfiles
## Define STDC_LIBS when using stdc library functions
##
#STDC_LIBS=-lm -lc
SRCS = main.c rs232dev.c uip_arch.c ../uip/uip.c \
../apps/httpd/httpd.c ../apps/httpd/fs.c ../apps/httpd/cgi.c
###########################################################################
# Rules to make object files from source
%.o: %.s
$(CC) -c -dA -Wa,$(ASFLAGS) -o $@ $<
%.o: %.c
$(CC) -c $(CFLAGS) -o $@ $<
%.lst: %.c
$(CC) -c $(CFLAGS) -dA -Wa,$(ASFLAGS) $<
uip.a37: uip.o uip_arch.o rs232dev.o main.o httpd.o fs.o crt0.o vectors.o cgi.o
$(LD) $(LD_FLAGS) -Wl,-Tuip.xcl,-Map,uip.map -o $@ $(STDC_LIBS) $^
crt0.o: crt0.s
vectors.o: vectors.c
rs232dev.o: rs232dev.c ../uip/uip.h uipopt.h
main.o: main.c ../uip/uip.h uipopt.h rs232dev.h
uip.o: ../uip/uip.c uipopt.h
$(CC) -c $(CFLAGS) -o $@ $<
httpd.o: ../apps/httpd/httpd.c ../apps/httpd/httpd.h ../uip/uip.h uipopt.h \
../apps/httpd/fs.c ../apps/httpd/fs.h \
../apps/httpd/fsdata.c ../apps/httpd/fsdata.h
$(CC) -c $(CFLAGS) -o $@ $<
fs.o: ../apps/httpd/fs.c ../apps/httpd/fs.h
$(CC) -c $(CFLAGS) -o $@ $<
uip_arch.o: uip_arch.c uip_arch.h ../uip/uip.h uipopt.h ../apps/httpd/httpd.h
$(CC) -c $(CFLAGS) -o $@ $<
cgi.o: ../apps/httpd/cgi.c ../apps/httpd/cgi.h
$(CC) -c $(CFLAGS) -o $@ $<
clean:
rm -f *.o *~ *core uip *.s

View File

@@ -1,16 +0,0 @@
This directory is a port of uIP to the Hitachi H8S2144 microprocessor.
In order to compile it, you need gcc-2.95+ (or later version) C compiler
for h8300-hms.
This can be downloaded from
http://sourceforge.net/project/showfiles.php?group_id=24580&release_id=34503
Tested on H8S2144 using sci1 at 9600 baud using linux slip setup.
slattach -p slip /dev/modem -s 9600 -d -L -l &
sleep 3s
ifconfig sl0 192.168.0.1 pointopoint 192.168.0.2 mtu 255 netmask 255.255.255.0 up
sleep 3s
route add 192.168.0.2 mss 195 window 195 dev sl0

View File

@@ -1,96 +0,0 @@
;//
;// Copyright (c) 2001, Paul Clarke, Hydra Electronic Design Solutions Pty. Ltd.
;; // http://www.hydraelectronics.com.au
;// All rights reserved.
;//
;// Redistribution and use in source and binary forms, with or without
;// modification, are permitted provided that the following conditions
;// are met:
;// 1. Redistributions of source code must retain the above copyright
;// notice, this list of conditions and the following disclaimer.
;// 2. Redistributions in binary form must reproduce the above copyright
;// notice, this list of conditions and the following disclaimer in the
;// documentation and/or other materials provided with the distribution.
;// 3. The name of the author may not be used to endorse or promote
;// products derived from this software without specific prior
;// written permission.
;//
;// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
;// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
;// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
;// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
;// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
;// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
;// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
;// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
;// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
;// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
;// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;//
;// This file is part of the uIP TCP/IP stack.
;//
;// $Id: crt0.s,v 1.2 2001/10/25 18:55:57 adam Exp $
;//
;//
;// C startup routine for embedded H8 code.
;//
;//
.h8300s
.section .text
.global _start
_h8_mdcr = H'FFFFC5
_h8_p1ddr = H'FFFFB0
_h8_p2ddr = H'FFFFB1
_h8_paddr = H'FFFFAB
_h8_wscr = H'FFFFC7
_start:
mov.l #_stack,sp
;
; Set wait states and external addr width
;
bset #7,@_h8_mdcr:8 // Enable external ram
mov.b #255,r1l //
mov.b r1l,@_h8_p1ddr:8 //
mov.b r1l,@_h8_p2ddr:8 //
mov.b r1l,@_h8_paddr:8 //
mov.b #0x19, r1l ; [0x13,0x12,0x11,0x10,0x03] slow..fast width 16
; [0x33,0x32,0x31,0x30,0x23] slow..fast width 8
; 0x19 = 3 state access Pin Wait mode 1 waitstate
; additional waitstates added if wait remains low.
mov.b r1l, @_h8_wscr:8
;
; Clear bss section
;
mov.l #_bss,er0
mov.l #_ebss,er1
mov.w #0,r2
.bssloop:
mov.w r2,@er0
adds #2,er0
cmp.l er1,er0
blo .bssloop
; Copy ROMed data section to ram.
mov.l #_ldata,er0
mov.l #_data,er1
.dataloop:
mov.w @er0,r2
mov.w r2,@er1
adds #2,er0
adds #2,er1
cmp.l #_edata,er1
blo .dataloop
jsr @_main
_exit:
jmp @_exit

View File

@@ -1,145 +0,0 @@
/*
* Copyright (c) 2001, Paul Clarke, Hydra Electronic Design Solutions Pty Ltd.
* http://www.hydraelectronics.com.au
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: hd2144.h,v 1.2 2001/10/25 18:55:57 adam Exp $
*
*/
typedef volatile unsigned char io_reg;
typedef volatile unsigned short io_dreg;
#define h8_kbcomp (*(io_reg*) 0xfffee4)
#define h8_sbycr (*(io_reg*) 0xffff84)
#define h8_lpwrcr (*(io_reg*) 0xffff85)
#define h8_mstpcr (*(io_dreg*) 0xffff86)
#define h8_sci_smr1 (*(io_reg*) 0xffff88)
#define h8_sci_brr1 (*(io_reg*) 0xffff89)
#define h8_sci_scr1 (*(io_reg*) 0xffff8a)
#define h8_sci_tdr1 (*(io_reg*) 0xffff8b)
#define h8_sci_ssr1 (*(io_reg*) 0xffff8c)
#define h8_sci_rdr1 (*(io_reg*) 0xffff8d)
#define h8_sci_scmr1 (*(io_reg*) 0xffff8e)
#define h8_frt_tier (*(io_reg*) 0xffff90)
#define h8_frt_tcsr (*(io_reg*) 0xffff91)
#define h8_frt_tcr (*(io_reg*) 0xffff96)
#define h8_frt_tocr (*(io_reg*) 0xffff97)
#define h8_frt_ocrar (*(io_reg*) 0xffff98)
#define h8_frt_ocraf (*(io_reg*) 0xffff9a)
#define h8_wdt_tcnt0_w (*(io_dreg*) 0xffffa8)
#define h8_wdt_tcsr0_w (*(io_dreg*) 0xffffa8)
#define h8_stcr (*(io_reg*) 0xffffc3)
// mstpcr Module peripheral control register
#define _PWR_FRT ( 0x2000 )
#define _PWR_TMR01 ( 0x1000 )
#define _PWR_TMRXY ( 0x0100 )
#define _PWR_SCI1 ( 0x0040 )
// frt_tier timer interrupt enable register
#define _ICIAE 0x80
#define _ICIBE 0x40
#define _ICICE 0x20
#define _ICIDE 0x10
#define _OCIAE 0x08
#define _OCIBE 0x04
#define _FOVIE 0x02
// frt_tcr free running timer control register
#define _IEDGA 0x80
#define _IEDGB 0x40
#define _IEDGC 0x20
#define _IEDGD 0x10
#define _BUFEA 0x08
#define _BUFEB 0x04
#define _CKS1 0x02
#define _CKS0 0x01
// frt_tocr timer output control register
#define _ICRDMS 0x80
#define _OCRAMS 0x40
#define _ICRS 0x20
#define _OCRS 0x10
#define _OEA 0x08
#define _OEB 0x04
#define _OLVLA 0x02
#define _OLVLB 0x01
#define XTAL_HZ (18432000L)
#define FRT_CLK_DIV (32)
// scr serial control register
#define _TIE 0x80
#define _RIE 0x40
#define _TE 0x20
#define _RE 0x10
#define _MPIE 0x08
#define _TEIE 0x04
#define _CKE1 0x02
#define _CKE0 0x01
// smr serial mode register
#define _CA 0x80
#define _CHR 0x40
#define _PE 0x20
#define _OE 0x10
#define _STOP 0x08
#define _MP 0x04
// ssr serial status register
#define _TDRE 0x80
#define _RDRF 0x40
#define _ORER 0x20
#define _FER 0x10
#define _PER 0x08
#define _TEND 0x04
#define _MPB 0x02
#define _MPBT 0x01
// stcr Serial timer control register
#define _IICS 0x80
#define _IICX1 0x40
#define _IICX0 0x20
#define _IICE 0x10
#define _FLSHE 0x08
#define _ICKS1 0x02
#define _ICKS0 0x01
#define BAUD(baud) (((XTAL_HZ/32)/baud)-1)
static inline void h8_AccessSci(void)
{
h8_stcr &= ~_IICE;
}
static inline void h8_EnableInterrupts(void)
{
__asm__ volatile ("andc.b #0x3F,ccr": : :"cc"); // clear I & UI bits
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright (c) 2001, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Adam Dunkels.
* 4. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: main.c,v 1.2 2001/10/25 18:55:57 adam Exp $
*
*/
#include "uip.h"
#include "uipopt.h"
#include "rs232dev.h"
#include "httpd.h"
/*-----------------------------------------------------------------------------------*/
void
main(void)
{
u8_t i;
rs232dev_init();
uip_init();
httpd_init();
while(1) {
uip_len = rs232dev_read();
if(uip_len == 0) {
for(i = 0; i < UIP_CONNS; i++) {
uip_periodic(i);
if(uip_len > 0)
rs232dev_send();
}
} else {
uip_process(UIP_DATA);
if(uip_len > 0)
rs232dev_send();
}
}
}
/*-----------------------------------------------------------------------------------*/

View File

@@ -1,553 +0,0 @@
/*
* Copyright (c) 2001, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Adam Dunkels.
* 4. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: rs232dev.c,v 1.2 2001/10/25 18:55:57 adam Exp $
*
*/
#include "uip.h"
#include "hd2144.h"
#define SLIP_END 0300
#define SLIP_ESC 0333
#define SLIP_ESC_END 0334
#define SLIP_ESC_ESC 0335
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Baudrate settings */
#define RS_BAUD_50 0x00
#define RS_BAUD_110 0x01
#define RS_BAUD_134_5 0x02
#define RS_BAUD_300 0x03
#define RS_BAUD_600 0x04
#define RS_BAUD_1200 0x05
#define RS_BAUD_2400 0x06
#define RS_BAUD_4800 0x07
#define RS_BAUD_9600 0x08
#define RS_BAUD_19200 0x09
#define RS_BAUD_38400 0x0A
#define RS_BAUD_57600 0x0B
#define RS_BAUD_115200 0x0C
#define RS_BAUD_230400 0x0D
/* Stop bit settings */
#define RS_STOP_1 0x00
#define RS_STOP_2 0x80
/* Data bit settings */
#define RS_BITS_5 0x60
#define RS_BITS_6 0x40
#define RS_BITS_7 0x20
#define RS_BITS_8 0x00
/* Parity settings */
#define RS_PAR_NONE 0x00
#define RS_PAR_ODD 0x20
#define RS_PAR_EVEN 0x60
#define RS_PAR_MARK 0xA0
#define RS_PAR_SPACE 0xE0
/* Bit masks to mask out things from the status returned by rs232_status */
#define RS_STATUS_PE 0x01 /* Parity error */
#define RS_STATUS_FE 0x02 /* Framing error */
#define RS_STATUS_OVERRUN 0x04 /* Overrun error */
#define RS_STATUS_RDRF 0x08 /* Receiver data register full */
#define RS_STATUS_THRE 0x10 /* Transmit holding reg. empty */
#define RS_STATUS_DCD 0x20 /* NOT data carrier detect */
#define RS_STATUS_DSR 0x40 /* NOT data set ready */
#define RS_STATUS_IRQ 0x80 /* IRQ condition */
/* Error codes returned by all functions */
#define RS_ERR_OK 0x00 /* Not an error - relax */
#define RS_ERR_NOT_INITIALIZED 0x01 /* Module not initialized */
#define RS_ERR_BAUD_TOO_FAST 0x02 /* Cannot handle baud rate */
#define RS_ERR_BAUD_NOT_AVAIL 0x03 /* Baud rate not available */
#define RS_ERR_NO_DATA 0x04 /* Nothing to read */
#define RS_ERR_OVERFLOW 0x05 /* No room in send buffer */
static volatile u8_t timer, tmptimer, timershot;
static u16_t len;
#define SIO_RECV(c) while(rs232_get(&c) == RS_ERR_NO_DATA)
#define SIO_RECVT(c) do { \
tmptimer = timer; \
timershot = 0; \
while(rs232_get(&c) == RS_ERR_NO_DATA) { \
if(timer != tmptimer) { \
timershot = 1; \
break; \
} \
} \
} while(0)
#define SIO_SEND(c) while(rs232_put(c) == RS_ERR_OVERFLOW)
#define MAX_SIZE UIP_BUFSIZE
static const unsigned char slip_end = SLIP_END,
slip_esc = SLIP_ESC,
slip_esc_end = SLIP_ESC_END,
slip_esc_esc = SLIP_ESC_ESC;
static u8_t dropcount;
#define printf(x)
typedef struct {
volatile unsigned char *put_ptr;
volatile unsigned char *get_ptr;
unsigned char *data;
} serBuffer;
serBuffer TxBuffer, RxBuffer;
unsigned char TxB[MAX_SIZE];
unsigned char RxB[MAX_SIZE];
void serBufferInit(serBuffer *buffer, unsigned char *data)
{
buffer->data=data;
buffer->put_ptr = data;
buffer->get_ptr = data;
}
unsigned char BufferAdd( serBuffer *buffer, unsigned char data)
{
if ( (buffer->get_ptr == buffer->data)
&& ((buffer->put_ptr == buffer->data+MAX_SIZE-1)
|| ( buffer->put_ptr == buffer->get_ptr -1)))
{
return 0;
}
*buffer->put_ptr = data;
buffer->put_ptr++;
if ( buffer->put_ptr >= buffer->data + MAX_SIZE)
{
buffer->put_ptr = buffer->data;
}
return 1;
}
unsigned BufferRemove( serBuffer *buffer, unsigned char *data)
{
if ( buffer->put_ptr == buffer->get_ptr)
{
return 0;
}
*data = *buffer->get_ptr;
buffer->get_ptr++;
if ( buffer->get_ptr >= buffer->data + MAX_SIZE)
{
buffer->get_ptr = buffer->data;
}
return 1;
}
/*-----------------------------------------------------------------------------------*/
unsigned char rs232_init( char hacked)
{
/* Initialize the serial port, install the interrupt handler. The parameter
* must be true (non zero) for a hacked swiftlink and false (zero) otherwise.
*/
serBufferInit( &TxBuffer, TxB);
serBufferInit( &RxBuffer, RxB);
return RS_ERR_OK;
}
unsigned char rs232_done (void)
{
/* Close the port, deinstall the interrupt hander. You MUST call this function
* before terminating the program, otherwise the machine may crash later. If
* in doubt, install an exit handler using atexit(). The function will do
* nothing, if it was already called.
*/
serBufferInit( &TxBuffer, TxB);
serBufferInit( &RxBuffer, RxB);
return RS_ERR_OK;
}
unsigned char rs232_get (char* b)
{
/* Get a character from the serial port. If no characters are available, the
* function will return RS_ERR_NO_DATA, so this is not a fatal error.
*/
if ( BufferRemove( &RxBuffer, b) == 0 )
{
h8_sci_scr1 |= _RIE ; // enable receive interrupt.
return RS_ERR_NO_DATA;
}
return RS_ERR_OK;
}
unsigned char rs232_put (char b)
{
/* Send a character via the serial port. There is a transmit buffer, but
* transmitting is not done via interrupt. The function returns
* RS_ERR_OVERFLOW if there is no space left in the transmit buffer.
*/
if ( BufferAdd( &TxBuffer, (unsigned char) b) == 0)
{
return RS_ERR_OVERFLOW;
}
h8_sci_scr1 |= _TIE ; // enable TIE interrupt.
return RS_ERR_OK;
}
unsigned char rs232_pause (void)
{
/* Assert flow control and disable interrupts. */
return RS_ERR_OK;
}
unsigned char rs232_unpause (void)
{
/* Re-enable interrupts and release flow control */
return RS_ERR_OK;
}
unsigned char rs232_status (unsigned char* status, unsigned char* errors)
{
/* Return the serial port status. */
*status = h8_sci_ssr1;
*errors = h8_sci_scr1;
return RS_ERR_OK;
}
unsigned char rs232_params (unsigned char params, unsigned char parity)
{
unsigned char scr_saved;
h8_AccessSci();
scr_saved = h8_sci_scr1;
h8_sci_scr1 = 0;
h8_sci_scmr1 = 0xf2;
/* Set the port parameters. Use a combination of the #defined values above. */
if (params & RS_STOP_2)
{
h8_sci_smr1 |= _STOP;
} else
{
h8_sci_smr1 &= ~_STOP;
}
switch (params & 0x60)
{
case RS_BITS_5:
break;
case RS_BITS_6:
break;
case RS_BITS_7:
h8_sci_smr1 |= _CHR;
break;
case RS_BITS_8:
default:
h8_sci_smr1 &= ~_CHR;
break;
}
switch (params & 0x0f)
{
case RS_BAUD_50:
h8_sci_brr1 = BAUD(50);
break;
case RS_BAUD_110:
h8_sci_brr1 = BAUD(110);
break;
case RS_BAUD_134_5:
h8_sci_brr1 = BAUD(135);
break;
case RS_BAUD_300:
h8_sci_brr1 = BAUD(300);
break;
case RS_BAUD_600:
h8_sci_brr1 = BAUD(600);
break;
case RS_BAUD_1200:
h8_sci_brr1 = BAUD(1200);
break;
case RS_BAUD_2400:
h8_sci_brr1 = BAUD(2400);
break;
case RS_BAUD_4800:
h8_sci_brr1 = BAUD(4800);
break;
case RS_BAUD_9600:
h8_sci_brr1 = BAUD(9600);
break;
case RS_BAUD_19200:
h8_sci_brr1 = BAUD(9600);
break;
case RS_BAUD_38400:
h8_sci_brr1 = BAUD(38400);
break;
case RS_BAUD_57600:
h8_sci_brr1 = BAUD(57600L);
break;
case RS_BAUD_115200:
h8_sci_brr1 = BAUD(115200L);
break;
case RS_BAUD_230400:
h8_sci_brr1 = BAUD(230400L);
break;
}
switch (parity & 0xE0)
{
case RS_PAR_NONE:
break;
case RS_PAR_ODD:
h8_sci_smr1 |= _PE| _OE;
break;
case RS_PAR_EVEN:
h8_sci_smr1 &= ~( _PE| _OE);
break;
case RS_PAR_MARK:
h8_sci_smr1 &= ~( _PE| _OE);
break;
case RS_PAR_SPACE:
break;
default:
break;
}
tmptimer = timer ;
while (tmptimer == timer)
{
/* wait 1 bit period */
}
h8_sci_scr1 = scr_saved | _TE | _RE;
return RS_ERR_OK;
}
static void
rs232_err(char err)
{
switch(err) {
case RS_ERR_OK:
printf("RS232 OK\r");
break;
case RS_ERR_NOT_INITIALIZED:
printf("RS232 not initialized\r");
break;
case RS_ERR_BAUD_TOO_FAST:
printf("RS232 baud too fast\r");
break;
case RS_ERR_BAUD_NOT_AVAIL:
printf("RS232 baud rate not available\r");
break;
case RS_ERR_NO_DATA:
printf("RS232 nothing to read\r");
break;
case RS_ERR_OVERFLOW:
printf("RS232 overflow\r");
break;
}
}
/*-----------------------------------------------------------------------------------*/
void
rs232dev_send(void)
{
#if MAX_SIZE > 255
u16_t i;
#else
u8_t i;
#endif /* MAX_SIZE > 255 */
static unsigned long address;
u8_t *ptr;
u8_t c;
/* if(dropcount++ == 4) {
dropcount = 0;
printf("drop\r");
return;
}*/
SIO_SEND(slip_end);
ptr = uip_buf;
for(i = 0; i < uip_len; i++) {
if(i == 40) {
ptr = uip_appdata;
address = (unsigned long) uip_appdata;
}
c = *ptr++;
switch(c) {
case SLIP_END:
SIO_SEND(slip_esc);
SIO_SEND(slip_esc_end);
break;
case SLIP_ESC:
SIO_SEND(slip_esc);
SIO_SEND(slip_esc_esc);
break;
default:
SIO_SEND(c);
break;
}
}
SIO_SEND(slip_end);
printf("tx\r");
}
/*-----------------------------------------------------------------------------------*/
u8_t
rs232dev_read(void)
{
u8_t c;
u16_t tmplen;
start:
while(1) {
if(len >= MAX_SIZE) {
len = 0;
goto start;
}
SIO_RECVT(c);
if(timershot == 1) {
return 0;
}
switch(c) {
case SLIP_END:
if(len > 0) {
tmplen = len;
len = 0;
return tmplen;
} else {
goto start;
}
break;
case SLIP_ESC:
SIO_RECV(c);
switch(c) {
case SLIP_ESC_END:
c = SLIP_END;
break;
case SLIP_ESC_ESC:
c = SLIP_ESC;
break;
}
/* FALLTHROUGH */
default:
if(len < MAX_SIZE) {
uip_buf[len] = c;
len++;
}
break;
}
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
void sci1_rxi_irq () __attribute__ ((interrupt_handler));
void sci1_rxi_irq (void)
{
(void) BufferAdd( &RxBuffer, h8_sci_rdr1) ; // add char to rx buffer
h8_sci_ssr1 &= ~(_RDRF| _ORER| _FER| _PER); // write 0's
}
void sci1_eri_irq () __attribute__ ((interrupt_handler));
void sci1_eri_irq (void)
{
unsigned char ssr;
ssr = h8_sci_ssr1;
h8_sci_ssr1 &= ~ (_ORER | _PER | _FER);
}
void sci1_tdre_irq () __attribute__ ((interrupt_handler));
void sci1_tdre_irq (void)
{
if ( BufferRemove( &TxBuffer, &h8_sci_tdr1) == 0)
{
h8_sci_scr1 &= ~_TIE; // disable transmit interrrupt
} else
{
h8_sci_ssr1 &= ~_TDRE;
}
}
void sci1_tc_irq () __attribute__ ((interrupt_handler));
void sci1_tc_irq (void)
{
h8_sci_scr1 &= ~_TEIE ; // disable TEIE interrupt.
}
void frt_fovi_irq (void) __attribute__ ((interrupt_handler));
void frt_fovi_irq (void)
{
static u8_t fix_period = 0;
if ( ++fix_period & 0x01) /* Adjust timer update rate to approx 5 Hz. */
{
timer++;
}
h8_frt_tcsr &= ~_FOVIE; // clear ovf interrupt
}
/*-----------------------------------------------------------------------------------*/
void
rs232dev_init(void)
{
char err;
err = rs232_init(0);
rs232_err(err);
timer = 0;
h8_mstpcr = 0; // enable all h8 peripherals !
h8_frt_tcr = _CKS1 | !_CKS0; // %32
h8_frt_tier = _FOVIE; // enable overflow interrupt!
h8_EnableInterrupts(); // enable interrupts
err = rs232_params(RS_BAUD_9600, RS_PAR_NONE);
rs232_err(err);
len = 0;
}
/*-----------------------------------------------------------------------------------*/

View File

@@ -1,47 +0,0 @@
/*
* Copyright (c) 2001, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Adam Dunkels.
* 4. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: rs232dev.h,v 1.2 2001/10/25 18:55:57 adam Exp $
*
*/
#ifndef __RS232DEV_H__
#define __RS232DEV_H__
#include "uip.h"
void rs232dev_init(void);
u8_t rs232dev_read(void);
void rs232dev_send(void);
#endif /* __RS232DEV_H__ */

View File

@@ -1,177 +0,0 @@
/*
* Linker Command script for H8S
*/
ENTRY(_start)
OUTPUT_FORMAT(srec)
OUTPUT_ARCH(h8300s)
SEARCH_DIR(/usr/local/h8300-hms/lib/h8300s)
MEMORY
{
vectors : ORIGIN = 0x000000, LENGTH = 0x0200
introm : ORIGIN = 0x000200, LENGTH = 128K - 0x0200
intram1 : ORIGIN = 0xFFE080, LENGTH = 0x0F80
}
/* .vectors system interrupt vector storage RO */
/* .text data/program area RO */
/* _ldata location of initialising data RO */
/* _data initialised variable data RW */
/* .bss uninitialised variables cleared by CRT0.S RW */
/* _stack initial stack pointer (TOP OF RAM +1) RW */
SECTIONS
{
.text :
{
_text = .;
*(.rodata)
*(.strings)
*(.text)
_etext = .;
} >introm /* text */
_ldata = LOADADDR(.text) + SIZEOF(.text);
.data : AT ( _ldata )
{
_data = .;
*(.data)
_edata = .;
} >intram1 /* data */
_end = LOADADDR(.data) + SIZEOF(.data);
.bss . :
{
_bss = .;
*(.bss)
*(COMMON)
*(.tiny)
_ebss = .;
} >intram1 /* data */
_stack = 0x00FFF000; /* one above last ram location */
.vectors :
{
LONG(ABSOLUTE(DEFINED(_start) ? _start : _default_irq)) /* ( 0) Automatic Reset */
LONG(ABSOLUTE(DEFINED(_sys1_irq) ? _sys1_irq : _default_irq)) /* ( 1) System Reserved */
LONG(ABSOLUTE(DEFINED(_sys2_irq) ? _sys2_irq : _default_irq)) /* ( 2) System Reserved */
LONG(ABSOLUTE(DEFINED(_sys3_irq) ? _sys3_irq : _default_irq)) /* ( 3) System Reserved */
LONG(ABSOLUTE(DEFINED(_sys4_irq) ? _sys4_irq : _default_irq)) /* ( 4) System Reserved */
LONG(ABSOLUTE(DEFINED(_sys5_irq) ? _sys5_irq : _default_irq)) /* ( 5) System Reserved */
LONG(ABSOLUTE(DEFINED(_DirTrans_irq) ? _DirTrans_irq : _default_irq)) /* ( 6) Direct Transition */
LONG(ABSOLUTE(DEFINED(_nmi_irq) ? _nmi_irq : _default_irq)) /* ( 7) External NMI */
LONG(ABSOLUTE(DEFINED(_trap_a_irq) ? _trap_a_irq : _default_irq)) /* ( 8) Trap A */
LONG(ABSOLUTE(DEFINED(_trap_b_irq) ? _trap_b_irq : _default_irq)) /* ( 9) Trap B */
LONG(ABSOLUTE(DEFINED(_trap_c_irq) ? _trap_c_irq : _default_irq)) /* ( 10) Trap C */
LONG(ABSOLUTE(DEFINED(_trap_d_irq) ? _trap_d_irq : _default_irq)) /* ( 11) Trap D */
LONG(ABSOLUTE(DEFINED(_sys12_irq) ? _sys12_irq : _default_irq)) /* ( 12) System Reserved */
LONG(ABSOLUTE(DEFINED(_sys13_irq) ? _sys13_irq : _default_irq)) /* ( 13) System Reserved */
LONG(ABSOLUTE(DEFINED(_sys14_irq) ? _sys14_irq : _default_irq)) /* ( 14) System Reserved */
LONG(ABSOLUTE(DEFINED(_sys15_irq) ? _sys15_irq : _default_irq)) /* ( 15) System Reserved */
LONG(ABSOLUTE(DEFINED(_ext0_irq) ? _ext0_irq : _default_irq)) /* ( 16) External IRQ0 */
LONG(ABSOLUTE(DEFINED(_ext1_irq) ? _ext1_irq : _default_irq)) /* ( 17) External IRQ1 */
LONG(ABSOLUTE(DEFINED(_ext2_irq) ? _ext2_irq : _default_irq)) /* ( 18) External IRQ2 */
LONG(ABSOLUTE(DEFINED(_ext3_irq) ? _ext3_irq : _default_irq)) /* ( 19) External IRQ3 */
LONG(ABSOLUTE(DEFINED(_ext4_irq) ? _ext4_irq : _default_irq)) /* ( 20) External IRQ4 */
LONG(ABSOLUTE(DEFINED(_ext5_irq) ? _ext5_irq : _default_irq)) /* ( 21) External IRQ5 */
LONG(ABSOLUTE(DEFINED(_ext6_irq) ? _ext6_irq : _default_irq)) /* ( 22) External IRQ6, KIN7..KIN0 */
LONG(ABSOLUTE(DEFINED(_ext7_irq) ? _ext7_irq : _default_irq)) /* ( 23) External IRQ7, KIN15..KIN8 */
LONG(ABSOLUTE(DEFINED(_swdtend_irq) ? _swdtend_irq : _default_irq)) /* ( 24) SWDTEND (2148 DTC) */
LONG(ABSOLUTE(DEFINED(_wovi0_irq) ? _wovi0_irq : _default_irq)) /* ( 25) WOVI0 (Watchdog timer 0) */
LONG(ABSOLUTE(DEFINED(_wovi1_irq) ? _wovi1_irq : _default_irq)) /* ( 26) WOVI1 (Watchdog timer 1) */
LONG(ABSOLUTE(DEFINED(_pc_brk_irq) ? _pc_brk_irq : _default_irq)) /* ( 27) PC Break */
LONG(ABSOLUTE(DEFINED(_adc_end_irq) ? _adc_end_irq : _default_irq)) /* ( 28) A/D Conversion end. */
LONG(ABSOLUTE(DEFINED(_sys29_irq) ? _sys29_irq : _default_irq)) /* ( 29) Reserved */
LONG(ABSOLUTE(DEFINED(_sys30_irq) ? _sys30_irq : _default_irq)) /* ( 30) Reserved */
LONG(ABSOLUTE(DEFINED(_sys31_irq) ? _sys31_irq : _default_irq)) /* ( 31) Reserved */
LONG(ABSOLUTE(DEFINED(_sys32_irq) ? _sys32_irq : _default_irq)) /* ( 32) Reserved */
LONG(ABSOLUTE(DEFINED(_sys33_irq) ? _sys33_irq : _default_irq)) /* ( 33) Reserved */
LONG(ABSOLUTE(DEFINED(_sys34_irq) ? _sys34_irq : _default_irq)) /* ( 34) Reserved */
LONG(ABSOLUTE(DEFINED(_sys35_irq) ? _sys35_irq : _default_irq)) /* ( 35) Reserved */
LONG(ABSOLUTE(DEFINED(_sys36_irq) ? _sys36_irq : _default_irq)) /* ( 36) Reserved */
LONG(ABSOLUTE(DEFINED(_sys37_irq) ? _sys37_irq : _default_irq)) /* ( 37) Reserved */
LONG(ABSOLUTE(DEFINED(_sys38_irq) ? _sys38_irq : _default_irq)) /* ( 38) Reserved */
LONG(ABSOLUTE(DEFINED(_sys39_irq) ? _sys39_irq : _default_irq)) /* ( 39) Reserved */
LONG(ABSOLUTE(DEFINED(_sys40_irq) ? _sys40_irq : _default_irq)) /* ( 40) Reserved */
LONG(ABSOLUTE(DEFINED(_sys41_irq) ? _sys41_irq : _default_irq)) /* ( 41) Reserved */
LONG(ABSOLUTE(DEFINED(_sys42_irq) ? _sys42_irq : _default_irq)) /* ( 42) Reserved */
LONG(ABSOLUTE(DEFINED(_sys43_irq) ? _sys43_irq : _default_irq)) /* ( 43) Reserved */
LONG(ABSOLUTE(DEFINED(_sys44_irq) ? _sys44_irq : _default_irq)) /* ( 44) Reserved */
LONG(ABSOLUTE(DEFINED(_sys45_irq) ? _sys45_irq : _default_irq)) /* ( 45) Reserved */
LONG(ABSOLUTE(DEFINED(_sys46_irq) ? _sys46_irq : _default_irq)) /* ( 46) Reserved */
LONG(ABSOLUTE(DEFINED(_sys47_irq) ? _sys47_irq : _default_irq)) /* ( 47) Reserved */
LONG(ABSOLUTE(DEFINED(_frt_icia_irq) ? _frt_icia_irq : _default_irq)) /* ( 48) ICIA (Input Capture A) */
LONG(ABSOLUTE(DEFINED(_frt_icib_irq) ? _frt_icib_irq : _default_irq)) /* ( 49) ICIB (Input Capture B) */
LONG(ABSOLUTE(DEFINED(_frt_icic_irq) ? _frt_icic_irq : _default_irq)) /* ( 50) ICIC (Input Capture C) */
LONG(ABSOLUTE(DEFINED(_frt_icid_irq) ? _frt_icid_irq : _default_irq)) /* ( 51) ICID (Input Capture D) */
LONG(ABSOLUTE(DEFINED(_frt_oca_irq) ? _frt_oca_irq : _default_irq)) /* ( 52) OCIA (Output Compare A) */
LONG(ABSOLUTE(DEFINED(_frt_ocb_irq) ? _frt_ocb_irq : _default_irq)) /* ( 53) OCIB (Output Compare B) */
LONG(ABSOLUTE(DEFINED(_frt_fovi_irq) ? _frt_fovi_irq : _default_irq)) /* ( 54) FOVI (overflow) */
LONG(ABSOLUTE(DEFINED(_sys55_irq) ? _sys55_irq : _default_irq)) /* ( 55) Reserved */
LONG(ABSOLUTE(DEFINED(_sys56_irq) ? _sys56_irq : _default_irq)) /* ( 56) Reserved */
LONG(ABSOLUTE(DEFINED(_sys57_irq) ? _sys57_irq : _default_irq)) /* ( 57) Reserved */
LONG(ABSOLUTE(DEFINED(_sys58_irq) ? _sys58_irq : _default_irq)) /* ( 58) Reserved */
LONG(ABSOLUTE(DEFINED(_sys59_irq) ? _sys59_irq : _default_irq)) /* ( 59) Reserved */
LONG(ABSOLUTE(DEFINED(_sys60_irq) ? _sys60_irq : _default_irq)) /* ( 60) Reserved */
LONG(ABSOLUTE(DEFINED(_sys61_irq) ? _sys61_irq : _default_irq)) /* ( 61) Reserved */
LONG(ABSOLUTE(DEFINED(_sys62_irq) ? _sys62_irq : _default_irq)) /* ( 62) Reserved */
LONG(ABSOLUTE(DEFINED(_sys63_irq) ? _sys63_irq : _default_irq)) /* ( 63) Reserved */
LONG(ABSOLUTE(DEFINED(_tm0_cmai_irq) ? _tm0_cmai_irq : _default_irq)) /* ( 64) CMIA0 (compare match A) (8 bit timer 0) */
LONG(ABSOLUTE(DEFINED(_tm0_cmib_irq) ? _tm0_cmib_irq : _default_irq)) /* ( 65) CMIB0 (compare match B) */
LONG(ABSOLUTE(DEFINED(_tm0_ovfi_irq) ? _tm0_ovfi_irq : _default_irq)) /* ( 66) OVI0 (overflow) */
LONG(ABSOLUTE(DEFINED(_sys67_irq) ? _sys67_irq : _default_irq)) /* ( 67 ) /* ( 67) Reserved */
LONG(ABSOLUTE(DEFINED(_tm1_cmia_irq) ? _tm1_cmia_irq : _default_irq)) /* ( 68) CMIA1 (compare match A) (8 bit timer 1) */
LONG(ABSOLUTE(DEFINED(_tm1_cmib_irq) ? _tm1_cmib_irq : _default_irq)) /* ( 69) CMIB1 (compare match B) */
LONG(ABSOLUTE(DEFINED(_tm1_ovfi_irq) ? _tm1_ovfi_irq : _default_irq)) /* ( 70) OVI1 (overflow) */
LONG(ABSOLUTE(DEFINED(_sys71_irq) ? _sys71_irq : _default_irq)) /* ( 71) Reserved */
LONG(ABSOLUTE(DEFINED(_tmy_cmia_irq) ? _tmy_cmia_irq : _default_irq)) /* ( 72) CMIAY (compare match A) (8 bit timer channels Y, X) */
LONG(ABSOLUTE(DEFINED(_tmy_cmib_irq) ? _tmy_cmib_irq : _default_irq)) /* ( 73) CMIBY (compare match B) */
LONG(ABSOLUTE(DEFINED(_tmy_ovfi_irq) ? _tmy_ovfi_irq : _default_irq)) /* ( 74) OVIY (overflow) */
LONG(ABSOLUTE(DEFINED(_tmx_ici_irq) ? _tmx_ici_irq : _default_irq)) /* ( 75) ICIX (2148 input capture X) */
LONG(ABSOLUTE(DEFINED(_ibf1_irq) ? _ibf1_irq : _default_irq)) /* ( 76) IBF1 (2148 IDR1 reception complete) */
LONG(ABSOLUTE(DEFINED(_ibf2_irq) ? _ibf2_irq : _default_irq)) /* ( 77) IBF2 (2148 IDR2 reception complete) (Host interface) */
LONG(ABSOLUTE(DEFINED(_sys78_irq) ? _sys78_irq : _default_irq)) /* ( 78) Reserved */
LONG(ABSOLUTE(DEFINED(_sys79_irq) ? _sys79_irq : _default_irq)) /* ( 79) Reserved */
LONG(ABSOLUTE(DEFINED(_sci0_eri_irq) ? _sci0_eri_irq : _default_irq)) /* ( 80) ERI0 (Receive error 0) (SCI Channel 0) */
LONG(ABSOLUTE(DEFINED(_sci0_rxi_irq) ? _sci0_rxi_irq : _default_irq)) /* ( 81) RXI0 (Reception completed 0) */
LONG(ABSOLUTE(DEFINED(_sci0_tdre_irq) ? _sci0_tdre_irq : _default_irq)) /* ( 82) TXI0 (Transmit data default_irq 0) */
LONG(ABSOLUTE(DEFINED(_sci0_tc_irq) ? _sci0_tc_irq : _default_irq)) /* ( 83) TEI0 (Transmission end 0) */
LONG(ABSOLUTE(DEFINED(_sci1_eri_irq) ? _sci1_eri_irq : _default_irq)) /* ( 84) ERI1 (Receive error 1) (SCI Channel 1) */
LONG(ABSOLUTE(DEFINED(_sci1_rxi_irq) ? _sci1_rxi_irq : _default_irq)) /* ( 85) RXI1 (Reception completed 1) */
LONG(ABSOLUTE(DEFINED(_sci1_tdre_irq) ? _sci1_tdre_irq : _default_irq)) /* ( 86) TXI1 (Transmit data default_irq 1) */
LONG(ABSOLUTE(DEFINED(_sci1_tc_irq) ? _sci1_tc_irq : _default_irq)) /* ( 87) TEI1 (Transmission end 1) */
LONG(ABSOLUTE(DEFINED(_sci2_eri_irq) ? _sci2_eri_irq : _default_irq)) /* ( 88) ERI2 (Receive error 2) (SCI Channel 2)Reserved */
LONG(ABSOLUTE(DEFINED(_sci2_rxi_irq) ? _sci2_rxi_irq : _default_irq)) /* ( 89) RXI2 (Reception completed 2) */
LONG(ABSOLUTE(DEFINED(_sci2_tdre_irq) ? _sci2_tdre_irq : _default_irq)) /* ( 90) TXI2 (Transmit data default_irq 2) */
LONG(ABSOLUTE(DEFINED(_sci2_tc_irq) ? _sci2_tc_irq : _default_irq)) /* ( 91) TEI2 (Transmission end 2) */
LONG(ABSOLUTE(DEFINED(_iici0_irq) ? _iici0_irq : _default_irq)) /* ( 92) IICI0 (2148 1-byte transmission/reception completed) (IIC Channel 0) */
LONG(ABSOLUTE(DEFINED(_ddcswi_irq) ? _ddcswi_irq : _default_irq)) /* ( 93) DDCSWI (2148 format switch) */
LONG(ABSOLUTE(DEFINED(_iici1_irq) ? _iici1_irq : _default_irq)) /* ( 94) IICI1 (2148 1-byte transmission/reception completed) (IIC Channel 1) */
LONG(ABSOLUTE(DEFINED(_sys95_irq) ? _sys95_irq : _default_irq)) /* ( 95) Reserved */
LONG(ABSOLUTE(DEFINED(_ps2ia_irq) ? _ps2ia_irq : _default_irq)) /* ( 96) PS2IA (2148 reception completed A) (Keyboard buffer controller) */
LONG(ABSOLUTE(DEFINED(_ps2ib_irq) ? _ps2ib_irq : _default_irq)) /* ( 97) PS2IB (2148 reception completed B) */
LONG(ABSOLUTE(DEFINED(_ps2ic_irq) ? _ps2ic_irq : _default_irq)) /* ( 98) PS2IC (2148 reception completed C) */
LONG(ABSOLUTE(DEFINED(_sys99_irq) ? _sys99_irq : _default_irq)) /* ( 99) Reserved */
LONG(ABSOLUTE(DEFINED(_irqa_irq) ? _irqa_irq : _default_irq)) /* (100) Interrupt A (USB Option ?) */
LONG(ABSOLUTE(DEFINED(_irqb_irq) ? _irqb_irq : _default_irq)) /* (101) Interrupt B */
LONG(ABSOLUTE(DEFINED(_irqc_irq) ? _irqc_irq : _default_irq)) /* (102) Interrupt C */
LONG(ABSOLUTE(DEFINED(_irqd_irq) ? _irqd_irq : _default_irq)) /* (103) Interrupt D */
} > vectors
}

View File

@@ -1,145 +0,0 @@
/*
* Copyright (c) 2001, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Adam Dunkels.
* 4. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uip_arch.c,v 1.2 2001/10/25 18:55:57 adam Exp $
*
*/
#include "uip.h"
#include "uip_arch.h"
#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
#define IP_PROTO_TCP 6
/*-----------------------------------------------------------------------------------*/
#if UIP_BUFSIZE > 255
/*-----------------------------------------------------------------------------------*/
void
uip_add_rcv_nxt(u16_t n)
{
u32_t *tmp;
tmp = &uip_conn->rcv_nxt[0];
*tmp += n;
}
/*-----------------------------------------------------------------------------------*/
void
uip_add_ack_nxt(u16_t n)
{
u32_t *tmp;
tmp = &uip_conn->ack_nxt[0];
*tmp += n;
}
/*-----------------------------------------------------------------------------------*/
#else /* UIP_BUFSIZE > 255 */
/*-----------------------------------------------------------------------------------*/
void
uip_add_rcv_nxt(u8_t n)
{
u32_t *tmp;
tmp = (u32_t *)&uip_conn->rcv_nxt[0];
*tmp += n;
}
/*-----------------------------------------------------------------------------------*/
void
uip_add_ack_nxt(u8_t n)
{
u32_t *tmp;
tmp = (u32_t*)&uip_conn->ack_nxt[0];
*tmp += n;
}
/*-----------------------------------------------------------------------------------*/
#endif /* UIP_BUFSIZE > 255 */
static u16_t
chksum(u8_t *sdata, u16_t len)
{
u32_t acc = 0;
u16_t i = 0;
while (i < len) {
if (i & 0x01)
{
acc += *sdata++;
} else
{
acc += ((u32_t)(*sdata++))<<8;
}
i++;
};
while(acc >> 16) {
acc = (acc & 0xffffUL) + (acc >> 16);
}
return acc & 0xffffUL;
}
/*-----------------------------------------------------------------------------------*/
u16_t
uip_ipchksum(void)
{
return chksum(&uip_buf[UIP_LLH_LEN], 20);
}
/*-----------------------------------------------------------------------------------*/
u16_t
uip_tcpchksum(void)
{
u32_t sum;
/* Compute the checksum of the TCP header. */
sum = chksum( &uip_buf[20 + UIP_LLH_LEN], 20);
/* Compute the checksum of the data in the TCP packet and add it to
the TCP header checksum. */
sum += chksum(uip_appdata,
(u16_t)(((BUF->len[0] << 8) + BUF->len[1]) - 40));
sum += BUF->srcipaddr[0];
sum += BUF->srcipaddr[1];
sum += BUF->destipaddr[0];
sum += BUF->destipaddr[1];
sum += (u16_t)htons((u16_t)IP_PROTO_TCP);
sum += (u16_t)htons(((BUF->len[0] << 8) + BUF->len[1]) - 20);
while(sum >> 16) {
sum = (sum & 0xffff) + (sum >> 16);
}
return sum & 0xffff;
}
/*-----------------------------------------------------------------------------------*/

View File

@@ -1,53 +0,0 @@
/*
* Copyright (c) 2001, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Adam Dunkels.
* 4. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uip_arch.h,v 1.2 2001/10/25 18:55:57 adam Exp $
*
*/
#ifndef __UIP_ARCH_H__
#define __UIP_ARCH_H__
#include "uip.h"
#if UIP_BUFSIZE > 255
void uip_add_rcv_nxt(u16_t n);
void uip_add_ack_nxt(u16_t n);
#else
void uip_add_rcv_nxt(u8_t n);
void uip_add_ack_nxt(u8_t n);
#endif /* UIP_BUFSIZE > 255 */
u16_t uip_ipchksum(void);
u16_t uip_tcpchksum(void);
#endif /* __UIP_ARCH_H__ */

View File

@@ -1,115 +0,0 @@
/*
* Copyright (c) 2001, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Adam Dunkels.
* 4. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uipopt.h,v 1.3 2001/11/25 19:00:03 adam Exp $
*
*/
#ifndef __UIPOPT_H__
#define __UIPOPT_H__
#define __fastcall__
/* This file is used for tweaking various configuration options for
uIP. You should make a copy of this file into one of your project's
directories instead of editing the example "uipopt.h" file that
come with the uIP distribution. */
/* The following typedefs may have to be tweaked for your particular
compiler. The uX_t types are unsigned integer types, where the X is
the number of bits in the integer type. */
typedef unsigned char u8_t;
typedef unsigned short u16_t;
typedef unsigned long u32_t;
/* This is where you configure if your CPU architecture is big or
little endian. Most CPUs today are little endian. The most notable
exception are the Motorolas which are big endian. Tweak the
definition of the BYTE_ORDER macro to configure uIP for your
project. */
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 3412
#endif /* LITTLE_ENDIAN */
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 1234
#endif /* BIGE_ENDIAN */
#ifndef BYTE_ORDER
#define BYTE_ORDER BIG_ENDIAN
#endif /* BYTE_ORDER */
/* This is the header of the application program that should be
used. */
#include "httpd.h"
/* UIP_CONNS: The maximum number of simultaneously active
connections. */
#define UIP_CONNS 10
/* UIP_LISTENPORTS: The maximum number of simultaneously listening TCP
ports. */
#define UIP_LISTENPORTS 1
/* UIP_BUFSIZE: The size of the buffer that holds incoming and
outgoing packets. In this version of uIP, this can be more than
255 bytes. */
#define UIP_BUFSIZE 240
/* UIP_IPADDR: The IP address of this uIP node. */
#define UIP_IPADDR0 192
#define UIP_IPADDR1 168
#define UIP_IPADDR2 0
#define UIP_IPADDR3 2
/* UIP_LLH_LEN: The link level header length; this is the offset into
the uip_buf where the IP header can be found. For Ethernet, this
should be set to 14. */
#define UIP_LLH_LEN 0
/* UIP_TCP_MSS: The TCP maximum segment size. This should be set to
at most UIP_BUFSIZE - 40. */
#define UIP_TCP_MSS UIP_BUFSIZE - 40
/* UIP_TTL: The IP TTL (time to live) of IP packets sent by uIP. */
#define UIP_TTL 128
/* UIP_RTO: The retransmission timeout counted in timer pulses (i.e.,
the speed of the periodic timer). */
#define UIP_RTO 3
#define UIP_STATISTICS 1
#define UIP_LOGGING 0
#define UIP_TIME_WAIT_TIMEOUT 120
#endif /* __UIPOPT_H__ */

View File

@@ -1,61 +0,0 @@
/*
* Copyright (c) 2001, Paul Clarke, Hydra Electronic Design Solutions Pty Ltd.
* http://www.hydraelectronics.com.au
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: vectors.c,v 1.2 2001/10/25 18:55:57 adam Exp $
*
*/
///////////////////////////////////////////////////////////////////////////////
//
// Module: vectors.c
// Description:
// Interrupt vector table for use on the H8S/2148
//
// Comments:
// This modules defines the function that is executed when a H8
// exception is processed.
//
#include "hd2144.h"
void default_irq(void) __attribute__ ((OS_Task));
void default_irq(void)
{
__asm__ volatile ("jmp @@0x01c"); // find addr of nmi routine and go there
}
void nmi_irq(void) __attribute__ ((interrupt_handler));
void nmi_irq(void)
{
// use watchdog to make a reset
h8_wdt_tcsr0_w = 0xA56f; // cause a reset when counter overflows
h8_wdt_tcnt0_w = 0x5aff; // counter = 0xff
}

430
uip/uip.c
View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, Adam Dunkels.
* Copyright (c) 2001-2002, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uip.c,v 1.24 2001/11/23 06:50:07 adam Exp $
* $Id: uip.c,v 1.34 2002/01/15 17:54:54 adam Exp $
*
*/
@@ -58,6 +58,53 @@ fields and finally send the packet back to the peer. */
#include "uipopt.h"
#include "uip_arch.h"
/*-----------------------------------------------------------------------------------*/
/* Variable definitions. */
u8_t uip_buf[UIP_BUFSIZE]; /* The packet buffer that contains
incoming packets. */
volatile u8_t *uip_appdata; /* The uip_appdata pointer points to
application data. */
#if UIP_BUFSIZE > 255
volatile u16_t uip_len; /* The uip_len is either 8 or 16 bits,
depending on the maximum packet
size. */
#else
volatile u8_t uip_len;
#endif /* UIP_BUFSIZE > 255 */
volatile u8_t uip_flags; /* The uip_flags variable is used for
communication between the TCP/IP stack
and the application program. */
struct uip_conn *uip_conn; /* uip_conn always points to the current
connection. */
struct uip_conn uip_conns[UIP_CONNS];
/* The uip_conns array holds all TCP
connections. */
u16_t uip_listenports[UIP_LISTENPORTS];
/* The uip_listenports list all currently
listning ports. */
static u16_t ipid; /* Ths ipid variable is an increasing
number that is used for the IP ID
field. */
static u8_t iss[4]; /* The iss variable is used for the TCP
initial sequence number. */
#if UIP_ACTIVE_OPEN
static u16_t lastport; /* Keeps track of the last port used for
a new connection. */
#endif /* UIP_ACTIVE_OPEN */
/* Temporary variables. */
static u8_t c, opt;
static u16_t tmpport;
/* Structures and definitions. */
typedef struct {
/* IP header. */
u8_t vhl,
@@ -87,30 +134,7 @@ typedef struct {
#define IP_PROTO_TCP 6
#define ICMP_ECHO_REPLY 0
#define ICMP_ECHO 8
u8_t uip_buf[UIP_BUFSIZE];
volatile u8_t *uip_appdata;
#if UIP_BUFSIZE > 255
volatile u16_t uip_len;
#else
volatile u8_t uip_len;
#endif /* UIP_BUFSIZE > 255 */
volatile u8_t uip_flags;
struct uip_conn *uip_conn;
static u16_t ipid;
void uip_process(u8_t flag);
struct uip_conn uip_conns[UIP_CONNS];
u16_t uip_listenports[UIP_LISTENPORTS];
/* Temporary variables. */
static u8_t tmpcnt;
static u16_t tmpport;
#define ICMP_ECHO 8
/* Macros. */
#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
@@ -124,51 +148,113 @@ struct uip_stats uip_stat;
#endif /* UIP_STATISTICS == 1 */
#if UIP_LOGGING == 1
#define UIP_LOG(m) uip_log(m)
#define UIP_LOG(m) printf("%s\n", m)
#else
#define UIP_LOG(m)
#endif /* UIP_LOGGING == 1 */
/* The "rexmit_shift" table takes care of the exponential backoff -
the RTO will be shifted rexmit_shift[number of retransmissions]. */
static const u8_t rexmit_shift[8] = {0,1,2,3,4,4,4,4};
/*-----------------------------------------------------------------------------------*/
void
uip_init(void)
{
for(tmpcnt = 0; tmpcnt < UIP_LISTENPORTS; ++tmpcnt) {
uip_listenports[tmpcnt] = 0;
for(c = 0; c < UIP_LISTENPORTS; ++c) {
uip_listenports[c] = 0;
}
for(tmpcnt = 0; tmpcnt < UIP_CONNS; ++tmpcnt) {
uip_conns[tmpcnt].tcpstateflags = CLOSED;
for(c = 0; c < UIP_CONNS; ++c) {
uip_conns[c].tcpstateflags = CLOSED;
}
#if UIP_ACTIVE_OPEN
lastport = 1024;
#endif /* UIP_ACTIVE_OPEN */
}
/*-----------------------------------------------------------------------------------*/
#if UIP_ACTIVE_OPEN
struct uip_conn *
uip_connect(u16_t *ripaddr, u16_t rport)
{
struct uip_conn *conn;
/* Find an unused local port. */
again:
++lastport;
if(lastport >= 32000) {
lastport = 4096;
}
for(c = 0; c < UIP_CONNS; ++c) {
if(uip_conns[c].tcpstateflags != CLOSED &&
uip_conns[c].lport == lastport)
goto again;
}
for(c = 0; c < UIP_CONNS; ++c) {
if(uip_conns[c].tcpstateflags == CLOSED)
goto found_unused;
}
for(c = 0; c < UIP_CONNS; ++c) {
if(uip_conns[c].tcpstateflags == TIME_WAIT)
goto found_unused;
}
return (void *)0;
found_unused:
conn = &uip_conns[c];
conn->tcpstateflags = SYN_SENT | UIP_OUTSTANDING;
conn->snd_nxt[0] = conn->ack_nxt[0] = iss[0];
conn->snd_nxt[1] = conn->ack_nxt[1] = iss[1];
conn->snd_nxt[2] = conn->ack_nxt[2] = iss[2];
conn->snd_nxt[3] = conn->ack_nxt[3] = iss[3];
if(++conn->ack_nxt[3] == 0) {
if(++conn->ack_nxt[2] == 0) {
if(++conn->ack_nxt[1] == 0) {
++conn->ack_nxt[0];
}
}
}
conn->nrtx = 0;
conn->timer = 1; /* Send the SYN next time around. */
conn->lport = htons(lastport);
conn->rport = htons(rport);
conn->ripaddr[0] = ripaddr[0];
conn->ripaddr[1] = ripaddr[1];
return conn;
}
#endif /* UIP_ACTIVE_OPEN */
/*-----------------------------------------------------------------------------------*/
void
uip_listen(u16_t port)
{
for(tmpcnt = 0; tmpcnt < UIP_LISTENPORTS; ++tmpcnt) {
if(uip_listenports[tmpcnt] == 0) {
uip_listenports[tmpcnt] = htons(port);
for(c = 0; c < UIP_LISTENPORTS; ++c) {
if(uip_listenports[c] == 0) {
uip_listenports[c] = htons(port);
break;
}
}
}
/*-----------------------------------------------------------------------------------*/
void
uip_periodic(u8_t conn)
{
uip_conn = &uip_conns[conn];
uip_process(UIP_TIMER);
}
/*-----------------------------------------------------------------------------------*/
void
uip_process(u8_t flag)
{
uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
/* Check if we were invoked because of the perodic timer fireing. */
if(flag == UIP_TIMER) {
/* Increase the initial sequence number. */
if(++iss[3] == 0) {
if(++iss[2] == 0) {
if(++iss[1] == 0) {
++iss[0];
}
}
}
uip_len = 0;
if(uip_conn->tcpstateflags == TIME_WAIT ||
uip_conn->tcpstateflags == FIN_WAIT_2) {
@@ -181,17 +267,28 @@ uip_process(u8_t flag)
connection's timer and see if it has reached the RTO value
in which case we retransmit. */
if(uip_conn->tcpstateflags & UIP_OUTSTANDING) {
++(uip_conn->timer);
if(uip_conn->timer ==
(UIP_RTO << rexmit_shift[uip_conn->nrtx])) {
uip_conn->timer = 0;
++(uip_conn->nrtx);
if(uip_conn->nrtx == 8) {
/* XXX: we should call UIP_APPCALL() with uip_flags set to
UIP_ABORTED or similar. But this will do for now. */
--(uip_conn->timer);
if(uip_conn->timer == 0) {
if(uip_conn->nrtx == UIP_MAXRTX) {
uip_conn->tcpstateflags = CLOSED;
return;
/* We call UIP_APPCALL() with uip_flags set to
UIP_TIMEDOUT to inform the application that the
connection has timed out. */
uip_flags = UIP_TIMEDOUT;
UIP_APPCALL();
/* We also send a reset packet to the remote host. */
BUF->flags = TCP_RST | TCP_ACK;
goto tcp_send_nodata;
}
/* Exponential backoff. */
uip_conn->timer = UIP_RTO << (uip_conn->nrtx > 4? 4: uip_conn->nrtx);
++(uip_conn->nrtx);
/* Ok, so we need to retransmit. We do this differently
depending on which state we are in. In ESTABLISHED, we
call upon the application so that it may prepare the
@@ -199,12 +296,19 @@ uip_process(u8_t flag)
SYNACK that we sent earlier and in LAST_ACK we have to
retransmit our FINACK. */
UIP_STAT(++uip_stat.tcp.rexmit);
switch(uip_conn->tcpstateflags & TS_MASK) {
switch(uip_conn->tcpstateflags & TS_MASK) {
case SYN_RCVD:
/* In the SYN_RCVD state, we should retransmit our
SYNACK. */
goto tcp_send_synack;
#if UIP_ACTIVE_OPEN
case SYN_SENT:
/* In the SYN_SENT state, we retransmit out SYN. */
BUF->flags = 0;
goto tcp_send_syn;
#endif /* UIP_ACTIVE_OPEN */
case ESTABLISHED:
/* In the ESTABLISHED state, we call upon the application
to do the actual retransmit after which we jump into
@@ -223,7 +327,7 @@ uip_process(u8_t flag)
}
}
} else if(uip_conn->tcpstateflags == ESTABLISHED) {
} else if((uip_conn->tcpstateflags & TS_MASK) == ESTABLISHED) {
/* If there was no need for a retransmission, we poll the
application for new data. */
uip_len = 0;
@@ -349,7 +453,8 @@ uip_process(u8_t flag)
UIP_STAT(++uip_stat.icmp.sent);
goto send;
/* TCP input processing. */
tcp_input:
UIP_STAT(++uip_stat.tcp.recv);
@@ -381,14 +486,12 @@ uip_process(u8_t flag)
tmpport = BUF->destport;
/* Next, check listening connections. */
for(tmpcnt = 0; tmpcnt < UIP_LISTENPORTS &&
uip_listenports[tmpcnt] != 0;
++tmpcnt) {
if(tmpport == uip_listenports[tmpcnt])
for(c = 0; c < UIP_LISTENPORTS && uip_listenports[c] != 0; ++c) {
if(tmpport == uip_listenports[c])
goto found_listen;
}
/* No matching connection found, so we send a RST packet. */
UIP_STAT(++uip_stat.tcp.synrst);
reset:
@@ -402,31 +505,29 @@ uip_process(u8_t flag)
uip_len = 40;
BUF->tcpoffset = 5 << 4;
/* Flip the seqno and ackno fields in the TCP header. We also have
to increase the sequence number we are acknowledging. */
tmpcnt = BUF->seqno[3];
/* Flip the seqno and ackno fields in the TCP header. */
c = BUF->seqno[3];
BUF->seqno[3] = BUF->ackno[3];
BUF->ackno[3] = tmpcnt + 1;
BUF->ackno[3] = c;
tmpcnt = BUF->seqno[2];
c = BUF->seqno[2];
BUF->seqno[2] = BUF->ackno[2];
BUF->ackno[2] = tmpcnt;
BUF->ackno[2] = c;
tmpcnt = BUF->seqno[1];
c = BUF->seqno[1];
BUF->seqno[1] = BUF->ackno[1];
BUF->ackno[1] = tmpcnt;
BUF->ackno[1] = c;
tmpcnt = BUF->seqno[0];
c = BUF->seqno[0];
BUF->seqno[0] = BUF->ackno[0];
BUF->ackno[0] = tmpcnt;
BUF->ackno[0] = c;
/* If the least significant byte overflowed, we need to propagate
the carry to the other bytes as well. */
if(BUF->ackno[3] == 0) {
++BUF->ackno[2];
if(BUF->ackno[2] == 0) {
++BUF->ackno[1];
if(BUF->ackno[1] == 0) {
/* We also have to increase the sequence number we are
acknowledging. If the least significant byte overflowed, we need
to propagate the carry to the other bytes as well. */
if(++BUF->ackno[3] == 0) {
if(++BUF->ackno[2] == 0) {
if(++BUF->ackno[1] == 0) {
++BUF->ackno[0];
}
}
@@ -455,12 +556,12 @@ uip_process(u8_t flag)
/* First we check if there are any connections avaliable. Unused
connections are kept in the same table as used connections, but
unused ones have the tcpstate set to CLOSED. */
for(tmpcnt = 0; tmpcnt < UIP_CONNS; ++tmpcnt) {
if((uip_conns[tmpcnt].tcpstateflags & TS_MASK) == CLOSED)
for(c = 0; c < UIP_CONNS; ++c) {
if(uip_conns[c].tcpstateflags == CLOSED)
goto found_unused_connection;
}
for(tmpcnt = 0; tmpcnt < UIP_CONNS; ++tmpcnt) {
if((uip_conns[tmpcnt].tcpstateflags & TS_MASK) == TIME_WAIT)
for(c = 0; c < UIP_CONNS; ++c) {
if(uip_conns[c].tcpstateflags == TIME_WAIT)
goto found_unused_connection;
}
/* All connections are used already, we drop packet and hope that
@@ -473,23 +574,22 @@ uip_process(u8_t flag)
/* This label will be jumped to if we have found an unused
connection that we can use. */
found_unused_connection:
uip_conn = &uip_conns[tmpcnt];
uip_conn = &uip_conns[c];
/* Fill in the necessary fields for the new connection. */
uip_conn->timer = 0;
uip_conn->timer = UIP_RTO;
uip_conn->nrtx = 0;
uip_conn->lport = BUF->destport;
uip_conn->rport = BUF->srcport;
uip_conn->ripaddr[0] = BUF->srcipaddr[0];
uip_conn->ripaddr[1] = BUF->srcipaddr[1];
uip_conn->tcpstateflags = SYN_RCVD | UIP_OUTSTANDING;
uip_conn->snd_nxt[0] = uip_conn->snd_nxt[1] =
uip_conn->snd_nxt[2] = uip_conn->snd_nxt[3] = 0;
uip_conn->tcpstateflags = SYN_RCVD | UIP_OUTSTANDING;
/* Next ACK from peer should acknowledge sequence number 1. */
uip_conn->ack_nxt[0] = uip_conn->ack_nxt[1] =
uip_conn->ack_nxt[2] = 0;
uip_conn->ack_nxt[3] = 1;
uip_conn->snd_nxt[0] = uip_conn->ack_nxt[0] = iss[0];
uip_conn->snd_nxt[1] = uip_conn->ack_nxt[1] = iss[1];
uip_conn->snd_nxt[2] = uip_conn->ack_nxt[2] = iss[2];
uip_conn->snd_nxt[3] = uip_conn->ack_nxt[3] = iss[3];
uip_add_ack_nxt(1);
/* rcv_nxt should be the seqno from the incoming packet + 1. */
uip_conn->rcv_nxt[3] = BUF->seqno[3];
@@ -498,10 +598,46 @@ uip_process(u8_t flag)
uip_conn->rcv_nxt[0] = BUF->seqno[0];
uip_add_rcv_nxt(1);
tcp_send_synack:
/* Our response will be a SYNACK. */
BUF->flags = TCP_SYN | TCP_ACK;
/* Parse the TCP MSS option, if present. */
if((BUF->tcpoffset & 0xf0) > 0x50) {
for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
opt = uip_buf[40 + UIP_LLH_LEN + c];
if(opt == 0x00) {
/* End of options. */
break;
} else if(opt == 0x01) {
++c;
/* NOP option. */
} else if(opt == 0x02 &&
uip_buf[40 + UIP_LLH_LEN + c + 1] == 0x04) {
/* An MSS option with the right option length. */
tmpport = (uip_buf[40 + UIP_LLH_LEN + c + 2] << 8) |
uip_buf[40 + UIP_LLH_LEN + c + 3];
uip_conn->mss = tmpport > UIP_TCP_MSS? UIP_TCP_MSS: tmpport;
/* And we are done processing options. */
break;
} else {
/* All other options have a length field, so that we easily
can skip past them. */
c += uip_buf[40 + UIP_LLH_LEN + c + 1];
}
}
}
/* Our response will be a SYNACK. */
#if UIP_ACTIVE_OPEN
tcp_send_synack:
BUF->flags = TCP_ACK;
tcp_send_syn:
BUF->flags |= TCP_SYN;
#else /* UIP_ACTIVE_OPEN */
tcp_send_synack:
BUF->flags = TCP_SYN | TCP_ACK;
#endif /* UIP_ACTIVE_OPEN */
/* We send out the TCP Maximum Segment Size option with our
SYNACK. */
BUF->optdata[0] = 2;
@@ -523,6 +659,8 @@ uip_process(u8_t flag)
if(BUF->flags & TCP_RST) {
uip_conn->tcpstateflags = CLOSED;
UIP_LOG("tcp: got reset, aborting connection.");
uip_flags = UIP_ABORT;
UIP_APPCALL();
goto drop;
}
/* All segments that are come thus far should have the ACK flag set,
@@ -536,11 +674,11 @@ uip_process(u8_t flag)
/* Calculated the length of the data, if the application has sent
any data to us. */
tmpcnt = (BUF->tcpoffset >> 4) << 2;
c = (BUF->tcpoffset >> 4) << 2;
/* uip_len will contain the length of the actual TCP data. This is
calculated by subtracing the length of the TCP header (in
tmpcnt) and the length of the IP header (20 bytes). */
uip_len = uip_len - tmpcnt - 20;
c) and the length of the IP header (20 bytes). */
uip_len = uip_len - c - 20;
/* First, check if the sequence number of the incoming packet is
what we're expecting next. If not, we send out an ACK with the
@@ -554,7 +692,7 @@ uip_process(u8_t flag)
}
/* Next, check if the incoming segment acknowledges any outstanding
data. */
data. If so, we also reset the retransmission timer. */
if(BUF->ackno[0] == uip_conn->ack_nxt[0] &&
BUF->ackno[1] == uip_conn->ack_nxt[1] &&
BUF->ackno[2] == uip_conn->ack_nxt[2] &&
@@ -566,16 +704,16 @@ uip_process(u8_t flag)
if(uip_conn->tcpstateflags & UIP_OUTSTANDING) {
uip_flags = UIP_ACKDATA;
uip_conn->tcpstateflags &= ~UIP_OUTSTANDING;
uip_conn->timer = UIP_RTO;
}
}
/* Do different things depending on in what state the connection is. */
switch(uip_conn->tcpstateflags & TS_MASK) {
/* CLOSED and LISTEN are not handled here, SYN_SENT is not
implemented. CLOSE_WAIT is not implemented either, since we
force the application to close when the peer sends a FIN
(hence the application goes directly from ESTABLISHED to
LAST_ACK). */
/* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
implemented, since we force the application to close when the
peer sends a FIN (hence the application goes directly from
ESTABLISHED to LAST_ACK). */
case SYN_RCVD:
/* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
we are waiting for an ACK that acknowledges the data we sent
@@ -583,12 +721,62 @@ uip_process(u8_t flag)
flag set. If so, we enter the ESTABLISHED state. */
if(uip_flags & UIP_ACKDATA) {
uip_conn->tcpstateflags = ESTABLISHED;
uip_flags = UIP_ACCEPT;
uip_flags = UIP_CONNECTED;
uip_len = 0;
UIP_APPCALL();
goto appsend;
}
goto drop;
#if UIP_ACTIVE_OPEN
case SYN_SENT:
/* In SYN_SENT, we wait for a SYNACK that is sent in response to
our SYN. The rcv_nxt is set to sequence number in the SYNACK
plus one, and we send an ACK. We move into the ESTABLISHED
state. */
if((uip_flags & UIP_ACKDATA) &&
BUF->flags == (TCP_SYN | TCP_ACK)) {
/* Parse the TCP MSS option, if present. */
if((BUF->tcpoffset & 0xf0) > 0x50) {
for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
opt = uip_buf[40 + UIP_LLH_LEN + c];
if(opt == 0x00) {
/* End of options. */
break;
} else if(opt == 0x01) {
++c;
/* NOP option. */
} else if(opt == 0x02 &&
uip_buf[40 + UIP_LLH_LEN + c + 1] == 0x04) {
/* An MSS option with the right option length. */
tmpport = (uip_buf[40 + UIP_LLH_LEN + c + 2] << 8) |
uip_buf[40 + UIP_LLH_LEN + c + 3];
uip_conn->mss = tmpport > UIP_TCP_MSS? UIP_TCP_MSS: tmpport;
/* And we are done processing options. */
break;
} else {
/* All other options have a length field, so that we easily
can skip past them. */
c += uip_buf[40 + UIP_LLH_LEN + c + 1];
}
}
}
uip_conn->tcpstateflags = ESTABLISHED;
uip_conn->rcv_nxt[0] = BUF->seqno[0];
uip_conn->rcv_nxt[1] = BUF->seqno[1];
uip_conn->rcv_nxt[2] = BUF->seqno[2];
uip_conn->rcv_nxt[3] = BUF->seqno[3];
uip_add_rcv_nxt(1);
uip_flags = UIP_CONNECTED | UIP_NEWDATA;
uip_len = 0;
UIP_APPCALL();
goto appsend;
}
goto drop;
#endif /* UIP_ACTIVE_OPEN */
case ESTABLISHED:
/* In the ESTABLISHED state, we call upon the application to feed
data into the uip_buf. If the UIP_ACKDATA flag is set, the
@@ -599,12 +787,11 @@ uip_process(u8_t flag)
If the incoming packet is a FIN, we should close the connection on
this side as well, and we send out a FIN and enter the LAST_ACK
state. We require that the FIN will have to acknowledge all
outstanding data, otherwise we drop it. BUG: this will not work if
a FIN segment contains data! */
outstanding data, otherwise we drop it. */
if(BUF->flags & TCP_FIN) {
uip_add_rcv_nxt(1 + uip_len);
uip_flags = UIP_CLOSED;
uip_flags = UIP_CLOSE;
uip_len = 0;
UIP_APPCALL();
uip_add_ack_nxt(1);
@@ -615,10 +802,13 @@ uip_process(u8_t flag)
goto tcp_send_nodata;
}
/* If uip_len > 0 we have TCP data in the packet, and we flag this
by setting the UIP_NEWDATA flag and update the sequence number
we acknowledge. */
if(uip_len > 0) {
we acknowledge. If the application has stopped the dataflow
using uip_stop(), we must not accept any data packets from the
remote host. */
if(uip_len > 0 && !(uip_conn->tcpstateflags & UIP_STOPPED)) {
uip_flags |= UIP_NEWDATA;
uip_add_rcv_nxt(uip_len);
}
@@ -730,6 +920,9 @@ uip_process(u8_t flag)
goto tcp_send_ack;
}
goto drop;
case TIME_WAIT:
goto tcp_send_ack;
case CLOSING:
if(uip_flags & UIP_ACKDATA) {
@@ -752,8 +945,7 @@ uip_process(u8_t flag)
/* We're done with the input processing. We are now ready to send a
reply. Our job is to fill in all the fields of the TCP and IP
headers before calculating the checksum and finally send the
packet. */
packet. */
BUF->ackno[0] = uip_conn->rcv_nxt[0];
BUF->ackno[1] = uip_conn->rcv_nxt[1];
BUF->ackno[2] = uip_conn->rcv_nxt[2];
@@ -777,6 +969,19 @@ uip_process(u8_t flag)
BUF->destipaddr[0] = uip_conn->ripaddr[0];
BUF->destipaddr[1] = uip_conn->ripaddr[1];
if(uip_conn->tcpstateflags & UIP_STOPPED) {
/* If the connection has issued uip_stop(), we advertise a zero
window so that the remote host will stop sending data. */
BUF->wnd[0] = BUF->wnd[1] = 0;
} else {
#if (UIP_TCP_MSS) > 255
BUF->wnd[0] = (uip_conn->mss >> 8);
#else
BUF->wnd[0] = 0;
#endif /* UIP_MSS */
BUF->wnd[1] = (uip_conn->mss & 0xff);
}
tcp_send_noconn:
@@ -794,9 +999,6 @@ uip_process(u8_t flag)
BUF->len[1] = uip_len;
#endif /* UIP_BUFSIZE > 255 */
BUF->wnd[0] = ((UIP_TCP_MSS) >> 8);
BUF->wnd[1] = ((UIP_TCP_MSS) & 0xff);
++ipid;
BUF->ipid[0] = ipid >> 8;
BUF->ipid[1] = ipid & 0xff;

521
uip/uip.h
View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, Adam Dunkels.
* Copyright (c) 2001-2002, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uip.h,v 1.8 2001/10/25 18:55:39 adam Exp $
* $Id: uip.h,v 1.19 2002/01/15 17:54:54 adam Exp $
*
*/
@@ -40,131 +40,198 @@
#include "uipopt.h"
/*-----------------------------------------------------------------------------------*/
/* First, the functions that should be called from the
* system. Initialization, the periodic timer and incoming packets are
* handled by the following three functions.
*/
/* The following global variables are used for passing parameters
between uIP, the network device driver and the application. */
/* uip_init():
*
* Must be called at boot up to configure the uIP data structures.
*/
void uip_init(void);
extern u8_t uip_buf[UIP_BUFSIZE]; /* The uip_buf array is used to
hold incoming and outgoing
packets. The device driver fills
this with incoming packets, and
reads from here when sending
packets out on the wire. */
extern volatile u8_t *uip_appdata; /* This pointer points to the
application data when the
application is called. If the
application wishes to send data,
this is where the application
should write it. */
/* uip_periodic(conn):
*
* Should be called when the periodic timer has fired. Should be
* called once per connection (0 - UIP_CONNS).
*/
#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \
uip_process(UIP_TIMER); } while (0)
#if UIP_BUFSIZE > 255
extern volatile u16_t uip_len;
#else
extern volatile u8_t uip_len;
#endif /* UIP_BUFSIZE > 255 */
/* uip_input():
*
* Is called when the network device driver has received new data.
*/
#define uip_input() uip_process(UIP_DATA)
/* When the application is called,
uip_len contains the length of
any new data that has been
received from the remote
host. The application should set
this variable to the size of any
data that the application wishes
to send. When the network device
driver output function is
called, uip_len contains the
length of the outgoing
packet. */
extern volatile u8_t uip_flags; /* When the application is called,
uip_flags will contain the flags
that are defined in this
file. Please read below for more
infomation. */
extern struct uip_conn *uip_conn; /* When the application is called,
uip_conn will point to the
conntection that should be
processed by the
application. See below
for more information. */
/*-----------------------------------------------------------------------------------*/
/* Functions that are used by the uIP application program. Opening and
* closing connections, sending and receiving data, etc. is all
* handled by the functions below.
*/
/* The uIP functional interface. */
void uip_init(void); /* uip_init() must be called at
boot up to configure the uIP
data structures. */
void uip_periodic(u8_t conn); /* uip_periodic() should be called
when the periodic timer has
fired. Should be called once per
connection (0 - UIP_CONNS). */
void uip_process(u8_t flag); /* uip_process() is called when the
network device driver has
received new data. */
void uip_listen(u16_t port); /* Starts listening to the
specified port. */
/* uip_listen(port):
*
* Starts listening to the specified port.
*/
void uip_listen(u16_t port);
/* The following structure is used for identifying a connection. All
but one field in the structure are to be considered read-only by an
application. The only exception is the appstate field whos purpose
is to let the application store application-specific state (e.g.,
file pointers) for the connection. The size of this field is
configured in the "uipopt.h" header file. */
/* uip_connect(ripaddr, port):
*
* Returns a connection identifier that connects to a port on the
* specified host (given in ripaddr). If no connections are avaliable,
* the function returns NULL. This function is avaliable only if
* support for active open has been configured (#define
* UIP_ACTIVE_OPEN 1 in uipopt.h)
*/
struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port);
struct uip_conn {
u8_t tcpstateflags; /* TCP state and flags. */
u16_t lport, rport; /* The local and the remote port. */
u16_t ripaddr[2]; /* The IP address of the remote peer. */
u8_t rcv_nxt[4]; /* The sequence number that we expect to receive
next. */
u8_t snd_nxt[4]; /* The sequence number that was last sent by
us. */
u8_t ack_nxt[4]; /* The sequence number that should be ACKed by
next ACK from peer. */
u8_t timer; /* The retransmission timer. */
u8_t nrtx; /* Counts the number of retransmissions for a
particular segment. */
u8_t appstate[UIP_APPSTATE_SIZE];
};
/* uip_send(data, len):
*
* Send data on the current connection. The length of the data must
* not exceed the maxium segment size (MSS) for the connection.
*/
#define uip_send(data, len) do { uip_appdata = data; uip_len = len;} while(0)
/* The following flags may be set in the global variable uip_flags
before calling the application callback. The UIP_ACKDATA and
UIP_NEWDATA flags may both be set at the same time, whereas the
others are mutualy exclusive. */
/* uip_datalen():
*
* The length of the data that is currently avaliable (if avaliable)
* in the uip_appdata buffer. The test function uip_data() is
* used to check if data is avaliable.
*/
#define uip_datalen() uip_len
#define UIP_ACKDATA 1 /* Signifies that the outstanding data was
acked and the application should send
out new data instead of retransmitting
the last data. */
#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent
us new data. */
#define UIP_REXMIT 4 /* Tells the application to retransmit the
data that was last sent. */
#define UIP_POLL 8 /* Used for polling the application, to
check if the application has data that
it wants to send. */
#define UIP_CLOSED 16 /* The remote host has closed the
connection, thus the connection has
gone away. */
#define UIP_ACCEPT 32 /* We have got a connection from a remote
host and have set up a new connection
for it. */
/* uip_close():
*
* Close the current connection.
*/
#define uip_close() (uip_flags = UIP_CLOSE)
#define UIP_ABORT 64
#define UIP_CLOSE 128
/* uip_abort():
*
* Abort the current connection.
*/
#define uip_abort() (uip_flags = UIP_ABORT)
/* uip_stop():
*
* Close our receiver's window so that we stop receiving data for the
* current connection.
*/
#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED)
/* uip_stopped():
*
* Find out if the current connection has been previously stopped.
*/
#define uip_stopped() (uip_conn->tcpstateflags & UIP_STOPPED)
/* uip_restart():
*
* Open the window again so that we start receiving data for the
* current connection.
*/
#define uip_restart() do { uip_flags |= UIP_NEWDATA; \
uip_conn->tcpstateflags &= ~UIP_STOPPED; \
} while(0)
/* The following flags are passed as an argument to the uip_process()
function. They are used to distinguish between the two cases where
uip_process() is called. It can be called either because we have
incoming data that should be processed, or because the periodic
timer has fired. */
/* uIP tests that can be made to determine in what state the current
connection is, and what the application function should do. */
#define UIP_DATA 1 /* Tells uIP that there is incoming data in
the uip_buf buffer. The length of the
data is stored in the global variable
uip_len. */
#define UIP_TIMER 2 /* Tells uIP that the periodic timer has
fired. */
/* uip_newdata():
*
* Will reduce to non-zero if there is new data for the application
* present at the uip_appdata pointer. The size of the data is
* avaliable through the uip_len variable.
*/
#define uip_newdata() (uip_flags & UIP_NEWDATA)
/* uip_acked():
*
* Will reduce to non-zero if the previously sent data has been
* acknowledged by the remote host. This means that the application
* can send new data. uip_reset_acked() can be used to reset the acked
* flag.
*/
#define uip_acked() (uip_flags & UIP_ACKDATA)
#define uip_reset_acked() (uip_flags &= ~UIP_ACKDATA)
/* uip_connected():
*
* Reduces to non-zero if the current connection has been connected to
* a remote host. This will happen both if the connection has been
* actively opened (with uip_connect()) or passively opened (with
* uip_listen()).
*/
#define uip_connected() (uip_flags & UIP_CONNECTED)
/* uip_closed():
*
* Is non-zero if the connection has been closed by the remote
* host. The application may do the necessary clean-ups.
*/
#define uip_closed() (uip_flags & UIP_CLOSE)
/* uip_aborted():
*
* Non-zero if the current connection has been aborted (reset) by the
* remote host.
*/
#define uip_aborted() (uip_flags & UIP_ABORT)
/* uip_timedout():
*
* Non-zero if the current connection has been aborted due to too many
* retransmissions.
*/
#define uip_timedout() (uip_flags & UIP_TIMEDOUT)
/* uip_rexmit():
*
* Reduces to non-zero if the previously sent data has been lost in
* the network, and the application should retransmit it. The
* application should set the uip_appdata buffer and the uip_len
* variable just as it did the last time this data was to be
* transmitted.
*/
#define uip_rexmit() (uip_flags & UIP_REXMIT)
/* uip_poll():
*
* Is non-zero if the reason the application is invoked is that the
* current connection has been idle for a while and should be
* polled.
*/
#define uip_poll() (uip_flags & UIP_POLL)
/* uip_mss():
*
* Gives the current maxium segment size (MSS) of the current
* connection.
*/
#define uip_mss() (uip_conn->mss)
/* uIP convenience and converting functions. */
/* uip_ipaddr(&ipaddr, addr0,addr1,addr2,addr3):
*
* Packs an IP address into a two element 16-bit array. Such arrays
* are used to represent IP addresses in uIP.
*/
#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
(addr)[0] = htons(((addr0) << 8) | (addr1)); \
(addr)[1] = htons(((addr2) << 8) | (addr3)); \
} while(0)
/* htons(), ntohs():
*
* Macros for converting 16-bit quantities between host and network
* byte order.
*/
#ifndef htons
# if BYTE_ORDER == BIG_ENDIAN
# define htons(n) (n)
@@ -175,44 +242,88 @@ struct uip_conn {
#define ntohs(n) htons(n)
#define CLOSED 0
#define SYN_RCVD 1
#define ESTABLISHED 2
#define FIN_WAIT_1 3
#define FIN_WAIT_2 4
#define CLOSING 5
#define TIME_WAIT 6
#define LAST_ACK 7
#define TS_MASK 7
/*-----------------------------------------------------------------------------------*/
/* The following global variables are used for passing parameters
* between uIP, the network device driver and the application. */
/*-----------------------------------------------------------------------------------*/
/* u8_t uip_buf[UIP_BUFSIZE]:
*
* The uip_buf array is used to hold incoming and outgoing
* packets. The device driver fills this with incoming packets.
*/
extern u8_t uip_buf[UIP_BUFSIZE];
/* u8_t *uip_appdata:
*
* This pointer points to the application data when the application is
* called. If the application wishes to send data, this is where the
* application should write it. The application can also point this to
* another location.
*/
extern volatile u8_t *uip_appdata;
/* u[8|16]_t uip_len:
*
* When the application is called, uip_len contains the length of any
* new data that has been received from the remote host. The
* application should set this variable to the size of any data that
* the application wishes to send. When the network device driver
* output function is called, uip_len should contain the length of the
* outgoing packet.
*/
#if UIP_BUFSIZE > 255
extern volatile u16_t uip_len;
#else
extern volatile u8_t uip_len;
#endif /* UIP_BUFSIZE > 255 */
/* struct uip_conn *uip_conn:
*
* When the application is called, uip_conn will point to the current
* conntection, the one that should be processed by the
* application. The uip_conns[] array is a list containing all
* connections.
*/
extern struct uip_conn *uip_conn;
extern struct uip_conn uip_conns[UIP_CONNS];
/* struct uip_conn:
*
* The uip_conn structure is used for identifying a connection. All
* but one field in the structure are to be considered read-only by an
* application. The only exception is the appstate field whos purpose
* is to let the application store application-specific state (e.g.,
* file pointers) for the connection. The size of this field is
* configured in the "uipopt.h" header file.
*/
struct uip_conn {
u8_t tcpstateflags; /* TCP state and flags. */
u16_t lport, rport; /* The local and the remote port. */
u16_t ripaddr[2]; /* The IP address of the remote peer. */
u8_t rcv_nxt[4]; /* The sequence number that we expect to receive
next. */
u8_t snd_nxt[4]; /* The sequence number that was last sent by
us. */
u8_t ack_nxt[4]; /* The sequence number that should be ACKed by
next ACK from peer. */
#if UIP_TCP_MSS > 255
u16_t mss; /* Maximum segment size for the connection. */
#else
u8_t mss;
#endif /* UIP_TCP_MSS */
u8_t timer; /* The retransmission timer. */
u8_t nrtx; /* Counts the number of retransmissions for a
particular segment. */
#define UIP_OUTSTANDING 8
typedef struct {
/* IP header. */
u8_t vhl,
tos,
len[2],
ipid[2],
ipoffset[2],
ttl,
proto;
u16_t ipchksum;
u16_t srcipaddr[2],
destipaddr[2];
/* TCP header. */
u16_t srcport,
destport;
u8_t seqno[4],
ackno[4],
tcpoffset,
flags,
wnd[2];
u16_t tcpchksum,
urgp;
u8_t optdata[4];
} uip_tcpip_hdr;
u8_t appstate[UIP_APPSTATE_SIZE];
};
/* struct uip_stats:
*
* Contains statistics about the TCP/IP stack.
*/
struct uip_stats {
struct {
u16_t drop;
@@ -253,7 +364,117 @@ struct uip_stats {
extern struct uip_stats uip_stat;
extern struct uip_conn uip_conns[UIP_CONNS];
/*-----------------------------------------------------------------------------------*/
/* All the stuff below this point is internal to uIP and should not be
* used directly by an application or by a device driver.
*/
/*-----------------------------------------------------------------------------------*/
/* u8_t uip_flags:
*
* When the application is called, uip_flags will contain the flags
* that are defined in this file. Please read below for more
* infomation.
*/
extern volatile u8_t uip_flags;
/* The following flags may be set in the global variable uip_flags
before calling the application callback. The UIP_ACKDATA and
UIP_NEWDATA flags may both be set at the same time, whereas the
others are mutualy exclusive. Note that these flags should *NOT* be
accessed directly, but through the uip_has and uip_in
functions/macros. */
#define UIP_ACKDATA 1 /* Signifies that the outstanding data was
acked and the application should send
out new data instead of retransmitting
the last data. */
#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent
us new data. */
#define UIP_REXMIT 4 /* Tells the application to retransmit the
data that was last sent. */
#define UIP_POLL 8 /* Used for polling the application, to
check if the application has data that
it wants to send. */
#define UIP_CLOSE 16 /* The remote host has closed the
connection, thus the connection has
gone away. Or the application signals
that it wants to close the
connection. */
#define UIP_ABORT 32 /* The remote host has aborted the
connection, thus the connection has
gone away. Or the application signals
that it wants to abort the
connection. */
#define UIP_CONNECTED 64 /* We have got a connection from a remote
host and have set up a new connection
for it, or an active connection has
been successfully established. */
#define UIP_TIMEDOUT 128 /* The connection has been aborted due to
too many retransmissions. */
/* uip_process(flag):
*
* The actual uIP function which does all the work.
*/
void uip_process(u8_t flag);
/* The following flags are passed as an argument to the uip_process()
function. They are used to distinguish between the two cases where
uip_process() is called. It can be called either because we have
incoming data that should be processed, or because the periodic
timer has fired. */
#define UIP_DATA 1 /* Tells uIP that there is incoming data in
the uip_buf buffer. The length of the
data is stored in the global variable
uip_len. */
#define UIP_TIMER 2 /* Tells uIP that the periodic timer has
fired. */
/* The TCP states used in the uip_conn->tcpstateflags. */
#define CLOSED 0
#define SYN_RCVD 1
#define SYN_SENT 2
#define ESTABLISHED 3
#define FIN_WAIT_1 4
#define FIN_WAIT_2 5
#define CLOSING 6
#define TIME_WAIT 7
#define LAST_ACK 8
#define TS_MASK 15
#define UIP_OUTSTANDING 16
#define UIP_STOPPED 32
/* The TCP and IP headers. */
typedef struct {
/* IP header. */
u8_t vhl,
tos,
len[2],
ipid[2],
ipoffset[2],
ttl,
proto;
u16_t ipchksum;
u16_t srcipaddr[2],
destipaddr[2];
/* TCP header. */
u16_t srcport,
destport;
u8_t seqno[4],
ackno[4],
tcpoffset,
flags,
wnd[2];
u16_t tcpchksum,
urgp;
u8_t optdata[4];
} uip_tcpip_hdr;
#endif /* __UIP_H__ */

326
uip/uip_arp.c Normal file
View File

@@ -0,0 +1,326 @@
/*
* Copyright (c) 2001-2002, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Adam Dunkels.
* 4. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uip_arp.c,v 1.3 2002/01/13 21:12:41 adam Exp $
*
*/
#include "uip_arp.h"
struct arp_hdr {
struct uip_eth_hdr ethhdr;
u16_t hwtype;
u16_t protocol;
u8_t hwlen;
u8_t protolen;
u16_t opcode;
struct uip_eth_addr shwaddr;
u16_t sipaddr[2];
struct uip_eth_addr dhwaddr;
u16_t dipaddr[2];
};
struct ethip_hdr {
struct uip_eth_hdr ethhdr;
/* IP header. */
u8_t vhl,
tos,
len[2],
ipid[2],
ipoffset[2],
ttl,
proto;
u16_t ipchksum;
u16_t srcipaddr[2],
destipaddr[2];
};
#define ARP_REQUEST 1
#define ARP_REPLY 2
#define ARP_HWTYPE_ETH 1
struct arp_entry {
u16_t ipaddr[2];
struct uip_eth_addr ethaddr;
u8_t time;
};
static const struct uip_eth_addr ethaddr = {{UIP_ETHADDR0,
UIP_ETHADDR1,
UIP_ETHADDR2,
UIP_ETHADDR3,
UIP_ETHADDR4,
UIP_ETHADDR5}};
static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
static u16_t ipaddr[2];
static u8_t i, c;
static u8_t time;
static u8_t tmpage;
#define BUF ((struct arp_hdr *)&uip_buf[0])
#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
/*-----------------------------------------------------------------------------------*/
void
uip_arp_init(void)
{
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
arp_table[i].ipaddr[0] =
arp_table[i].ipaddr[1] = 0;
}
}
/*-----------------------------------------------------------------------------------*/
void
uip_arp_timer(void)
{
++time;
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
if((arp_table[i].ipaddr[0] | arp_table[i].ipaddr[1]) != 0 &&
time - arp_table[i].time >= UIP_ARP_MAXAGE) {
arp_table[i].ipaddr[0] =
arp_table[i].ipaddr[1] = 0;
}
}
}
/*-----------------------------------------------------------------------------------*/
static void
uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
{
/* Walk through the ARP mapping table and try to find an entry to
update. If none is found, the IP -> MAC address mapping is
inserted in the ARP table. */
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
/* Only check those entries that are actually in use. */
if(arp_table[i].ipaddr[0] != 0 &&
arp_table[i].ipaddr[1] != 0) {
/* Check if the source IP address of the incoming packet matches
the IP address in this ARP table entry. */
if(ipaddr[0] == arp_table[i].ipaddr[0] &&
ipaddr[1] == arp_table[i].ipaddr[1]) {
/* An old entry found, update this and return. */
for(c = 0; c < 6; ++c) {
arp_table[i].ethaddr.addr[c] = ethaddr->addr[c];
}
arp_table[i].time = time;
return;
}
}
}
/* If we get here, no existing ARP table entry was found, so we
create one. */
/* First, we try to find an unused entry in the ARP table. */
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
if(arp_table[i].ipaddr[0] == 0 &&
arp_table[i].ipaddr[1] == 0)
break;
}
/* If no unused entry is found, we try to find the oldest entry and
throw it away. */
if(i == UIP_ARPTAB_SIZE) {
tmpage = 0;
c = 0;
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
if(time - arp_table[i].time > tmpage) {
tmpage = time - arp_table[i].time;
c = i;
}
}
i = c;
}
/* Now, i is the ARP table entry which we will fill with the new
information. */
arp_table[i].ipaddr[0] = ipaddr[0];
arp_table[i].ipaddr[1] = ipaddr[1];
for(c = 0; c < 6; ++c) {
arp_table[i].ethaddr.addr[c] = ethaddr->addr[c];
}
arp_table[i].time = time;
}
/*-----------------------------------------------------------------------------------*/
void
uip_arp_ipin(void)
{
/* Only insert/update an entry if the source IP address of the
incoming IP packet comes from a host on the local network. */
if((IPBUF->srcipaddr[0] & htons((UIP_NETMASK0 << 8) | UIP_NETMASK1)) !=
(htons((UIP_IPADDR0 << 8) | UIP_IPADDR1)
& htons((UIP_NETMASK0 << 8) | UIP_NETMASK1)))
return;
if((IPBUF->srcipaddr[1] & htons((UIP_NETMASK2 << 8) | UIP_NETMASK3)) !=
(htons((UIP_IPADDR2 << 8) | UIP_IPADDR3)
& htons((UIP_NETMASK2 << 8) | UIP_NETMASK3)))
return;
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
return;
}
/*-----------------------------------------------------------------------------------*/
void
uip_arp_arpin(void)
{
if(uip_len < sizeof(struct arp_hdr)) {
uip_len = 0;
return;
}
uip_len = 0;
switch(BUF->opcode) {
case htons(ARP_REQUEST):
/* ARP request. If it asked for our address, we send out a
reply. */
if(BUF->dipaddr[0] == htons((UIP_IPADDR0 << 8) | UIP_IPADDR1) &&
BUF->dipaddr[1] == htons((UIP_IPADDR2 << 8) | UIP_IPADDR3)) {
/* The reply opcode is 2. */
BUF->opcode = htons(2);
BUF->dhwaddr = BUF->shwaddr;
for(c = 0; c < 6; ++c) {
BUF->shwaddr.addr[c] =
BUF->ethhdr.src.addr[c] = ethaddr.addr[c];
BUF->ethhdr.dest.addr[c] = BUF->dhwaddr.addr[c];
}
BUF->dipaddr[0] = BUF->sipaddr[0];
BUF->dipaddr[1] = BUF->sipaddr[1];
BUF->sipaddr[0] = htons((UIP_IPADDR0 << 8) | UIP_IPADDR1);
BUF->sipaddr[1] = htons((UIP_IPADDR2 << 8) | UIP_IPADDR3);
BUF->ethhdr.type = htons(UIP_ETHTYPE_ARP);
uip_len = sizeof(struct arp_hdr);
}
break;
case htons(ARP_REPLY):
/* ARP reply. We insert or update the ARP table if it was meant
for us. */
if(BUF->dipaddr[0] == htons((UIP_IPADDR0 << 8) | UIP_IPADDR1) &&
BUF->dipaddr[1] == htons((UIP_IPADDR2 << 8) | UIP_IPADDR3)) {
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
}
break;
}
return;
}
/*-----------------------------------------------------------------------------------*/
void
uip_arp_out(void)
{
/* Find the destination IP address in the ARP table and construct
the Ethernet header. If the destination IP addres isn't on the
local network, we use the default router's IP address instead.
If not ARP table entry is found, we overwrite the original IP
packet with an ARP request for the IP address. */
/* Check if the destination address is on the local network. */
if((IPBUF->destipaddr[0] & htons((UIP_NETMASK0 << 8) | UIP_NETMASK1)) !=
(htons((UIP_IPADDR0 << 8) | UIP_IPADDR1)
& htons((UIP_NETMASK0 << 8) | UIP_NETMASK1)) ||
(IPBUF->destipaddr[1] & htons((UIP_NETMASK2 << 8) | UIP_NETMASK3)) !=
(htons((UIP_IPADDR2 << 8) | UIP_IPADDR3)
& htons((UIP_NETMASK2 << 8) | UIP_NETMASK3))) {
/* Destination address was not on the local network, so we need to
use the default router's IP address instead of the destination
address when determining the MAC address. */
ipaddr[0] = htons((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1);
ipaddr[1] = htons((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3);
} else {
/* Else, we use the destination IP address. */
ipaddr[0] = IPBUF->destipaddr[0];
ipaddr[1] = IPBUF->destipaddr[1];
}
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
if(ipaddr[0] == arp_table[i].ipaddr[0] &&
ipaddr[1] == arp_table[i].ipaddr[1])
break;
}
if(i == UIP_ARPTAB_SIZE) {
/* The destination address was not in our ARP table, so we
overwrite the IP packet with an ARP request. */
for(c = 0; c < 6; ++c) {
BUF->ethhdr.dest.addr[c] = 0xff; /* Broadcast ARP request. */
BUF->ethhdr.src.addr[c] =
BUF->shwaddr.addr[c] = ethaddr.addr[c];
BUF->dhwaddr.addr[c] = 0;
}
BUF->dipaddr[0] = ipaddr[0];
BUF->dipaddr[1] = ipaddr[1];
BUF->sipaddr[0] = htons((UIP_IPADDR0 << 8) | UIP_IPADDR1);
BUF->sipaddr[1] = htons((UIP_IPADDR2 << 8) | UIP_IPADDR3);
BUF->opcode = htons(ARP_REQUEST); /* ARP request. */
BUF->hwtype = htons(ARP_HWTYPE_ETH);
BUF->protocol = htons(UIP_ETHTYPE_IP);
BUF->hwlen = 6;
BUF->protolen = 4;
BUF->ethhdr.type = htons(UIP_ETHTYPE_ARP);
uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
uip_len = sizeof(struct arp_hdr);
return;
}
/* Build an ethernet header. */
for(c = 0; c < 6; ++c) {
IPBUF->ethhdr.dest.addr[c] = arp_table[i].ethaddr.addr[c];
IPBUF->ethhdr.src.addr[0] = ethaddr.addr[c];
}
IPBUF->ethhdr.type = htons(UIP_ETHTYPE_IP);
uip_len += sizeof(struct uip_eth_hdr);
}
/*-----------------------------------------------------------------------------------*/

91
uip/uip_arp.h Normal file
View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) 2001-2002, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Adam Dunkels.
* 4. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uip_arp.h,v 1.2 2002/01/11 18:54:35 adam Exp $
*
*/
#ifndef __UIP_ARP_H__
#define __UIP_ARP_H__
#include "uip.h"
struct uip_eth_addr {
u8_t addr[6];
};
struct uip_eth_hdr {
struct uip_eth_addr dest;
struct uip_eth_addr src;
u16_t type;
};
#define UIP_ETHTYPE_ARP 0x0806
#define UIP_ETHTYPE_IP 0x0800
/* The uip_arp_init() function must be called before any of the other
ARP functions. */
void uip_arp_init(void);
/* The uip_arp_ipin() function should be called whenever an IP packet
arrives from the Ethernet. This function refreshes the ARP table or
inserts a new mapping if none exists. The function assumes that an
IP packet with an Ethernet header is present in the uip_buf buffer
and that the length of the packet is in the uip_len variable. */
void uip_arp_ipin(void);
/* The uip_arp_arpin() should be called when an ARP packet is received
by the Ethernet driver. This function also assumes that the
Ethernet frame is present in the uip_buf buffer. When the
uip_arp_arpin() function returns, the contents of the uip_buf
buffer should be sent out on the Ethernet if the uip_len variable
is > 0. */
void uip_arp_arpin(void);
/* The uip_arp_out() function should be called when an IP packet
should be sent out on the Ethernet. This function creates an
Ethernet header before the IP header in the uip_buf buffer. The
Ethernet header will have the correct Ethernet MAC destination
address filled in if an ARP table entry for the destination IP
address (or the IP address of the default router) is present. If no
such table entry is found, the IP packet is overwritten with an ARP
request and we rely on TCP to retransmit the packet that was
overwritten. In any case, the uip_len variable holds the length of
the Ethernet frame that should be transmitted. */
void uip_arp_out(void);
/* The uip_arp_timer() function should be called every ten seconds. It
is responsible for flushing old entries in the ARP table. */
void uip_arp_timer(void);
#endif /* __UIP_ARP_H__ */

View File

@@ -30,29 +30,34 @@
#
# This file is part of the uIP TCP/IP stack.
#
# $Id: Makefile,v 1.6 2001/11/20 20:49:45 adam Exp $
# $Id: Makefile,v 1.2 2002/01/10 07:34:41 adam Exp $
#
CC=gcc
CFLAGS=-Wall -g -fpack-struct -I../uip -I. -I../apps/httpd
CFLAGS=-Wall -g -fpack-struct -I../uip -I. -I../apps/httpd -O1
%.o:
$(CC) $(CFLAGS) -c $(<:.o=.c)
uip: uip.o uip_arch.o tundev.o httpd.o main.o fs.o cgi.o
uip: uip.o uip_arch.o tapdev.o httpd.o main.o fs.o uip_arp.o cgi.o
httpd.o: ../apps/httpd/httpd.c ../apps/httpd/httpd.h ../uip/uip.h \
uipopt.h ../apps/httpd/fs.h
cgi.o: ../apps/httpd/cgi.c ../apps/httpd/cgi.h
cgi.o: ../apps/httpd/cgi.c ../uip/uip.h uipopt.h ../apps/httpd/httpd.h \
../apps/httpd/cgi.h ../apps/httpd/fs.h
fs.o: ../apps/httpd/fs.c ../uip/uip.h uipopt.h ../apps/httpd/httpd.h \
../apps/httpd/fs.h ../apps/httpd/fsdata.h \
../apps/httpd/fsdata.c
tundev.o: tundev.c ../uip/uip.h
main.o: main.c ../uip/uip.h uipopt.h ../apps/httpd/httpd.h tundev.h
tapdev.o: tapdev.c uipopt.h
main.o: main.c ../uip/uip.h uipopt.h ../apps/httpd/httpd.h \
tapdev.h
uip_arch.o: uip_arch.c uip_arch.h ../uip/uip.h uipopt.h \
../apps/httpd/httpd.h
uip.o: ../uip/uip.c uipopt.h ../apps/httpd/httpd.h
../apps/httpd/httpd.h
uip.o: ../uip/uip.c ../uip/uip.h uipopt.h ../apps/httpd/httpd.h
uip_arp.o: ../uip/uip_arp.c ../uip/uip_arp.h ../uip/uip.h uipopt.h \
../apps/httpd/httpd.h
clean:
rm -f *.o *~ *core uip

View File

@@ -31,31 +31,36 @@
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: main.c,v 1.2 2001/09/14 23:02:25 adam Exp $
* $Id: main.c,v 1.2 2002/01/13 21:12:41 adam Exp $
*
*/
#include "uip.h"
#include "tundev.h"
#include "uip_arp.h"
#include "tapdev.h"
#include "httpd.h"
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
/*-----------------------------------------------------------------------------------*/
int
main(void)
{
u8_t i;
tundev_init();
u8_t i, arptimer;
tapdev_init();
uip_init();
httpd_init();
arptimer = 0;
while(1) {
/* Let the tundev network device driver read an entire IP packet
/* Let the tapdev network device driver read an entire IP packet
into the uip_buf. If it must wait for more than 0.5 seconds, it
will return with the return value 0. If so, we know that it is
time to call upon the uip_periodic(). Otherwise, the tundev has
time to call upon the uip_periodic(). Otherwise, the tapdev has
received an IP packet that is to be processed by uIP. */
uip_len = tundev_read();
uip_len = tapdev_read();
if(uip_len == 0) {
for(i = 0; i < UIP_CONNS; i++) {
uip_periodic(i);
@@ -63,17 +68,37 @@ main(void)
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if(uip_len > 0) {
tundev_send();
uip_arp_out();
tapdev_send();
}
}
} else {
/* Call the ARP timer function every 10 seconds. */
if(++arptimer == 20) {
uip_arp_timer();
arptimer = 0;
}
uip_process(UIP_DATA);
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if(uip_len > 0) {
tundev_send();
} else {
if(BUF->type == htons(UIP_ETHTYPE_IP)) {
uip_arp_ipin();
uip_len -= sizeof(struct uip_eth_hdr);
uip_input();
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if(uip_len > 0) {
uip_arp_out();
tapdev_send();
}
} else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
uip_arp_arpin();
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if(uip_len > 0) {
tapdev_send();
}
}
}

168
unix/tapdev.c Normal file
View File

@@ -0,0 +1,168 @@
/*
* Copyright (c) 2001, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: tapdev.c,v 1.2 2002/01/11 18:54:35 adam Exp $
*/
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/socket.h>
#ifdef linux
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#define DEVTAP "/dev/net/tun"
#else /* linux */
#define DEVTAP "/dev/tap0"
#endif /* linux */
#include "uip.h"
static int drop = 0;
static int fd;
static unsigned long lasttime;
static struct timezone tz;
/*-----------------------------------------------------------------------------------*/
void
tapdev_init(void)
{
char buf[1024];
fd = open(DEVTAP, O_RDWR);
if(fd == -1) {
perror("tapdev: tapdev_init: open");
exit(1);
}
#ifdef linux
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
if (ioctl(tapif->fd, TUNSETIFF, (void *) &ifr) < 0) {
perror(buf);
exit(1);
}
}
#endif /* Linux */
snprintf(buf, sizeof(buf), "ifconfig tap0 inet %d.%d.%d.%d",
UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3);
system(buf);
lasttime = 0;
}
/*-----------------------------------------------------------------------------------*/
unsigned int
tapdev_read(void)
{
fd_set fdset;
struct timeval tv, now;
int ret;
if(lasttime >= 500000) {
lasttime = 0;
return 0;
}
tv.tv_sec = 0;
tv.tv_usec = 500000 - lasttime;
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
gettimeofday(&now, &tz);
ret = select(fd + 1, &fdset, NULL, NULL, &tv);
if(ret == 0) {
lasttime = 0;
return 0;
}
ret = read(fd, uip_buf, UIP_BUFSIZE);
if(ret == -1) {
perror("tap_dev: tapdev_read: read");
}
gettimeofday(&tv, &tz);
lasttime += (tv.tv_sec - now.tv_sec) * 1000000 + (tv.tv_usec - now.tv_usec);
/* printf("--- tap_dev: tapdev_read: read %d bytes\n", ret);*/
/* {
int i;
for(i = 0; i < 20; i++) {
printf("%x ", uip_buf[i]);
}
printf("\n");
}*/
/* check_checksum(uip_buf, ret);*/
return ret;
}
/*-----------------------------------------------------------------------------------*/
void
tapdev_send(void)
{
int ret;
struct iovec iov[2];
/* printf("tapdev_send: sending %d bytes\n", size);*/
/* check_checksum(uip_buf, size);*/
/* drop++;
if(drop % 8 == 7) {
printf("Dropped a packet!\n");
return;
}*/
iov[0].iov_base = uip_buf;
iov[0].iov_len = 40 + UIP_LLH_LEN;
iov[1].iov_base = (char *)uip_appdata;
iov[1].iov_len = uip_len - 40 + UIP_LLH_LEN;
ret = writev(fd, iov, 2);
if(ret == -1) {
perror("tap_dev: tapdev_send: writev");
exit(1);
}
}
/*-----------------------------------------------------------------------------------*/

View File

@@ -31,15 +31,15 @@
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: tundev.h,v 1.2 2001/09/14 23:02:25 adam Exp $
* $Id: tapdev.h,v 1.1 2002/01/10 06:22:56 adam Exp $
*
*/
#ifndef __TUNDEV_H__
#define __TUNDEV_H__
#ifndef __TAPDEV_H__
#define __TAPDEV_H__
void tundev_init(void);
unsigned int tundev_read(void);
void tundev_send(void);
void tapdev_init(void);
unsigned int tapdev_read(void);
void tapdev_send(void);
#endif /* __TUNDEV_H__ */
#endif /* __TAPDEV_H__ */

View File

@@ -31,7 +31,7 @@
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uip_arch.c,v 1.8 2001/11/13 06:46:05 adam Exp $
* $Id: uip_arch.c,v 1.1 2002/01/10 06:22:56 adam Exp $
*
*/

View File

@@ -31,7 +31,7 @@
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uip_arch.h,v 1.2 2001/09/14 23:02:25 adam Exp $
* $Id: uip_arch.h,v 1.1 2002/01/10 06:22:56 adam Exp $
*
*/

189
unix/uipopt.h Normal file
View File

@@ -0,0 +1,189 @@
/*
* Copyright (c) 2001, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Adam Dunkels.
* 4. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uipopt.h,v 1.5 2002/01/13 21:12:41 adam Exp $
*
*/
#ifndef __UIPOPT_H__
#define __UIPOPT_H__
/* This file is used for tweaking various configuration options for
uIP. You should make a copy of this file into one of your project's
directories instead of editing this example "uipopt.h" file that
comes with the uIP distribution. */
/*-----------------------------------------------------------------------------------*/
/* First, two typedefs that may have to be tweaked for your particular
compiler. The uX_t types are unsigned integer types, where the X is
the number of bits in the integer type. Most compilers use
"unsigned char" and "unsigned short" for those two,
respectively. */
typedef unsigned char u8_t;
typedef unsigned short u16_t;
/*-----------------------------------------------------------------------------------*/
/* The configuration options for a specific node. This includes IP
* address, netmask and default router as well as the Ethernet
* address. The netmask, default router and Ethernet address are
* appliciable only if uIP should be run over Ethernet.
*
* All of these should be changed to suit your project.
*/
/* UIP_IPADDR: The IP address of this uIP node. */
#define UIP_IPADDR0 192
#define UIP_IPADDR1 168
#define UIP_IPADDR2 0
#define UIP_IPADDR3 2
/* UIP_NETMASK: The netmask. */
#define UIP_NETMASK0 255
#define UIP_NETMASK1 255
#define UIP_NETMASK2 255
#define UIP_NETMASK3 0
/* UIP_DRIPADDR: IP address of the default router. */
#define UIP_DRIPADDR0 192
#define UIP_DRIPADDR1 168
#define UIP_DRIPADDR2 0
#define UIP_DRIPADDR3 1
/* UIP_ETHADDR: The Ethernet address. */
#define UIP_ETHADDR0 0x00
#define UIP_ETHADDR1 0xbd
#define UIP_ETHADDR2 0x3b
#define UIP_ETHADDR3 0x33
#define UIP_ETHADDR4 0x05
#define UIP_ETHADDR5 0x71
/*-----------------------------------------------------------------------------------*/
/* The following options are used to configure application specific
* setting such as how many TCP ports that should be avaliable and if
* the uIP should be configured to support active opens.
*
* These should probably be tweaked to suite your project.
*/
/* Include the header file for the application program that should be
used. If you don't use the example web server, you should change
this. */
#include "httpd.h"
/* UIP_ACTIVE_OPEN: Determines if support for opening connections from
uIP should be compiled in. If this isn't needed for your
application, don't turn it on. (A web server doesn't need this, for
instance.) */
#define UIP_ACTIVE_OPEN 0
/* UIP_CONNS: The maximum number of simultaneously active
connections. */
#define UIP_CONNS 10
/* UIP_LISTENPORTS: The maximum number of simultaneously listening TCP
ports. For a web server, 1 is enough here. */
#define UIP_LISTENPORTS 10
/* UIP_BUFSIZE: The size of the buffer that holds incoming and
outgoing packets. */
#define UIP_BUFSIZE 180
/* UIP_STATISTICS: Determines if statistics support should be compiled
in. The statistics is useful for debugging and to show the user. */
#define UIP_STATISTICS 0
/* UIP_LOGGING: Determines if logging of certain events should be
compiled in. Useful mostly for debugging. The function uip_log(char
*msg) must be implemented to suit your architecture if logging is
turned on. */
#define UIP_LOGGING 0
/* UIP_LLH_LEN: The link level header length; this is the offset into
the uip_buf where the IP header can be found. For Ethernet, this
should be set to 14. For SLIP, this should be set to 0. */
#define UIP_LLH_LEN 14
/*-----------------------------------------------------------------------------------*/
/* The following configuration options can be tweaked for your
* project, but you are probably safe to use the default values. The
* options are listed in order of tweakability.
*/
/* UIP_ARPTAB_SIZE: The size of the ARP table - use a larger value if
this uIP node will have many connections from the local network. */
#define UIP_ARPTAB_SIZE 8
/* The maxium age of ARP table entries measured in 10ths of
seconds. An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
default). */
#define UIP_ARP_MAXAGE 120
/* UIP_RTO: The retransmission timeout counted in timer pulses (i.e.,
the speed of the periodic timer, usually one second). */
#define UIP_RTO 3
/* UIP_MAXRTX: The maximum number of times a segment should be
retransmitted before the connection should be aborted. */
#define UIP_MAXRTX 8
/* UIP_TCP_MSS: The TCP maximum segment size. This should be set to
at most UIP_BUFSIZE - UIP_LLH_LEN - 40. */
#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - 40)
/* UIP_TTL: The IP TTL (time to live) of IP packets sent by uIP. */
#define UIP_TTL 255
/* UIP_TIME_WAIT_TIMEOUT: How long a connection should stay in the
TIME_WAIT state. Has no real implication, so it should be left
untouched. */
#define UIP_TIME_WAIT_TIMEOUT 120
/*-----------------------------------------------------------------------------------*/
/* This is where you configure if your CPU architecture is big or
* little endian. Most CPUs today are little endian. The most notable
* exception are the Motorolas which are big endian. Tweak the
* definition of the BYTE_ORDER macro to configure uIP for your
* project.
*/
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 3412
#endif /* LITTLE_ENDIAN */
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 1234
#endif /* BIGE_ENDIAN */
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif /* BYTE_ORDER */
#endif /* __UIPOPT_H__ */