Add support for Android

This commit is contained in:
switch_st 2018-06-12 02:59:13 +08:00
parent 63c8b67ab9
commit 463538a8df
101 changed files with 15343 additions and 2 deletions

367
android/edge_android.c Normal file
View File

@ -0,0 +1,367 @@
/**
* (C) 2007-18 - ntop.org and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not see see <http://www.gnu.org/licenses/>
*
*/
#include "../n2n.h"
#ifdef __ANDROID_NDK__
#include "edge_android.h"
#include <tun2tap/tun2tap.h>
#define N2N_NETMASK_STR_SIZE 16 /* dotted decimal 12 numbers + 3 dots */
#define N2N_MACNAMSIZ 18 /* AA:BB:CC:DD:EE:FF + NULL*/
#define N2N_IF_MODE_SIZE 16 /* static | dhcp */
/* *************************************************** */
#if defined(DUMMY_ID_00001) /* Disabled waiting for config option to enable it */
static char gratuitous_arp[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Dest mac */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */
0x08, 0x06, /* ARP */
0x00, 0x01, /* Ethernet */
0x08, 0x00, /* IP */
0x06, /* Hw Size */
0x04, /* Protocol Size */
0x00, 0x01, /* ARP Request */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */
0x00, 0x00, 0x00, 0x00, /* Src IP */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Target mac */
0x00, 0x00, 0x00, 0x00 /* Target IP */
};
/* ************************************** */
/** Build a gratuitous ARP packet for a /24 layer 3 (IP) network. */
static int build_gratuitous_arp(char *buffer, uint16_t buffer_len) {
if(buffer_len < sizeof(gratuitous_arp)) return(-1);
memcpy(buffer, gratuitous_arp, sizeof(gratuitous_arp));
memcpy(&buffer[6], device.mac_addr, 6);
memcpy(&buffer[22], device.mac_addr, 6);
memcpy(&buffer[28], &device.ip_addr, 4);
/* REVISIT: BbMaj7 - use a real netmask here. This is valid only by accident
* for /24 IPv4 networks. */
buffer[31] = 0xFF; /* Use a faked broadcast address */
memcpy(&buffer[38], &device.ip_addr, 4);
return(sizeof(gratuitous_arp));
}
/* ************************************** */
/** Called from update_supernode_reg to periodically send gratuitous ARP
* broadcasts. */
static void send_grat_arps(n2n_edge_t * eee,) {
char buffer[48];
size_t len;
traceEvent(TRACE_NORMAL, "Sending gratuitous ARP...");
len = build_gratuitous_arp(buffer, sizeof(buffer));
send_packet2net(eee, buffer, len);
send_packet2net(eee, buffer, len); /* Two is better than one :-) */
}
#endif /* #if defined(DUMMY_ID_00001) */
/* ***************************************************** */
/** Find the address and IP mode for the tuntap device.
*
* s is one of these forms:
*
* <host> := <hostname> | A.B.C.D
*
* <host> | static:<host> | dhcp:<host>
*
* If the mode is present (colon required) then fill ip_mode with that value
* otherwise do not change ip_mode. Fill ip_mode with everything after the
* colon if it is present; or s if colon is not present.
*
* ip_add and ip_mode are NULL terminated if modified.
*
* return 0 on success and -1 on error
*/
static int scan_address(char * ip_addr, size_t addr_size,
char * ip_mode, size_t mode_size,
const char * s) {
int retval = -1;
char * p;
if((NULL == s) || (NULL == ip_addr))
{
return -1;
}
memset(ip_addr, 0, addr_size);
p = strpbrk(s, ":");
if(p)
{
/* colon is present */
if(ip_mode)
{
size_t end=0;
memset(ip_mode, 0, mode_size);
end = MIN(p-s, (ssize_t)(mode_size-1)); /* ensure NULL term */
strncpy(ip_mode, s, end);
strncpy(ip_addr, p+1, addr_size-1); /* ensure NULL term */
retval = 0;
}
}
else
{
/* colon is not present */
strncpy(ip_addr, s, addr_size);
}
return retval;
}
/* *************************************************** */
int start_edge(const n2n_edge_cmd_t* cmd)
{
int keep_on_running = 0;
int local_port = 0 /* any port */;
char tuntap_dev_name[N2N_IFNAMSIZ] = "tun0";
char ip_mode[N2N_IF_MODE_SIZE]="static";
char ip_addr[N2N_NETMASK_STR_SIZE] = "";
char netmask[N2N_NETMASK_STR_SIZE]="255.255.255.0";
char device_mac[N2N_MACNAMSIZ]="";
char * encrypt_key=NULL;
n2n_edge_t eee;
int i;
keep_on_running = 0;
pthread_mutex_lock(&status.mutex);
status.is_running = keep_on_running;
pthread_mutex_unlock(&status.mutex);
report_edge_status();
if (!cmd) {
traceEvent( TRACE_ERROR, "Empty cmd struct" );
return 1;
}
traceLevel = cmd->trace_vlevel;
traceLevel = traceLevel < 0 ? 0 : traceLevel; /* TRACE_ERROR */
traceLevel = traceLevel > 4 ? 4 : traceLevel; /* TRACE_DEBUG */
if (-1 == edge_init(&eee) )
{
traceEvent( TRACE_ERROR, "Failed in edge_init" );
return 1;
}
memset(&(eee.supernode), 0, sizeof(eee.supernode));
eee.supernode.family = AF_INET;
if (cmd->vpn_fd < 0) {
traceEvent(TRACE_ERROR, "VPN socket is invalid.");
return 1;
}
eee.device.fd = cmd->vpn_fd;
if (cmd->enc_key_file)
{
strncpy(eee.keyschedule, cmd->enc_key_file, N2N_PATHNAME_MAXLEN-1);
eee.keyschedule[N2N_PATHNAME_MAXLEN-1]=0; /* strncpy does not add NULL if the source has no NULL. */
traceEvent(TRACE_DEBUG, "keyfile = '%s'\n", eee.keyschedule);
}
else if (cmd->enc_key)
{
encrypt_key = strdup(cmd->enc_key);
traceEvent(TRACE_DEBUG, "encrypt_key = '%s'\n", encrypt_key);
}
if (cmd->ip_addr[0] != '\0')
{
scan_address(ip_addr, N2N_NETMASK_STR_SIZE,
ip_mode, N2N_IF_MODE_SIZE,
cmd->ip_addr);
}
else
{
traceEvent(TRACE_ERROR, "Ip address is not set.");
free(encrypt_key);
return 1;
}
if (cmd->community[0] != '\0')
{
strncpy((char *)eee.community_name, cmd->community, N2N_COMMUNITY_SIZE);
}
else
{
traceEvent(TRACE_ERROR, "Community is not set.");
free(encrypt_key);
return 1;
}
eee.drop_multicast = cmd->drop_multicast == 0 ? 0 : 1;
if (cmd->mac_addr[0] != '\0')
{
strncpy(device_mac, cmd->mac_addr, N2N_MACNAMSIZ);
}
else
{
strncpy(device_mac, random_device_mac(), N2N_MACNAMSIZ);
traceEvent(TRACE_DEBUG, "random device mac: %s\n", device_mac);
}
eee.allow_routing = cmd->allow_routing == 0 ? 0 : 1;
for (i = 0; i < N2N_EDGE_NUM_SUPERNODES && i < EDGE_CMD_SUPERNODES_NUM; ++i)
{
if (cmd->supernodes[i][0] != '\0')
{
strncpy(eee.sn_ip_array[eee.sn_num], cmd->supernodes[i], N2N_EDGE_SN_HOST_SIZE);
traceEvent(TRACE_DEBUG, "Adding supernode[%u] = %s\n", (unsigned int)eee.sn_num, (eee.sn_ip_array[eee.sn_num]));
++eee.sn_num;
}
}
eee.re_resolve_supernode_ip = cmd->re_resolve_supernode_ip == 0 ? 0 : 1;
if (cmd->ip_netmask[0] != '\0')
{
strncpy(netmask, cmd->ip_netmask, N2N_NETMASK_STR_SIZE);
}
for (i=0; i< N2N_EDGE_NUM_SUPERNODES; ++i )
{
traceEvent(TRACE_NORMAL, "supernode %u => %s\n", i, (eee.sn_ip_array[i]));
}
supernode2addr(&(eee.supernode), eee.sn_ip_array[eee.sn_idx]);
if (encrypt_key == NULL && strlen(eee.keyschedule) == 0)
{
traceEvent(TRACE_WARNING, "Encryption is disabled in edge.");
eee.null_transop = 1;
}
if (0 == strcmp("dhcp", ip_mode))
{
traceEvent(TRACE_NORMAL, "Dynamic IP address assignment enabled.");
eee.dyn_ip_mode = 1;
}
else
{
traceEvent(TRACE_NORMAL, "ip_mode='%s'", ip_mode);
}
if(tuntap_open(&(eee.device), tuntap_dev_name, ip_mode, ip_addr, netmask, device_mac, cmd->mtu) < 0)
{
traceEvent(TRACE_ERROR, "Failed in tuntap_open");
free(encrypt_key);
return 1;
}
if(local_port > 0)
{
traceEvent(TRACE_NORMAL, "Binding to local port %d", (signed int)local_port);
}
if (encrypt_key)
{
if(edge_init_twofish(&eee, (uint8_t *)(encrypt_key), strlen(encrypt_key)) < 0)
{
traceEvent(TRACE_ERROR, "twofish setup failed.\n");
free(encrypt_key);
return 1;
}
free(encrypt_key);
encrypt_key = NULL;
}
else if (strlen(eee.keyschedule) > 0)
{
if (edge_init_keyschedule(&eee) != 0)
{
traceEvent(TRACE_ERROR, "keyschedule setup failed.\n");
free(encrypt_key);
return 1;
}
}
/* else run in NULL mode */
eee.udp_sock = open_socket(local_port, 1 /*bind ANY*/ );
if(eee.udp_sock < 0)
{
traceEvent(TRACE_ERROR, "Failed to bind main UDP port %u", (signed int)local_port);
return 1;
}
eee.udp_mgmt_sock = open_socket(N2N_EDGE_MGMT_PORT, 0 /* bind LOOPBACK*/ );
if(eee.udp_mgmt_sock < 0)
{
traceEvent( TRACE_ERROR, "Failed to bind management UDP port %u", (unsigned int)N2N_EDGE_MGMT_PORT );
return 1;
}
/* set host addr, netmask, mac addr for UIP and init arp*/
{
int match, i;
u8_t ip[4];
uip_ipaddr_t ipaddr;
struct uip_eth_addr eaddr;
match = sscanf(ip_addr, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3);
if (match != 4) {
traceEvent(TRACE_ERROR, "scan ip failed, ip: %s", ip_addr);
return 1;
}
uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]);
uip_sethostaddr(ipaddr);
match = sscanf(netmask, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3);
if (match != 4) {
traceEvent(TRACE_ERROR, "scan netmask error, ip: %s", netmask);
return 1;
}
uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]);
uip_setnetmask(ipaddr);
for (i = 0; i < 6; ++i) {
eaddr.addr[i] = eee.device.mac_addr[i];
}
uip_setethaddr(eaddr);
uip_arp_init();
}
keep_on_running = 1;
pthread_mutex_lock(&status.mutex);
status.is_running = keep_on_running;
pthread_mutex_unlock(&status.mutex);
report_edge_status();
traceEvent(TRACE_NORMAL, "edge started");
update_supernode_reg(&eee, time(NULL));
return run_edge_loop(&eee, &keep_on_running);
}
int stop_edge(void)
{
// quick stop
int fd = open_socket(0, 0 /* bind LOOPBACK*/ );
if (fd < 0) {
return 1;
}
struct sockaddr_in peer_addr;
peer_addr.sin_family = PF_INET;
peer_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
peer_addr.sin_port = htons(N2N_EDGE_MGMT_PORT);
sendto(fd, "stop", 4, 0, (struct sockaddr *)&peer_addr, sizeof(struct sockaddr_in));
pthread_mutex_lock(&status.mutex);
status.is_running = 0;
pthread_mutex_unlock(&status.mutex);
report_edge_status();
return 0;
}
#endif /* #ifdef __ANDROID_NDK__ */
/* ************************************** */

64
android/edge_android.h Normal file
View File

@ -0,0 +1,64 @@
//
// Created by switchwang(https://github.com/switch-st) on 2018-04-13.
//
#ifndef _EDGE_ANDROID_H_
#define _EDGE_ANDROID_H_
#ifdef __ANDROID_NDK__
#include "../n2n.h"
#include <pthread.h>
#define EDGE_CMD_IPSTR_SIZE 16
#define EDGE_CMD_SUPERNODES_NUM 2
#define EDGE_CMD_SN_HOST_SIZE 48
#define EDGE_CMD_MACNAMSIZ 18
typedef struct n2n_edge_cmd_st
{
char ip_addr[EDGE_CMD_IPSTR_SIZE];
char ip_netmask[EDGE_CMD_IPSTR_SIZE];
char supernodes[EDGE_CMD_SUPERNODES_NUM][EDGE_CMD_SN_HOST_SIZE];
char community[N2N_COMMUNITY_SIZE];
char* enc_key;
char* enc_key_file;
char mac_addr[EDGE_CMD_MACNAMSIZ];
unsigned int mtu;
int re_resolve_supernode_ip;
unsigned int local_port;
int allow_routing;
int drop_multicast;
int trace_vlevel;
int vpn_fd;
} n2n_edge_cmd_t;
typedef struct n2n_edge_status_st
{
pthread_mutex_t mutex;
uint8_t is_running;
} n2n_edge_status;
#define INIT_EDGE_CMD(cmd) do {\
memset(&(cmd), 0, sizeof((cmd))); \
(cmd).enc_key = NULL; \
(cmd).enc_key_file = NULL; \
(cmd).mtu = 1400; \
(cmd).re_resolve_supernode_ip = 0;\
(cmd).local_port = 0; \
(cmd).allow_routing = 0; \
(cmd).drop_multicast = 1; \
(cmd).trace_vlevel = 2; \
(cmd).vpn_fd = -1; \
} while (0);
n2n_edge_status status;
int start_edge(const n2n_edge_cmd_t* cmd);
int stop_edge(void);
void report_edge_status(void);
#endif /* __ANDROID_NDK__ */
#endif //_EDGE_ANDROID_H_

405
android/edge_jni.c Normal file
View File

@ -0,0 +1,405 @@
//
// Created by switchwang(https://github.com/switch-st) on 2018-04-15.
//
#include <jni.h>
#include <pthread.h>
#include "edge_android.h"
static int GetEdgeCmd(JNIEnv *env, jobject jcmd, n2n_edge_cmd_t* cmd);
static void* EdgeRoutine(void* cmd);
static n2n_edge_cmd_t cmd;
static pthread_t tid = -1;
static JavaVM* jvm = NULL;
static jobject jobj_service = NULL;
static jclass jcls_status = NULL;
JNIEXPORT jboolean JNICALL Java_wang_switchy_hin2n_service_N2NService_startEdge(
JNIEnv *env,
jobject this,
jobject jcmd) {
#ifndef NDEBUG
__android_log_write(LOG_DEBUG, "edge_jni", "in start");
#endif /* #ifndef NDEBUG */
if (GetEdgeCmd(env, jcmd, &cmd) != 0) {
goto ERROR;
}
int val = fcntl(cmd.vpn_fd, F_GETFL);
if (val == -1) {
goto ERROR;
}
if ((val & O_NONBLOCK) == O_NONBLOCK) {
val &= ~O_NONBLOCK;
val = fcntl(cmd.vpn_fd, F_SETFL, val);
if (val == -1) {
goto ERROR;
}
}
if (tid != -1) {
stop_edge();
pthread_kill(tid, SIGINT);
pthread_join(tid, NULL);
tid = -1;
if (jcls_status) {
(*env)->DeleteGlobalRef(env, jcls_status);
jcls_status = NULL;
}
if (jobj_service) {
(*env)->DeleteGlobalRef(env, jobj_service);
jobj_service = NULL;
}
jvm = NULL;
pthread_mutex_destroy(&status.mutex);
}
if ((*env)->GetJavaVM(env, &jvm) != JNI_OK) {
goto ERROR;
}
jobj_service = (*env)->NewGlobalRef(env, this);
jclass cls = (*env)->FindClass(env, "wang/switchy/hin2n/model/EdgeStatus");
if (!cls) {
goto ERROR;
}
jcls_status = (*env)->NewGlobalRef(env, cls);
pthread_mutex_init(&status.mutex, NULL);
int ret = pthread_create(&tid, NULL, EdgeRoutine, &cmd);
if (ret != 0) {
tid = -1;
goto ERROR;
}
return JNI_TRUE;
ERROR:
if (jcls_status) {
(*env)->DeleteGlobalRef(env, jcls_status);
jcls_status = NULL;
}
if (jobj_service) {
(*env)->DeleteGlobalRef(env, jobj_service);
jobj_service = NULL;
}
jvm = NULL;
pthread_mutex_destroy(&status.mutex);
free(cmd.enc_key);
free(cmd.enc_key_file);
cmd.enc_key = NULL;
cmd.enc_key_file = NULL;
return JNI_FALSE;
}
JNIEXPORT void JNICALL Java_wang_switchy_hin2n_service_N2NService_stopEdge(
JNIEnv *env,
jobject this) {
#ifndef NDEBUG
__android_log_write(LOG_DEBUG, "edge_jni", "in stop");
#endif /* #ifndef NDEBUG */
stop_edge();
pthread_join(tid, NULL);
tid = -1;
if (jcls_status) {
(*env)->DeleteGlobalRef(env, jcls_status);
jcls_status = NULL;
}
if (jobj_service) {
(*env)->DeleteGlobalRef(env, jobj_service);
jobj_service = NULL;
}
jvm = NULL;
pthread_mutex_destroy(&status.mutex);
}
JNIEXPORT jobject JNICALL Java_wang_switchy_hin2n_service_N2NService_getEdgeStatus(
JNIEnv *env,
jobject this) {
jboolean is_running = JNI_FALSE;
if (tid != -1) {
is_running = pthread_kill(tid, 0) ? JNI_FALSE : JNI_TRUE;
pthread_mutex_lock(&status.mutex);
is_running = is_running && status.is_running;
pthread_mutex_unlock(&status.mutex);
}
jclass cls = (*env)->FindClass(env, "wang/switchy/hin2n/model/EdgeStatus");
jobject jStatus = (*env)->NewObject(env, cls, (*env)->GetMethodID(env, cls, "<init>", "()V"));
if (!jStatus) {
return NULL;
}
(*env)->SetBooleanField(env, jStatus, (*env)->GetFieldID(env, cls, "isRunning", "Z"), is_running);
return jStatus;
}
/////////////////////////////////////////////////////////////////////////
#ifndef JNI_CHECKNULL
#define JNI_CHECKNULL(p) do { if (!(p)) return 1;}while(0)
#endif /* JNI_CHECKNULL */
int GetEdgeCmd(JNIEnv *env, jobject jcmd, n2n_edge_cmd_t* cmd)
{
jclass cls;
int i, j;
INIT_EDGE_CMD(*cmd);
cls = (*env)->GetObjectClass(env, jcmd);
JNI_CHECKNULL(cls);
// ipAddr
{
jstring jsIpAddr = (*env)->GetObjectField(env, jcmd, (*env)->GetFieldID(env, cls, "ipAddr", "Ljava/lang/String;"));
JNI_CHECKNULL(jsIpAddr);
const char* ipAddr = (*env)->GetStringUTFChars(env, jsIpAddr, NULL);
if (!ipAddr || strlen(ipAddr) == 0) {
(*env)->ReleaseStringUTFChars(env, jsIpAddr, ipAddr);
return 1;
}
strncpy(cmd->ip_addr, ipAddr, EDGE_CMD_IPSTR_SIZE);
(*env)->ReleaseStringUTFChars(env, jsIpAddr, ipAddr);
#ifndef NDEBUG
__android_log_print(LOG_DEBUG, "edge_jni", "ipAddr = %s", cmd->ip_addr);
#endif /* #ifndef NDEBUG */
}
// ipNetmask
{
jstring jsIpNetmask = (*env)->GetObjectField(env, jcmd, (*env)->GetFieldID(env, cls, "ipNetmask", "Ljava/lang/String;"));
JNI_CHECKNULL(jsIpNetmask);
const char* ipNetmask = (*env)->GetStringUTFChars(env, jsIpNetmask, NULL);
if (!ipNetmask || strlen(ipNetmask) == 0) {
(*env)->ReleaseStringUTFChars(env, jsIpNetmask, ipNetmask);
return 1;
}
strncpy(cmd->ip_netmask, ipNetmask, EDGE_CMD_IPSTR_SIZE);
(*env)->ReleaseStringUTFChars(env, jsIpNetmask, ipNetmask);
#ifndef NDEBUG
__android_log_print(LOG_DEBUG, "edge_jni", "ipNetmask = %s", cmd->ip_netmask);
#endif /* #ifndef NDEBUG */
}
// supernodes
{
jarray jaSupernodes = (*env)->GetObjectField(env, jcmd, (*env)->GetFieldID(env, cls, "supernodes", "[Ljava/lang/String;"));
JNI_CHECKNULL(jaSupernodes);
int len = (*env)->GetArrayLength(env, jaSupernodes);
if (len <= 0) {
return 1;
}
for (i = 0, j = 0; i < len && i < EDGE_CMD_SUPERNODES_NUM; ++i) {
const jobject jsNode = (*env)->GetObjectArrayElement(env, jaSupernodes, i);
if (!jsNode) {
continue;
}
const char* node = (*env)->GetStringUTFChars(env, jsNode, NULL);
if (!node || strlen(node) == 0) {
(*env)->ReleaseStringUTFChars(env, jsNode, node);
continue;
}
strncpy(cmd->supernodes[j], node, EDGE_CMD_SN_HOST_SIZE);
(*env)->ReleaseStringUTFChars(env, jsNode, node);
#ifndef NDEBUG
__android_log_print(LOG_DEBUG, "edge_jni", "supernodes = %s", cmd->supernodes[j]);
#endif /* #ifndef NDEBUG */
j++;
}
#ifndef NDEBUG
__android_log_print(LOG_DEBUG, "edge_jni", "j = %d", j);
#endif /* #ifndef NDEBUG */
if (j == 0) {
return 1;
}
}
// community
{
jstring jsCommunity = (*env)->GetObjectField(env, jcmd, (*env)->GetFieldID(env, cls, "community", "Ljava/lang/String;"));
JNI_CHECKNULL(jsCommunity);
const char* community = (*env)->GetStringUTFChars(env, jsCommunity, NULL);
if (!community || strlen(community) == 0) {
(*env)->ReleaseStringUTFChars(env, jsCommunity, community);
return 1;
}
strncpy(cmd->community, community, N2N_COMMUNITY_SIZE);
(*env)->ReleaseStringUTFChars(env, jsCommunity, community);
#ifndef NDEBUG
__android_log_print(LOG_DEBUG, "edge_jni", "community = %s", cmd->community);
#endif /* #ifndef NDEBUG */
}
// encKey
{
jstring jsEncKey = (*env)->GetObjectField(env, jcmd, (*env)->GetFieldID(env, cls, "encKey", "Ljava/lang/String;"));
if (jsEncKey) {
const char* encKey = (*env)->GetStringUTFChars(env, jsEncKey, NULL);
if (encKey && strlen(encKey) != 0) {
cmd->enc_key = strdup(encKey);
}
(*env)->ReleaseStringUTFChars(env, jsEncKey, encKey);
#ifndef NDEBUG
__android_log_print(LOG_DEBUG, "edge_jni", "encKey = %s", cmd->enc_key);
#endif /* #ifndef NDEBUG */
}
}
// encKeyFile
{
jstring jsEncKeyFile = (*env)->GetObjectField(env, jcmd, (*env)->GetFieldID(env, cls, "encKeyFile", "Ljava/lang/String;"));
if (jsEncKeyFile) {
const char* encKeyFile = (*env)->GetStringUTFChars(env, jsEncKeyFile, NULL);
if (encKeyFile && strlen(encKeyFile) != 0) {
cmd->enc_key_file = strdup(encKeyFile);
}
(*env)->ReleaseStringUTFChars(env, jsEncKeyFile, encKeyFile);
#ifndef NDEBUG
__android_log_print(LOG_DEBUG, "edge_jni", "encKeyFile = %s", cmd->enc_key_file);
#endif /* #ifndef NDEBUG */
}
}
// macAddr
{
jstring jsMacAddr = (*env)->GetObjectField(env, jcmd, (*env)->GetFieldID(env, cls, "macAddr", "Ljava/lang/String;"));
JNI_CHECKNULL(jsMacAddr);
const char* macAddr = (*env)->GetStringUTFChars(env, jsMacAddr, NULL);
if (macAddr && strlen(macAddr) != 0) {
strncpy(cmd->mac_addr, macAddr, EDGE_CMD_MACNAMSIZ);
}
(*env)->ReleaseStringUTFChars(env, jsMacAddr, macAddr);
#ifndef NDEBUG
__android_log_print(LOG_DEBUG, "edge_jni", "macAddr = %s", cmd->mac_addr);
#endif /* #ifndef NDEBUG */
}
// mtu
{
jint jiMtu = (*env)->GetIntField(env, jcmd, (*env)->GetFieldID(env, cls, "mtu", "I"));
if (jiMtu <= 0) {
return 1;
}
cmd->mtu = jiMtu;
#ifndef NDEBUG
__android_log_print(LOG_DEBUG, "edge_jni", "mtu = %d", cmd->mtu);
#endif /* #ifndef NDEBUG */
}
// reResoveSupernodeIP
{
jboolean jbReResoveSupernodeIP= (*env)->GetBooleanField(env, jcmd, (*env)->GetFieldID(env, cls, "reResoveSupernodeIP", "Z"));
cmd->re_resolve_supernode_ip = jbReResoveSupernodeIP ? 1 : 0;
#ifndef NDEBUG
__android_log_print(LOG_DEBUG, "edge_jni", "reResoveSupernodeIP = %d", cmd->re_resolve_supernode_ip);
#endif /* #ifndef NDEBUG */
}
// localPort
{
jint jiLocalPort = (*env)->GetIntField(env, jcmd, (*env)->GetFieldID(env, cls, "localPort", "I"));
if (jiLocalPort < 0) {
return 1;
}
cmd->local_port = jiLocalPort;
#ifndef NDEBUG
__android_log_print(LOG_DEBUG, "edge_jni", "localPort = %d", cmd->local_port);
#endif /* #ifndef NDEBUG */
}
// allowRouting
{
jboolean jbAllowRouting= (*env)->GetBooleanField(env, jcmd, (*env)->GetFieldID(env, cls, "allowRouting", "Z"));
cmd->allow_routing = jbAllowRouting ? 1 : 0;
#ifndef NDEBUG
__android_log_print(LOG_DEBUG, "edge_jni", "allowRouting = %d", cmd->allow_routing);
#endif /* #ifndef NDEBUG */
}
// dropMuticast
{
jboolean jbDropMuticast= (*env)->GetBooleanField(env, jcmd, (*env)->GetFieldID(env, cls, "dropMuticast", "Z"));
cmd->drop_multicast = jbDropMuticast ? 1 : 0;
#ifndef NDEBUG
__android_log_print(LOG_DEBUG, "edge_jni", "dropMuticast = %d", cmd->drop_multicast);
#endif /* #ifndef NDEBUG */
}
// traceLevel
{
jint jiTraceLevel = (*env)->GetIntField(env, jcmd, (*env)->GetFieldID(env, cls, "traceLevel", "I"));
cmd->trace_vlevel = jiTraceLevel;
#ifndef NDEBUG
__android_log_print(LOG_DEBUG, "edge_jni", "traceLevel = %d", cmd->trace_vlevel);
#endif /* #ifndef NDEBUG */
}
// vpnFd
{
jint jiVpnFd = (*env)->GetIntField(env, jcmd, (*env)->GetFieldID(env, cls, "vpnFd", "I"));
if (jiVpnFd < 0) {
return 1;
}
cmd->vpn_fd = jiVpnFd;
#ifndef NDEBUG
__android_log_print(LOG_DEBUG, "edge_jni", "vpnFd = %d", cmd->vpn_fd);
#endif /* #ifndef NDEBUG */
}
return 0;
}
void* EdgeRoutine(void* cmd)
{
int flag = 0;
if (jvm) {
JNIEnv* env = NULL;
if ((*jvm)->AttachCurrentThread(jvm, &env, NULL) == JNI_OK) {
flag = 1;
}
}
n2n_edge_cmd_t* c = cmd;
int ret = start_edge(c);
free(c->enc_key);
free(c->enc_key_file);
c->enc_key = NULL;
c->enc_key_file = NULL;
if (flag && jvm) {
(*jvm)->DetachCurrentThread(jvm);
}
return (void*)ret;
}
void report_edge_status(void)
{
if (!jvm || !jobj_service || !jcls_status || tid == -1) {
return;
}
jboolean is_running = JNI_FALSE;
pthread_mutex_lock(&status.mutex);
is_running = status.is_running;
pthread_mutex_unlock(&status.mutex);
JNIEnv* env = NULL;
if ((*jvm)->GetEnv(jvm, &env, JNI_VERSION_1_1) != JNI_OK || !env) {
return;
}
jmethodID mid = (*env)->GetMethodID(env, jcls_status, "<init>", "()V");
if (!mid) {
return;
}
jobject jStatus = (*env)->NewObject(env, jcls_status, mid);
if (!jStatus) {
return;
}
jfieldID fid = (*env)->GetFieldID(env, jcls_status, "isRunning", "Z");
if (!fid) {
return;
}
(*env)->SetBooleanField(env, jStatus, fid, is_running);
jclass cls = (*env)->GetObjectClass(env, jobj_service);
if (!cls) {
return;
}
mid = (*env)->GetMethodID(env, cls, "reportEdgeStatus", "(Lwang/switchy/hin2n/model/EdgeStatus;)V");
if (!mid) {
return;
}
(*env)->CallVoidMethod(env, jobj_service, mid, jStatus);
(*env)->DeleteLocalRef(env, jStatus);
}

View File

@ -0,0 +1,9 @@
//
// Created by switchwang(https://github.com/switch-st) on 2018-04-20.
//
#include "tun2tap.h"
u8_t* uip_buf = NULL;
u8_t uip_arp_buf[UIP_LLH_LEN + UIP_ARP_LEN];
u16_t uip_arp_len = 0;

53
android/tun2tap/tun2tap.h Normal file
View File

@ -0,0 +1,53 @@
//
// Created by switchwang(https://github.com/switch-st) on 2018-04-14.
//
#ifndef _TUN2TAP_H_
#define _TUN2TAP_H_
#ifdef HTONS
#undef HTONS
#endif
#include "uip-conf.h"
#include <uip/uip.h>
#include <uip/uip_arp.h>
#define UIP_ARP_LEN 28
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 BUF ((struct arp_hdr *)&uip_buf[0])
#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
extern u8_t* uip_buf;
extern u8_t uip_arp_buf[UIP_LLH_LEN + UIP_ARP_LEN];
extern u16_t uip_arp_len;
#endif //_TUN2TAP_H_

View File

@ -0,0 +1,13 @@
//
// Created by switchwang(https://github.com/switch-st) on 2018-04-14.
//
#ifndef _TUN2TAP_DEFINE_H_
#define _TUN2TAP_DEFINE_H_
#define uip_tcp_appstate_t void*
#define UIP_APPCALL()
extern u8_t* uip_buf;
#endif //_TUN2TAP_DEFINE_H_

163
android/tun2tap/uip-conf.h Normal file
View File

@ -0,0 +1,163 @@
/**
* \addtogroup uipopt
* @{
*/
/**
* \name Project-specific configuration options
* @{
*
* uIP has a number of configuration options that can be overridden
* for each project. These are kept in a project-specific uip-conf.h
* file and all configuration names have the prefix UIP_CONF.
*/
/*
* Copyright (c) 2006, 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.
*
* This file is part of the uIP TCP/IP stack
*
* $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $
*/
/**
* \file
* An example uIP configuration file
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __UIP_CONF_H__
#define __UIP_CONF_H__
#include <inttypes.h>
/**
* 8 bit datatype
*
* This typedef defines the 8-bit type used throughout uIP.
*
* \hideinitializer
*/
typedef uint8_t u8_t;
/**
* 16 bit datatype
*
* This typedef defines the 16-bit type used throughout uIP.
*
* \hideinitializer
*/
typedef uint16_t u16_t;
/**
* Statistics datatype
*
* This typedef defines the dataype used for keeping statistics in
* uIP.
*
* \hideinitializer
*/
typedef unsigned short uip_stats_t;
/**
* Maximum number of TCP connections.
*
* \hideinitializer
*/
#define UIP_CONF_MAX_CONNECTIONS 40
/**
* Maximum number of listening TCP ports.
*
* \hideinitializer
*/
#define UIP_CONF_MAX_LISTENPORTS 40
/**
* uIP buffer size.
*
* \hideinitializer
*/
/*#define UIP_CONF_BUFFER_SIZE 420*/
#define UIP_CONF_BUFFER_SIZE 2048
/**
* Manually define the uip_buf.
*
* \hideinitializer
*/
#define UIP_CONF_EXTERNAL_BUFFER
/**
* CPU byte order.
* Defined in CMakeList.txt
*
* \hideinitializer
*/
#ifndef UIP_CONF_BYTE_ORDER
#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN
#endif
/**
* Logging on or off
*
* \hideinitializer
*/
/*#define UIP_CONF_LOGGING 1*/
#define UIP_CONF_LOGGING 0
/**
* UDP support on or off
*
* \hideinitializer
*/
#define UIP_CONF_UDP 0
/**
* UDP checksums on or off
*
* \hideinitializer
*/
#define UIP_CONF_UDP_CHECKSUMS 1
/**
* uIP statistics on or off
*
* \hideinitializer
*/
#define UIP_CONF_STATISTICS 1
/* Here we include the header file for the application(s) we use in
our project. */
#include "tun2tap_appdef.h"
#endif /* __UIP_CONF_H__ */
/** @} */
/** @} */

107
android/tuntap_android.c Normal file
View File

@ -0,0 +1,107 @@
/*
* (C) 2007-09 - Luca Deri <deri@ntop.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>
*/
#include "../n2n.h"
#ifdef __ANDROID_NDK__
#include <tun2tap/tun2tap.h>
/* ********************************** */
/** @brief Open and configure the TAP device for packet read/write.
*
* This routine creates the interface via the tuntap driver then uses ifconfig
* to configure address/mask and MTU.
*
* @param device - [inout] a device info holder object
* @param dev - user-defined name for the new iface,
* if NULL system will assign a name
* @param device_ip - address of iface
* @param device_mask - netmask for device_ip
* @param mtu - MTU for device_ip
*
* @return - negative value on error
* - non-negative file-descriptor on success
*/
int tuntap_open(tuntap_dev *device,
char *dev, /* user-definable interface name, eg. edge0 */
const char *address_mode, /* static or dhcp */
char *device_ip,
char *device_mask,
const char * device_mac,
int mtu) {
int i, n_matched;
unsigned int mac[6];
n_matched = sscanf(device_mac, "%x:%x:%x:%x:%x:%x", mac, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5);
if (n_matched != 6) {
return -1;
}
memset(device->mac_addr, 0, sizeof(device->mac_addr));
for (i = 0; i < 6; i++)
device->mac_addr[i] = mac[i];
device->ip_addr = inet_addr(device_ip);
device->device_mask = inet_addr(device_mask);
device->mtu = mtu;
strncpy(device->dev_name, dev, MIN(IFNAMSIZ, N2N_IFNAMSIZ));
return device->fd;
}
int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) {
int rlen = read(tuntap->fd, buf + UIP_LLH_LEN, len - UIP_LLH_LEN);
if ((rlen <= 0) || (rlen > N2N_PKT_BUF_SIZE - UIP_LLH_LEN))
{
return rlen;
}
uip_buf = buf;
uip_len = rlen;
uip_arp_out();
if (IPBUF->ethhdr.type == htons(UIP_ETHTYPE_ARP))
{
traceEvent(TRACE_DEBUG, "ARP request packets are sent instead of packets");
}
return uip_len;
}
int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) {
uip_buf = buf;
uip_len = len;
if (IPBUF->ethhdr.type == htons(UIP_ETHTYPE_IP)) {
return write(tuntap->fd, buf + UIP_LLH_LEN, len - UIP_LLH_LEN);
} else if (IPBUF->ethhdr.type == htons(UIP_ETHTYPE_ARP)) {
uip_arp_arpin();
if (uip_len > 0) {
uip_arp_len = uip_len;
memcpy(uip_arp_buf, uip_buf, uip_arp_len);
traceEvent(TRACE_DEBUG, "ARP reply packet prepare to send");
}
return uip_len;
}
errno = EINVAL;
return -1;
}
void tuntap_close(struct tuntap_dev *tuntap) {
close(tuntap->fd);
}
void tuntap_get_address(struct tuntap_dev *tuntap) {
}
#endif /* #ifdef __ANDROID_NDK__ */

13
android/uip/README Normal file
View File

@ -0,0 +1,13 @@
uIP is a very small implementation of the TCP/IP stack that is written
by Adam Dunkels <adam@sics.se>. More information can be obtained
at the uIP homepage at http://www.sics.se/~adam/uip/.
This is version $Name: uip-1-0 $.
The directory structure look as follows:
apps/ - Example applications
doc/ - Documentation
lib/ - Library code used by some applications
uip/ - uIP TCP/IP stack code
unix/ - uIP as a user space process under FreeBSD or Linux

2
android/uip/apps/README Normal file
View File

@ -0,0 +1,2 @@
This directory contains a few example applications. They are not all
heavily tested, however.

View File

@ -0,0 +1 @@
APP_SOURCES += dhcpc.c timer.c

View File

@ -0,0 +1,356 @@
/*
* Copyright (c) 2005, 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.
*
* This file is part of the uIP TCP/IP stack
*
* @(#)$Id: dhcpc.c,v 1.2 2006/06/11 21:46:37 adam Exp $
*/
#include <stdio.h>
#include <string.h>
#include "uip.h"
#include "dhcpc.h"
#include "timer.h"
#include "pt.h"
#define STATE_INITIAL 0
#define STATE_SENDING 1
#define STATE_OFFER_RECEIVED 2
#define STATE_CONFIG_RECEIVED 3
static struct dhcpc_state s;
struct dhcp_msg {
u8_t op, htype, hlen, hops;
u8_t xid[4];
u16_t secs, flags;
u8_t ciaddr[4];
u8_t yiaddr[4];
u8_t siaddr[4];
u8_t giaddr[4];
u8_t chaddr[16];
#ifndef UIP_CONF_DHCP_LIGHT
u8_t sname[64];
u8_t file[128];
#endif
u8_t options[312];
};
#define BOOTP_BROADCAST 0x8000
#define DHCP_REQUEST 1
#define DHCP_REPLY 2
#define DHCP_HTYPE_ETHERNET 1
#define DHCP_HLEN_ETHERNET 6
#define DHCP_MSG_LEN 236
#define DHCPC_SERVER_PORT 67
#define DHCPC_CLIENT_PORT 68
#define DHCPDISCOVER 1
#define DHCPOFFER 2
#define DHCPREQUEST 3
#define DHCPDECLINE 4
#define DHCPACK 5
#define DHCPNAK 6
#define DHCPRELEASE 7
#define DHCP_OPTION_SUBNET_MASK 1
#define DHCP_OPTION_ROUTER 3
#define DHCP_OPTION_DNS_SERVER 6
#define DHCP_OPTION_REQ_IPADDR 50
#define DHCP_OPTION_LEASE_TIME 51
#define DHCP_OPTION_MSG_TYPE 53
#define DHCP_OPTION_SERVER_ID 54
#define DHCP_OPTION_REQ_LIST 55
#define DHCP_OPTION_END 255
static const u8_t xid[4] = {0xad, 0xde, 0x12, 0x23};
static const u8_t magic_cookie[4] = {99, 130, 83, 99};
/*---------------------------------------------------------------------------*/
static u8_t *
add_msg_type(u8_t *optptr, u8_t type)
{
*optptr++ = DHCP_OPTION_MSG_TYPE;
*optptr++ = 1;
*optptr++ = type;
return optptr;
}
/*---------------------------------------------------------------------------*/
static u8_t *
add_server_id(u8_t *optptr)
{
*optptr++ = DHCP_OPTION_SERVER_ID;
*optptr++ = 4;
memcpy(optptr, s.serverid, 4);
return optptr + 4;
}
/*---------------------------------------------------------------------------*/
static u8_t *
add_req_ipaddr(u8_t *optptr)
{
*optptr++ = DHCP_OPTION_REQ_IPADDR;
*optptr++ = 4;
memcpy(optptr, s.ipaddr, 4);
return optptr + 4;
}
/*---------------------------------------------------------------------------*/
static u8_t *
add_req_options(u8_t *optptr)
{
*optptr++ = DHCP_OPTION_REQ_LIST;
*optptr++ = 3;
*optptr++ = DHCP_OPTION_SUBNET_MASK;
*optptr++ = DHCP_OPTION_ROUTER;
*optptr++ = DHCP_OPTION_DNS_SERVER;
return optptr;
}
/*---------------------------------------------------------------------------*/
static u8_t *
add_end(u8_t *optptr)
{
*optptr++ = DHCP_OPTION_END;
return optptr;
}
/*---------------------------------------------------------------------------*/
static void
create_msg(register struct dhcp_msg *m)
{
m->op = DHCP_REQUEST;
m->htype = DHCP_HTYPE_ETHERNET;
m->hlen = s.mac_len;
m->hops = 0;
memcpy(m->xid, xid, sizeof(m->xid));
m->secs = 0;
m->flags = HTONS(BOOTP_BROADCAST); /* Broadcast bit. */
/* uip_ipaddr_copy(m->ciaddr, uip_hostaddr);*/
memcpy(m->ciaddr, uip_hostaddr, sizeof(m->ciaddr));
memset(m->yiaddr, 0, sizeof(m->yiaddr));
memset(m->siaddr, 0, sizeof(m->siaddr));
memset(m->giaddr, 0, sizeof(m->giaddr));
memcpy(m->chaddr, s.mac_addr, s.mac_len);
memset(&m->chaddr[s.mac_len], 0, sizeof(m->chaddr) - s.mac_len);
#ifndef UIP_CONF_DHCP_LIGHT
memset(m->sname, 0, sizeof(m->sname));
memset(m->file, 0, sizeof(m->file));
#endif
memcpy(m->options, magic_cookie, sizeof(magic_cookie));
}
/*---------------------------------------------------------------------------*/
static void
send_discover(void)
{
u8_t *end;
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
create_msg(m);
end = add_msg_type(&m->options[4], DHCPDISCOVER);
end = add_req_options(end);
end = add_end(end);
uip_send(uip_appdata, end - (u8_t *)uip_appdata);
}
/*---------------------------------------------------------------------------*/
static void
send_request(void)
{
u8_t *end;
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
create_msg(m);
end = add_msg_type(&m->options[4], DHCPREQUEST);
end = add_server_id(end);
end = add_req_ipaddr(end);
end = add_end(end);
uip_send(uip_appdata, end - (u8_t *)uip_appdata);
}
/*---------------------------------------------------------------------------*/
static u8_t
parse_options(u8_t *optptr, int len)
{
u8_t *end = optptr + len;
u8_t type = 0;
while(optptr < end) {
switch(*optptr) {
case DHCP_OPTION_SUBNET_MASK:
memcpy(s.netmask, optptr + 2, 4);
break;
case DHCP_OPTION_ROUTER:
memcpy(s.default_router, optptr + 2, 4);
break;
case DHCP_OPTION_DNS_SERVER:
memcpy(s.dnsaddr, optptr + 2, 4);
break;
case DHCP_OPTION_MSG_TYPE:
type = *(optptr + 2);
break;
case DHCP_OPTION_SERVER_ID:
memcpy(s.serverid, optptr + 2, 4);
break;
case DHCP_OPTION_LEASE_TIME:
memcpy(s.lease_time, optptr + 2, 4);
break;
case DHCP_OPTION_END:
return type;
}
optptr += optptr[1] + 2;
}
return type;
}
/*---------------------------------------------------------------------------*/
static u8_t
parse_msg(void)
{
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
if(m->op == DHCP_REPLY &&
memcmp(m->xid, xid, sizeof(xid)) == 0 &&
memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) {
memcpy(s.ipaddr, m->yiaddr, 4);
return parse_options(&m->options[4], uip_datalen());
}
return 0;
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_dhcp(void))
{
PT_BEGIN(&s.pt);
/* try_again:*/
s.state = STATE_SENDING;
s.ticks = CLOCK_SECOND;
do {
send_discover();
timer_set(&s.timer, s.ticks);
PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer));
if(uip_newdata() && parse_msg() == DHCPOFFER) {
s.state = STATE_OFFER_RECEIVED;
break;
}
if(s.ticks < CLOCK_SECOND * 60) {
s.ticks *= 2;
}
} while(s.state != STATE_OFFER_RECEIVED);
s.ticks = CLOCK_SECOND;
do {
send_request();
timer_set(&s.timer, s.ticks);
PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer));
if(uip_newdata() && parse_msg() == DHCPACK) {
s.state = STATE_CONFIG_RECEIVED;
break;
}
if(s.ticks <= CLOCK_SECOND * 10) {
s.ticks += CLOCK_SECOND;
} else {
PT_RESTART(&s.pt);
}
} while(s.state != STATE_CONFIG_RECEIVED);
#if 0
printf("Got IP address %d.%d.%d.%d\n",
uip_ipaddr1(s.ipaddr), uip_ipaddr2(s.ipaddr),
uip_ipaddr3(s.ipaddr), uip_ipaddr4(s.ipaddr));
printf("Got netmask %d.%d.%d.%d\n",
uip_ipaddr1(s.netmask), uip_ipaddr2(s.netmask),
uip_ipaddr3(s.netmask), uip_ipaddr4(s.netmask));
printf("Got DNS server %d.%d.%d.%d\n",
uip_ipaddr1(s.dnsaddr), uip_ipaddr2(s.dnsaddr),
uip_ipaddr3(s.dnsaddr), uip_ipaddr4(s.dnsaddr));
printf("Got default router %d.%d.%d.%d\n",
uip_ipaddr1(s.default_router), uip_ipaddr2(s.default_router),
uip_ipaddr3(s.default_router), uip_ipaddr4(s.default_router));
printf("Lease expires in %ld seconds\n",
ntohs(s.lease_time[0])*65536ul + ntohs(s.lease_time[1]));
#endif
dhcpc_configured(&s);
/* timer_stop(&s.timer);*/
/*
* PT_END restarts the thread so we do this instead. Eventually we
* should reacquire expired leases here.
*/
while(1) {
PT_YIELD(&s.pt);
}
PT_END(&s.pt);
}
/*---------------------------------------------------------------------------*/
void
dhcpc_init(const void *mac_addr, int mac_len)
{
uip_ipaddr_t addr;
s.mac_addr = mac_addr;
s.mac_len = mac_len;
s.state = STATE_INITIAL;
uip_ipaddr(addr, 255,255,255,255);
s.conn = uip_udp_new(&addr, HTONS(DHCPC_SERVER_PORT));
if(s.conn != NULL) {
uip_udp_bind(s.conn, HTONS(DHCPC_CLIENT_PORT));
}
PT_INIT(&s.pt);
}
/*---------------------------------------------------------------------------*/
void
dhcpc_appcall(void)
{
handle_dhcp();
}
/*---------------------------------------------------------------------------*/
void
dhcpc_request(void)
{
u16_t ipaddr[2];
if(s.state == STATE_INITIAL) {
uip_ipaddr(ipaddr, 0,0,0,0);
uip_sethostaddr(ipaddr);
/* handle_dhcp(PROCESS_EVENT_NONE, NULL);*/
}
}
/*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2005, 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.
*
* This file is part of the uIP TCP/IP stack
*
* @(#)$Id: dhcpc.h,v 1.3 2006/06/11 21:46:37 adam Exp $
*/
#ifndef __DHCPC_H__
#define __DHCPC_H__
#include "timer.h"
#include "pt.h"
struct dhcpc_state {
struct pt pt;
char state;
struct uip_udp_conn *conn;
struct timer timer;
u16_t ticks;
const void *mac_addr;
int mac_len;
u8_t serverid[4];
u16_t lease_time[2];
u16_t ipaddr[2];
u16_t netmask[2];
u16_t dnsaddr[2];
u16_t default_router[2];
};
void dhcpc_init(const void *mac_addr, int mac_len);
void dhcpc_request(void);
void dhcpc_appcall(void);
void dhcpc_configured(const struct dhcpc_state *s);
typedef struct dhcpc_state uip_udp_appstate_t;
#define UIP_UDP_APPCALL dhcpc_appcall
#endif /* __DHCPC_H__ */

View File

@ -0,0 +1 @@
APP_SOURCES += hello-world.c

View File

@ -0,0 +1,100 @@
/**
* \addtogroup helloworld
* @{
*/
/**
* \file
* An example of how to write uIP applications
* with protosockets.
* \author
* Adam Dunkels <adam@sics.se>
*/
/*
* This is a short example of how to write uIP applications using
* protosockets.
*/
/*
* We define the application state (struct hello_world_state) in the
* hello-world.h file, so we need to include it here. We also include
* uip.h (since this cannot be included in hello-world.h) and
* <string.h>, since we use the memcpy() function in the code.
*/
#include "hello-world.h"
#include "uip.h"
#include <string.h>
/*
* Declaration of the protosocket function that handles the connection
* (defined at the end of the code).
*/
static int handle_connection(struct hello_world_state *s);
/*---------------------------------------------------------------------------*/
/*
* The initialization function. We must explicitly call this function
* from the system initialization code, some time after uip_init() is
* called.
*/
void
hello_world_init(void)
{
/* We start to listen for connections on TCP port 1000. */
uip_listen(HTONS(1000));
}
/*---------------------------------------------------------------------------*/
/*
* In hello-world.h we have defined the UIP_APPCALL macro to
* hello_world_appcall so that this funcion is uIP's application
* function. This function is called whenever an uIP event occurs
* (e.g. when a new connection is established, new data arrives, sent
* data is acknowledged, data needs to be retransmitted, etc.).
*/
void
hello_world_appcall(void)
{
/*
* The uip_conn structure has a field called "appstate" that holds
* the application state of the connection. We make a pointer to
* this to access it easier.
*/
struct hello_world_state *s = &(uip_conn->appstate);
/*
* If a new connection was just established, we should initialize
* the protosocket in our applications' state structure.
*/
if(uip_connected()) {
PSOCK_INIT(&s->p, s->inputbuffer, sizeof(s->inputbuffer));
}
/*
* Finally, we run the protosocket function that actually handles
* the communication. We pass it a pointer to the application state
* of the current connection.
*/
handle_connection(s);
}
/*---------------------------------------------------------------------------*/
/*
* This is the protosocket function that handles the communication. A
* protosocket function must always return an int, but must never
* explicitly return - all return statements are hidden in the PSOCK
* macros.
*/
static int
handle_connection(struct hello_world_state *s)
{
PSOCK_BEGIN(&s->p);
PSOCK_SEND_STR(&s->p, "Hello. What is your name?\n");
PSOCK_READTO(&s->p, '\n');
strncpy(s->name, s->inputbuffer, sizeof(s->name));
PSOCK_SEND_STR(&s->p, "Hello ");
PSOCK_SEND_STR(&s->p, s->name);
PSOCK_CLOSE(&s->p);
PSOCK_END(&s->p);
}
/*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,52 @@
/**
* \addtogroup apps
* @{
*/
/**
* \defgroup helloworld Hello, world
* @{
*
* A small example showing how to write applications with
* \ref psock "protosockets".
*/
/**
* \file
* Header file for an example of how to write uIP applications
* with protosockets.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __HELLO_WORLD_H__
#define __HELLO_WORLD_H__
/* Since this file will be included by uip.h, we cannot include uip.h
here. But we might need to include uipopt.h if we need the u8_t and
u16_t datatypes. */
#include "uipopt.h"
#include "psock.h"
/* Next, we define the uip_tcp_appstate_t datatype. This is the state
of our application, and the memory required for this state is
allocated together with each TCP connection. One application state
for each TCP connection. */
typedef struct hello_world_state {
struct psock p;
char inputbuffer[10];
char name[40];
} uip_tcp_appstate_t;
/* Finally we define the application function to be called by uIP. */
void hello_world_appcall(void);
#ifndef UIP_APPCALL
#define UIP_APPCALL hello_world_appcall
#endif /* UIP_APPCALL */
void hello_world_init(void);
#endif /* __HELLO_WORLD_H__ */
/** @} */
/** @} */

View File

@ -0,0 +1 @@
APP_SOURCES += resolv.c

View File

@ -0,0 +1,464 @@
/**
* \addtogroup apps
* @{
*/
/**
* \defgroup resolv DNS resolver
* @{
*
* The uIP DNS resolver functions are used to lookup a hostname and
* map it to a numerical IP address. It maintains a list of resolved
* hostnames that can be queried with the resolv_lookup()
* function. New hostnames can be resolved using the resolv_query()
* function.
*
* When a hostname has been resolved (or found to be non-existant),
* the resolver code calls a callback function called resolv_found()
* that must be implemented by the module that uses the resolver.
*/
/**
* \file
* DNS host name to IP address resolver.
* \author Adam Dunkels <adam@dunkels.com>
*
* This file implements a DNS host name to IP address resolver.
*/
/*
* Copyright (c) 2002-2003, 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. 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: resolv.c,v 1.5 2006/06/11 21:46:37 adam Exp $
*
*/
#include "resolv.h"
#include "uip.h"
#include <string.h>
#ifndef NULL
#define NULL (void *)0
#endif /* NULL */
/** \internal The maximum number of retries when asking for a name. */
#define MAX_RETRIES 8
/** \internal The DNS message header. */
struct dns_hdr {
u16_t id;
u8_t flags1, flags2;
#define DNS_FLAG1_RESPONSE 0x80
#define DNS_FLAG1_OPCODE_STATUS 0x10
#define DNS_FLAG1_OPCODE_INVERSE 0x08
#define DNS_FLAG1_OPCODE_STANDARD 0x00
#define DNS_FLAG1_AUTHORATIVE 0x04
#define DNS_FLAG1_TRUNC 0x02
#define DNS_FLAG1_RD 0x01
#define DNS_FLAG2_RA 0x80
#define DNS_FLAG2_ERR_MASK 0x0f
#define DNS_FLAG2_ERR_NONE 0x00
#define DNS_FLAG2_ERR_NAME 0x03
u16_t numquestions;
u16_t numanswers;
u16_t numauthrr;
u16_t numextrarr;
};
/** \internal The DNS answer message structure. */
struct dns_answer {
/* DNS answer record starts with either a domain name or a pointer
to a name already present somewhere in the packet. */
u16_t type;
u16_t class;
u16_t ttl[2];
u16_t len;
uip_ipaddr_t ipaddr;
};
struct namemap {
#define STATE_UNUSED 0
#define STATE_NEW 1
#define STATE_ASKING 2
#define STATE_DONE 3
#define STATE_ERROR 4
u8_t state;
u8_t tmr;
u8_t retries;
u8_t seqno;
u8_t err;
char name[32];
uip_ipaddr_t ipaddr;
};
#ifndef UIP_CONF_RESOLV_ENTRIES
#define RESOLV_ENTRIES 4
#else /* UIP_CONF_RESOLV_ENTRIES */
#define RESOLV_ENTRIES UIP_CONF_RESOLV_ENTRIES
#endif /* UIP_CONF_RESOLV_ENTRIES */
static struct namemap names[RESOLV_ENTRIES];
static u8_t seqno;
static struct uip_udp_conn *resolv_conn = NULL;
/*---------------------------------------------------------------------------*/
/** \internal
* Walk through a compact encoded DNS name and return the end of it.
*
* \return The end of the name.
*/
/*---------------------------------------------------------------------------*/
static unsigned char *
parse_name(unsigned char *query)
{
unsigned char n;
do {
n = *query++;
while(n > 0) {
/* printf("%c", *query);*/
++query;
--n;
};
/* printf(".");*/
} while(*query != 0);
/* printf("\n");*/
return query + 1;
}
/*---------------------------------------------------------------------------*/
/** \internal
* Runs through the list of names to see if there are any that have
* not yet been queried and, if so, sends out a query.
*/
/*---------------------------------------------------------------------------*/
static void
check_entries(void)
{
register struct dns_hdr *hdr;
char *query, *nptr, *nameptr;
static u8_t i;
static u8_t n;
register struct namemap *namemapptr;
for(i = 0; i < RESOLV_ENTRIES; ++i) {
namemapptr = &names[i];
if(namemapptr->state == STATE_NEW ||
namemapptr->state == STATE_ASKING) {
if(namemapptr->state == STATE_ASKING) {
if(--namemapptr->tmr == 0) {
if(++namemapptr->retries == MAX_RETRIES) {
namemapptr->state = STATE_ERROR;
resolv_found(namemapptr->name, NULL);
continue;
}
namemapptr->tmr = namemapptr->retries;
} else {
/* printf("Timer %d\n", namemapptr->tmr);*/
/* Its timer has not run out, so we move on to next
entry. */
continue;
}
} else {
namemapptr->state = STATE_ASKING;
namemapptr->tmr = 1;
namemapptr->retries = 0;
}
hdr = (struct dns_hdr *)uip_appdata;
memset(hdr, 0, sizeof(struct dns_hdr));
hdr->id = htons(i);
hdr->flags1 = DNS_FLAG1_RD;
hdr->numquestions = HTONS(1);
query = (char *)uip_appdata + 12;
nameptr = namemapptr->name;
--nameptr;
/* Convert hostname into suitable query format. */
do {
++nameptr;
nptr = query;
++query;
for(n = 0; *nameptr != '.' && *nameptr != 0; ++nameptr) {
*query = *nameptr;
++query;
++n;
}
*nptr = n;
} while(*nameptr != 0);
{
static unsigned char endquery[] =
{0,0,1,0,1};
memcpy(query, endquery, 5);
}
uip_udp_send((unsigned char)(query + 5 - (char *)uip_appdata));
break;
}
}
}
/*---------------------------------------------------------------------------*/
/** \internal
* Called when new UDP data arrives.
*/
/*---------------------------------------------------------------------------*/
static void
newdata(void)
{
char *nameptr;
struct dns_answer *ans;
struct dns_hdr *hdr;
static u8_t nquestions, nanswers;
static u8_t i;
register struct namemap *namemapptr;
hdr = (struct dns_hdr *)uip_appdata;
/* printf("ID %d\n", htons(hdr->id));
printf("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE);
printf("Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK);
printf("Num questions %d, answers %d, authrr %d, extrarr %d\n",
htons(hdr->numquestions),
htons(hdr->numanswers),
htons(hdr->numauthrr),
htons(hdr->numextrarr));
*/
/* The ID in the DNS header should be our entry into the name
table. */
i = htons(hdr->id);
namemapptr = &names[i];
if(i < RESOLV_ENTRIES &&
namemapptr->state == STATE_ASKING) {
/* This entry is now finished. */
namemapptr->state = STATE_DONE;
namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
/* Check for error. If so, call callback to inform. */
if(namemapptr->err != 0) {
namemapptr->state = STATE_ERROR;
resolv_found(namemapptr->name, NULL);
return;
}
/* We only care about the question(s) and the answers. The authrr
and the extrarr are simply discarded. */
nquestions = htons(hdr->numquestions);
nanswers = htons(hdr->numanswers);
/* Skip the name in the question. XXX: This should really be
checked agains the name in the question, to be sure that they
match. */
nameptr = parse_name((char *)uip_appdata + 12) + 4;
while(nanswers > 0) {
/* The first byte in the answer resource record determines if it
is a compressed record or a normal one. */
if(*nameptr & 0xc0) {
/* Compressed name. */
nameptr +=2;
/* printf("Compressed anwser\n");*/
} else {
/* Not compressed name. */
nameptr = parse_name((char *)nameptr);
}
ans = (struct dns_answer *)nameptr;
/* printf("Answer: type %x, class %x, ttl %x, length %x\n",
htons(ans->type), htons(ans->class), (htons(ans->ttl[0])
<< 16) | htons(ans->ttl[1]), htons(ans->len));*/
/* Check for IP address type and Internet class. Others are
discarded. */
if(ans->type == HTONS(1) &&
ans->class == HTONS(1) &&
ans->len == HTONS(4)) {
/* printf("IP address %d.%d.%d.%d\n",
htons(ans->ipaddr[0]) >> 8,
htons(ans->ipaddr[0]) & 0xff,
htons(ans->ipaddr[1]) >> 8,
htons(ans->ipaddr[1]) & 0xff);*/
/* XXX: we should really check that this IP address is the one
we want. */
namemapptr->ipaddr[0] = ans->ipaddr[0];
namemapptr->ipaddr[1] = ans->ipaddr[1];
resolv_found(namemapptr->name, namemapptr->ipaddr);
return;
} else {
nameptr = nameptr + 10 + htons(ans->len);
}
--nanswers;
}
}
}
/*---------------------------------------------------------------------------*/
/** \internal
* The main UDP function.
*/
/*---------------------------------------------------------------------------*/
void
resolv_appcall(void)
{
if(uip_udp_conn->rport == HTONS(53)) {
if(uip_poll()) {
check_entries();
}
if(uip_newdata()) {
newdata();
}
}
}
/*---------------------------------------------------------------------------*/
/**
* Queues a name so that a question for the name will be sent out.
*
* \param name The hostname that is to be queried.
*/
/*---------------------------------------------------------------------------*/
void
resolv_query(char *name)
{
static u8_t i;
static u8_t lseq, lseqi;
register struct namemap *nameptr;
lseq = lseqi = 0;
for(i = 0; i < RESOLV_ENTRIES; ++i) {
nameptr = &names[i];
if(nameptr->state == STATE_UNUSED) {
break;
}
if(seqno - nameptr->seqno > lseq) {
lseq = seqno - nameptr->seqno;
lseqi = i;
}
}
if(i == RESOLV_ENTRIES) {
i = lseqi;
nameptr = &names[i];
}
/* printf("Using entry %d\n", i);*/
strcpy(nameptr->name, name);
nameptr->state = STATE_NEW;
nameptr->seqno = seqno;
++seqno;
}
/*---------------------------------------------------------------------------*/
/**
* Look up a hostname in the array of known hostnames.
*
* \note This function only looks in the internal array of known
* hostnames, it does not send out a query for the hostname if none
* was found. The function resolv_query() can be used to send a query
* for a hostname.
*
* \return A pointer to a 4-byte representation of the hostname's IP
* address, or NULL if the hostname was not found in the array of
* hostnames.
*/
/*---------------------------------------------------------------------------*/
u16_t *
resolv_lookup(char *name)
{
static u8_t i;
struct namemap *nameptr;
/* Walk through the list to see if the name is in there. If it is
not, we return NULL. */
for(i = 0; i < RESOLV_ENTRIES; ++i) {
nameptr = &names[i];
if(nameptr->state == STATE_DONE &&
strcmp(name, nameptr->name) == 0) {
return nameptr->ipaddr;
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
/**
* Obtain the currently configured DNS server.
*
* \return A pointer to a 4-byte representation of the IP address of
* the currently configured DNS server or NULL if no DNS server has
* been configured.
*/
/*---------------------------------------------------------------------------*/
u16_t *
resolv_getserver(void)
{
if(resolv_conn == NULL) {
return NULL;
}
return resolv_conn->ripaddr;
}
/*---------------------------------------------------------------------------*/
/**
* Configure which DNS server to use for queries.
*
* \param dnsserver A pointer to a 4-byte representation of the IP
* address of the DNS server to be configured.
*/
/*---------------------------------------------------------------------------*/
void
resolv_conf(u16_t *dnsserver)
{
if(resolv_conn != NULL) {
uip_udp_remove(resolv_conn);
}
resolv_conn = uip_udp_new(dnsserver, HTONS(53));
}
/*---------------------------------------------------------------------------*/
/**
* Initalize the resolver.
*/
/*---------------------------------------------------------------------------*/
void
resolv_init(void)
{
static u8_t i;
for(i = 0; i < RESOLV_ENTRIES; ++i) {
names[i].state = STATE_DONE;
}
}
/*---------------------------------------------------------------------------*/
/** @} */
/** @} */

View File

@ -0,0 +1,75 @@
/**
* \addtogroup resolv
* @{
*/
/**
* \file
* DNS resolver code header file.
* \author Adam Dunkels <adam@dunkels.com>
*/
/*
* Copyright (c) 2002-2003, 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. 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: resolv.h,v 1.4 2006/06/11 21:46:37 adam Exp $
*
*/
#ifndef __RESOLV_H__
#define __RESOLV_H__
typedef int uip_udp_appstate_t;
void resolv_appcall(void);
#define UIP_UDP_APPCALL resolv_appcall
#include "uipopt.h"
/**
* Callback function which is called when a hostname is found.
*
* This function must be implemented by the module that uses the DNS
* resolver. It is called when a hostname is found, or when a hostname
* was not found.
*
* \param name A pointer to the name that was looked up. \param
* ipaddr A pointer to a 4-byte array containing the IP address of the
* hostname, or NULL if the hostname could not be found.
*/
void resolv_found(char *name, u16_t *ipaddr);
/* Functions. */
void resolv_conf(u16_t *dnsserver);
u16_t *resolv_getserver(void);
void resolv_init(void);
u16_t *resolv_lookup(char *name);
void resolv_query(char *name);
#endif /* __RESOLV_H__ */
/** @} */

View File

@ -0,0 +1 @@
APP_SOURCES += smtp.c smtp-strings.c memb.c

View File

@ -0,0 +1,40 @@
#!/usr/bin/perl
sub stringify {
my $name = shift(@_);
open(OUTPUTC, "> $name.c");
open(OUTPUTH, "> $name.h");
open(FILE, "$name");
while(<FILE>) {
if(/(.+) "(.+)"/) {
$var = $1;
$data = $2;
$datan = $data;
$datan =~ s/\\r/\r/g;
$datan =~ s/\\n/\n/g;
$datan =~ s/\\01/\01/g;
$datan =~ s/\\0/\0/g;
printf(OUTPUTC "const char $var\[%d] = \n", length($datan) + 1);
printf(OUTPUTC "/* \"$data\" */\n");
printf(OUTPUTC "{");
for($j = 0; $j < length($datan); $j++) {
printf(OUTPUTC "%#02x, ", unpack("C", substr($datan, $j, 1)));
}
printf(OUTPUTC "};\n");
printf(OUTPUTH "extern const char $var\[%d];\n", length($datan) + 1);
}
}
close(OUTPUTC);
close(OUTPUTH);
}
stringify("smtp-strings");
exit 0;

View File

@ -0,0 +1,11 @@
smtp_220 "220"
smtp_helo "HELO "
smtp_mail_from "MAIL FROM: "
smtp_rcpt_to "RCPT TO: "
smtp_data "DATA\r\n"
smtp_to "To: "
smtp_from "From: "
smtp_subject "Subject: "
smtp_quit "QUIT\r\n"
smtp_crnl "\r\n"
smtp_crnlperiodcrnl "\r\n.\r\n"

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2004, 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. 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: smtp-strings.c,v 1.3 2006/06/11 21:46:37 adam Exp $
*/
const char smtp_220[4] =
/* "220" */
{0x32, 0x32, 0x30, };
const char smtp_helo[6] =
/* "HELO " */
{0x48, 0x45, 0x4c, 0x4f, 0x20, };
const char smtp_mail_from[12] =
/* "MAIL FROM: " */
{0x4d, 0x41, 0x49, 0x4c, 0x20, 0x46, 0x52, 0x4f, 0x4d, 0x3a, 0x20, };
const char smtp_rcpt_to[10] =
/* "RCPT TO: " */
{0x52, 0x43, 0x50, 0x54, 0x20, 0x54, 0x4f, 0x3a, 0x20, };
const char smtp_data[7] =
/* "DATA\r\n" */
{0x44, 0x41, 0x54, 0x41, 0xd, 0xa, };
const char smtp_to[5] =
/* "To: " */
{0x54, 0x6f, 0x3a, 0x20, };
const char smtp_cc[5] =
/* "Cc: " */
{0x43, 0x63, 0x3a, 0x20, };
const char smtp_from[7] =
/* "From: " */
{0x46, 0x72, 0x6f, 0x6d, 0x3a, 0x20, };
const char smtp_subject[10] =
/* "Subject: " */
{0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, };
const char smtp_quit[7] =
/* "QUIT\r\n" */
{0x51, 0x55, 0x49, 0x54, 0xd, 0xa, };
const char smtp_crnl[3] =
/* "\r\n" */
{0xd, 0xa, };
const char smtp_crnlperiodcrnl[6] =
/* "\r\n.\r\n" */
{0xd, 0xa, 0x2e, 0xd, 0xa, };

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2004, 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. 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: smtp-strings.h,v 1.3 2006/06/11 21:46:37 adam Exp $
*/
extern const char smtp_220[4];
extern const char smtp_helo[6];
extern const char smtp_mail_from[12];
extern const char smtp_rcpt_to[10];
extern const char smtp_data[7];
extern const char smtp_to[5];
extern const char smtp_cc[5];
extern const char smtp_from[7];
extern const char smtp_subject[10];
extern const char smtp_quit[7];
extern const char smtp_crnl[3];
extern const char smtp_crnlperiodcrnl[6];

View File

@ -0,0 +1,262 @@
/**
* \addtogroup apps
* @{
*/
/**
* \defgroup smtp SMTP E-mail sender
* @{
*
* The Simple Mail Transfer Protocol (SMTP) as defined by RFC821 is
* the standard way of sending and transfering e-mail on the
* Internet. This simple example implementation is intended as an
* example of how to implement protocols in uIP, and is able to send
* out e-mail but has not been extensively tested.
*/
/**
* \file
* SMTP example implementation
* \author Adam Dunkels <adam@dunkels.com>
*/
/*
* Copyright (c) 2004, 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. 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.
*
* This file is part of the uIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: smtp.c,v 1.4 2006/06/11 21:46:37 adam Exp $
*/
#include "smtp.h"
#include "smtp-strings.h"
#include "psock.h"
#include "uip.h"
#include <string.h>
static struct smtp_state s;
static char *localhostname;
static uip_ipaddr_t smtpserver;
#define ISO_nl 0x0a
#define ISO_cr 0x0d
#define ISO_period 0x2e
#define ISO_2 0x32
#define ISO_3 0x33
#define ISO_4 0x34
#define ISO_5 0x35
/*---------------------------------------------------------------------------*/
static
PT_THREAD(smtp_thread(void))
{
PSOCK_BEGIN(&s.psock);
PSOCK_READTO(&s.psock, ISO_nl);
if(strncmp(s.inputbuffer, smtp_220, 3) != 0) {
PSOCK_CLOSE(&s.psock);
smtp_done(2);
PSOCK_EXIT(&s.psock);
}
PSOCK_SEND_STR(&s.psock, (char *)smtp_helo);
PSOCK_SEND_STR(&s.psock, localhostname);
PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
PSOCK_READTO(&s.psock, ISO_nl);
if(s.inputbuffer[0] != ISO_2) {
PSOCK_CLOSE(&s.psock);
smtp_done(3);
PSOCK_EXIT(&s.psock);
}
PSOCK_SEND_STR(&s.psock, (char *)smtp_mail_from);
PSOCK_SEND_STR(&s.psock, s.from);
PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
PSOCK_READTO(&s.psock, ISO_nl);
if(s.inputbuffer[0] != ISO_2) {
PSOCK_CLOSE(&s.psock);
smtp_done(4);
PSOCK_EXIT(&s.psock);
}
PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to);
PSOCK_SEND_STR(&s.psock, s.to);
PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
PSOCK_READTO(&s.psock, ISO_nl);
if(s.inputbuffer[0] != ISO_2) {
PSOCK_CLOSE(&s.psock);
smtp_done(5);
PSOCK_EXIT(&s.psock);
}
if(s.cc != 0) {
PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to);
PSOCK_SEND_STR(&s.psock, s.cc);
PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
PSOCK_READTO(&s.psock, ISO_nl);
if(s.inputbuffer[0] != ISO_2) {
PSOCK_CLOSE(&s.psock);
smtp_done(6);
PSOCK_EXIT(&s.psock);
}
}
PSOCK_SEND_STR(&s.psock, (char *)smtp_data);
PSOCK_READTO(&s.psock, ISO_nl);
if(s.inputbuffer[0] != ISO_3) {
PSOCK_CLOSE(&s.psock);
smtp_done(7);
PSOCK_EXIT(&s.psock);
}
PSOCK_SEND_STR(&s.psock, (char *)smtp_to);
PSOCK_SEND_STR(&s.psock, s.to);
PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
if(s.cc != 0) {
PSOCK_SEND_STR(&s.psock, (char *)smtp_cc);
PSOCK_SEND_STR(&s.psock, s.cc);
PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
}
PSOCK_SEND_STR(&s.psock, (char *)smtp_from);
PSOCK_SEND_STR(&s.psock, s.from);
PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
PSOCK_SEND_STR(&s.psock, (char *)smtp_subject);
PSOCK_SEND_STR(&s.psock, s.subject);
PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
PSOCK_SEND(&s.psock, s.msg, s.msglen);
PSOCK_SEND_STR(&s.psock, (char *)smtp_crnlperiodcrnl);
PSOCK_READTO(&s.psock, ISO_nl);
if(s.inputbuffer[0] != ISO_2) {
PSOCK_CLOSE(&s.psock);
smtp_done(8);
PSOCK_EXIT(&s.psock);
}
PSOCK_SEND_STR(&s.psock, (char *)smtp_quit);
smtp_done(SMTP_ERR_OK);
PSOCK_END(&s.psock);
}
/*---------------------------------------------------------------------------*/
void
smtp_appcall(void)
{
if(uip_closed()) {
s.connected = 0;
return;
}
if(uip_aborted() || uip_timedout()) {
s.connected = 0;
smtp_done(1);
return;
}
smtp_thread();
}
/*---------------------------------------------------------------------------*/
/**
* Specificy an SMTP server and hostname.
*
* This function is used to configure the SMTP module with an SMTP
* server and the hostname of the host.
*
* \param lhostname The hostname of the uIP host.
*
* \param server A pointer to a 4-byte array representing the IP
* address of the SMTP server to be configured.
*/
void
smtp_configure(char *lhostname, void *server)
{
localhostname = lhostname;
uip_ipaddr_copy(smtpserver, server);
}
/*---------------------------------------------------------------------------*/
/**
* Send an e-mail.
*
* \param to The e-mail address of the receiver of the e-mail.
* \param cc The e-mail address of the CC: receivers of the e-mail.
* \param from The e-mail address of the sender of the e-mail.
* \param subject The subject of the e-mail.
* \param msg The actual e-mail message.
* \param msglen The length of the e-mail message.
*/
unsigned char
smtp_send(char *to, char *cc, char *from,
char *subject, char *msg, u16_t msglen)
{
struct uip_conn *conn;
conn = uip_connect(smtpserver, HTONS(25));
if(conn == NULL) {
return 0;
}
s.connected = 1;
s.to = to;
s.cc = cc;
s.from = from;
s.subject = subject;
s.msg = msg;
s.msglen = msglen;
PSOCK_INIT(&s.psock, s.inputbuffer, sizeof(s.inputbuffer));
return 1;
}
/*---------------------------------------------------------------------------*/
void
smtp_init(void)
{
s.connected = 0;
}
/*---------------------------------------------------------------------------*/
/** @} */
/** @} */

View File

@ -0,0 +1,103 @@
/**
* \addtogroup smtp
* @{
*/
/**
* \file
* SMTP header file
* \author Adam Dunkels <adam@dunkels.com>
*/
/*
* Copyright (c) 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. 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: smtp.h,v 1.4 2006/06/11 21:46:37 adam Exp $
*
*/
#ifndef __SMTP_H__
#define __SMTP_H__
#include "uipopt.h"
/**
* Error number that signifies a non-error condition.
*/
#define SMTP_ERR_OK 0
/**
* Callback function that is called when an e-mail transmission is
* done.
*
* This function must be implemented by the module that uses the SMTP
* module.
*
* \param error The number of the error if an error occured, or
* SMTP_ERR_OK.
*/
void smtp_done(unsigned char error);
void smtp_init(void);
/* Functions. */
void smtp_configure(char *localhostname, u16_t *smtpserver);
unsigned char smtp_send(char *to, char *from,
char *subject, char *msg,
u16_t msglen);
#define SMTP_SEND(to, cc, from, subject, msg) \
smtp_send(to, cc, from, subject, msg, strlen(msg))
void smtp_appcall(void);
struct smtp_state {
u8_t state;
char *to;
char *from;
char *subject;
char *msg;
u16_t msglen;
u16_t sentlen, textlen;
u16_t sendptr;
};
#ifndef UIP_APPCALL
#define UIP_APPCALL smtp_appcall
#endif
typedef struct smtp_state uip_tcp_appstate_t;
#endif /* __SMTP_H__ */
/** @} */

View File

@ -0,0 +1 @@
APP_SOURCES += telnetd.c shell.c memb.c

View File

@ -0,0 +1,123 @@
/*
* Copyright (c) 2003, 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. 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: shell.c,v 1.1 2006/06/07 09:43:54 adam Exp $
*
*/
#include "shell.h"
#include <string.h>
struct ptentry {
char *commandstr;
void (* pfunc)(char *str);
};
#define SHELL_PROMPT "uIP 1.0> "
/*---------------------------------------------------------------------------*/
static void
parse(register char *str, struct ptentry *t)
{
struct ptentry *p;
for(p = t; p->commandstr != NULL; ++p) {
if(strncmp(p->commandstr, str, strlen(p->commandstr)) == 0) {
break;
}
}
p->pfunc(str);
}
/*---------------------------------------------------------------------------*/
static void
inttostr(register char *str, unsigned int i)
{
str[0] = '0' + i / 100;
if(str[0] == '0') {
str[0] = ' ';
}
str[1] = '0' + (i / 10) % 10;
if(str[0] == ' ' && str[1] == '0') {
str[1] = ' ';
}
str[2] = '0' + i % 10;
str[3] = ' ';
str[4] = 0;
}
/*---------------------------------------------------------------------------*/
static void
help(char *str)
{
shell_output("Available commands:", "");
shell_output("stats - show network statistics", "");
shell_output("conn - show TCP connections", "");
shell_output("help, ? - show help", "");
shell_output("exit - exit shell", "");
}
/*---------------------------------------------------------------------------*/
static void
unknown(char *str)
{
if(strlen(str) > 0) {
shell_output("Unknown command: ", str);
}
}
/*---------------------------------------------------------------------------*/
static struct ptentry parsetab[] =
{{"stats", help},
{"conn", help},
{"help", help},
{"exit", shell_quit},
{"?", help},
/* Default action */
{NULL, unknown}};
/*---------------------------------------------------------------------------*/
void
shell_init(void)
{
}
/*---------------------------------------------------------------------------*/
void
shell_start(void)
{
shell_output("uIP command shell", "");
shell_output("Type '?' and return for help", "");
shell_prompt(SHELL_PROMPT);
}
/*---------------------------------------------------------------------------*/
void
shell_input(char *cmd)
{
parse(cmd, parsetab);
shell_prompt(SHELL_PROMPT);
}
/*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,104 @@
/**
* \file
* Interface for the Contiki shell.
* \author Adam Dunkels <adam@dunkels.com>
*
* Some of the functions declared in this file must be implemented as
* a shell back-end in the architecture specific files of a Contiki
* port.
*/
/*
* Copyright (c) 2003, 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. 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 Contiki desktop OS.
*
* $Id: shell.h,v 1.1 2006/06/07 09:43:54 adam Exp $
*
*/
#ifndef __SHELL_H__
#define __SHELL_H__
/**
* Initialize the shell.
*
* Called when the shell front-end process starts. This function may
* be used to start listening for signals.
*/
void shell_init(void);
/**
* Start the shell back-end.
*
* Called by the front-end when a new shell is started.
*/
void shell_start(void);
/**
* Process a shell command.
*
* This function will be called by the shell GUI / telnet server whan
* a command has been entered that should be processed by the shell
* back-end.
*
* \param command The command to be processed.
*/
void shell_input(char *command);
/**
* Quit the shell.
*
*/
void shell_quit(char *);
/**
* Print a string to the shell window.
*
* This function is implemented by the shell GUI / telnet server and
* can be called by the shell back-end to output a string in the
* shell window. The string is automatically appended with a linebreak.
*
* \param str1 The first half of the string to be output.
* \param str2 The second half of the string to be output.
*/
void shell_output(char *str1, char *str2);
/**
* Print a prompt to the shell window.
*
* This function can be used by the shell back-end to print out a
* prompt to the shell window.
*
* \param prompt The prompt to be printed.
*
*/
void shell_prompt(char *prompt);
#endif /* __SHELL_H__ */

View File

@ -0,0 +1,350 @@
/*
* Copyright (c) 2003, 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. 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: telnetd.c,v 1.2 2006/06/07 09:43:54 adam Exp $
*
*/
#include "uip.h"
#include "telnetd.h"
#include "memb.h"
#include "shell.h"
#include <string.h>
#define ISO_nl 0x0a
#define ISO_cr 0x0d
struct telnetd_line {
char line[TELNETD_CONF_LINELEN];
};
MEMB(linemem, struct telnetd_line, TELNETD_CONF_NUMLINES);
#define STATE_NORMAL 0
#define STATE_IAC 1
#define STATE_WILL 2
#define STATE_WONT 3
#define STATE_DO 4
#define STATE_DONT 5
#define STATE_CLOSE 6
static struct telnetd_state s;
#define TELNET_IAC 255
#define TELNET_WILL 251
#define TELNET_WONT 252
#define TELNET_DO 253
#define TELNET_DONT 254
/*---------------------------------------------------------------------------*/
static char *
alloc_line(void)
{
return memb_alloc(&linemem);
}
/*---------------------------------------------------------------------------*/
static void
dealloc_line(char *line)
{
memb_free(&linemem, line);
}
/*---------------------------------------------------------------------------*/
void
shell_quit(char *str)
{
s.state = STATE_CLOSE;
}
/*---------------------------------------------------------------------------*/
static void
sendline(char *line)
{
static unsigned int i;
for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
if(s.lines[i] == NULL) {
s.lines[i] = line;
break;
}
}
if(i == TELNETD_CONF_NUMLINES) {
dealloc_line(line);
}
}
/*---------------------------------------------------------------------------*/
void
shell_prompt(char *str)
{
char *line;
line = alloc_line();
if(line != NULL) {
strncpy(line, str, TELNETD_CONF_LINELEN);
/* petsciiconv_toascii(line, TELNETD_CONF_LINELEN);*/
sendline(line);
}
}
/*---------------------------------------------------------------------------*/
void
shell_output(char *str1, char *str2)
{
static unsigned len;
char *line;
line = alloc_line();
if(line != NULL) {
len = strlen(str1);
strncpy(line, str1, TELNETD_CONF_LINELEN);
if(len < TELNETD_CONF_LINELEN) {
strncpy(line + len, str2, TELNETD_CONF_LINELEN - len);
}
len = strlen(line);
if(len < TELNETD_CONF_LINELEN - 2) {
line[len] = ISO_cr;
line[len+1] = ISO_nl;
line[len+2] = 0;
}
/* petsciiconv_toascii(line, TELNETD_CONF_LINELEN);*/
sendline(line);
}
}
/*---------------------------------------------------------------------------*/
void
telnetd_init(void)
{
uip_listen(HTONS(23));
memb_init(&linemem);
shell_init();
}
/*---------------------------------------------------------------------------*/
static void
acked(void)
{
static unsigned int i;
while(s.numsent > 0) {
dealloc_line(s.lines[0]);
for(i = 1; i < TELNETD_CONF_NUMLINES; ++i) {
s.lines[i - 1] = s.lines[i];
}
s.lines[TELNETD_CONF_NUMLINES - 1] = NULL;
--s.numsent;
}
}
/*---------------------------------------------------------------------------*/
static void
senddata(void)
{
static char *bufptr, *lineptr;
static int buflen, linelen;
bufptr = uip_appdata;
buflen = 0;
for(s.numsent = 0; s.numsent < TELNETD_CONF_NUMLINES &&
s.lines[s.numsent] != NULL ; ++s.numsent) {
lineptr = s.lines[s.numsent];
linelen = strlen(lineptr);
if(linelen > TELNETD_CONF_LINELEN) {
linelen = TELNETD_CONF_LINELEN;
}
if(buflen + linelen < uip_mss()) {
memcpy(bufptr, lineptr, linelen);
bufptr += linelen;
buflen += linelen;
} else {
break;
}
}
uip_send(uip_appdata, buflen);
}
/*---------------------------------------------------------------------------*/
static void
closed(void)
{
static unsigned int i;
for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
if(s.lines[i] != NULL) {
dealloc_line(s.lines[i]);
}
}
}
/*---------------------------------------------------------------------------*/
static void
get_char(u8_t c)
{
if(c == ISO_cr) {
return;
}
s.buf[(int)s.bufptr] = c;
if(s.buf[(int)s.bufptr] == ISO_nl ||
s.bufptr == sizeof(s.buf) - 1) {
if(s.bufptr > 0) {
s.buf[(int)s.bufptr] = 0;
/* petsciiconv_topetscii(s.buf, TELNETD_CONF_LINELEN);*/
}
shell_input(s.buf);
s.bufptr = 0;
} else {
++s.bufptr;
}
}
/*---------------------------------------------------------------------------*/
static void
sendopt(u8_t option, u8_t value)
{
char *line;
line = alloc_line();
if(line != NULL) {
line[0] = TELNET_IAC;
line[1] = option;
line[2] = value;
line[3] = 0;
sendline(line);
}
}
/*---------------------------------------------------------------------------*/
static void
newdata(void)
{
u16_t len;
u8_t c;
char *dataptr;
len = uip_datalen();
dataptr = (char *)uip_appdata;
while(len > 0 && s.bufptr < sizeof(s.buf)) {
c = *dataptr;
++dataptr;
--len;
switch(s.state) {
case STATE_IAC:
if(c == TELNET_IAC) {
get_char(c);
s.state = STATE_NORMAL;
} else {
switch(c) {
case TELNET_WILL:
s.state = STATE_WILL;
break;
case TELNET_WONT:
s.state = STATE_WONT;
break;
case TELNET_DO:
s.state = STATE_DO;
break;
case TELNET_DONT:
s.state = STATE_DONT;
break;
default:
s.state = STATE_NORMAL;
break;
}
}
break;
case STATE_WILL:
/* Reply with a DONT */
sendopt(TELNET_DONT, c);
s.state = STATE_NORMAL;
break;
case STATE_WONT:
/* Reply with a DONT */
sendopt(TELNET_DONT, c);
s.state = STATE_NORMAL;
break;
case STATE_DO:
/* Reply with a WONT */
sendopt(TELNET_WONT, c);
s.state = STATE_NORMAL;
break;
case STATE_DONT:
/* Reply with a WONT */
sendopt(TELNET_WONT, c);
s.state = STATE_NORMAL;
break;
case STATE_NORMAL:
if(c == TELNET_IAC) {
s.state = STATE_IAC;
} else {
get_char(c);
}
break;
}
}
}
/*---------------------------------------------------------------------------*/
void
telnetd_appcall(void)
{
static unsigned int i;
if(uip_connected()) {
/* tcp_markconn(uip_conn, &s);*/
for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
s.lines[i] = NULL;
}
s.bufptr = 0;
s.state = STATE_NORMAL;
shell_start();
}
if(s.state == STATE_CLOSE) {
s.state = STATE_NORMAL;
uip_close();
return;
}
if(uip_closed() ||
uip_aborted() ||
uip_timedout()) {
closed();
}
if(uip_acked()) {
acked();
}
if(uip_newdata()) {
newdata();
}
if(uip_rexmit() ||
uip_newdata() ||
uip_acked() ||
uip_connected() ||
uip_poll()) {
senddata();
}
}
/*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2003, 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. 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: telnetd.h,v 1.2 2006/06/07 09:43:54 adam Exp $
*
*/
#ifndef __TELNETD_H__
#define __TELNETD_H__
#include "uipopt.h"
void telnetd_appcall(void);
#ifndef TELNETD_CONF_LINELEN
#define TELNETD_CONF_LINELEN 40
#endif
#ifndef TELNETD_CONF_NUMLINES
#define TELNETD_CONF_NUMLINES 16
#endif
struct telnetd_state {
char *lines[TELNETD_CONF_NUMLINES];
char buf[TELNETD_CONF_LINELEN];
char bufptr;
u8_t numsent;
u8_t state;
};
typedef struct telnetd_state uip_tcp_appstate_t;
#ifndef UIP_APPCALL
#define UIP_APPCALL telnetd_appcall
#endif
#endif /* __TELNETD_H__ */

View File

@ -0,0 +1 @@
APP_SOURCES += webclient-strings.c webclient.c

View File

@ -0,0 +1,40 @@
#!/usr/bin/perl
sub stringify {
my $name = shift(@_);
open(OUTPUTC, "> $name.c");
open(OUTPUTH, "> $name.h");
open(FILE, "$name");
while(<FILE>) {
if(/(.+) "(.+)"/) {
$var = $1;
$data = $2;
$datan = $data;
$datan =~ s/\\r/\r/g;
$datan =~ s/\\n/\n/g;
$datan =~ s/\\01/\01/g;
$datan =~ s/\\0/\0/g;
printf(OUTPUTC "const char $var\[%d] = \n", length($datan) + 1);
printf(OUTPUTC "/* \"$data\" */\n");
printf(OUTPUTC "{");
for($j = 0; $j < length($datan); $j++) {
printf(OUTPUTC "%#02x, ", unpack("C", substr($datan, $j, 1)));
}
printf(OUTPUTC "0 };\n");
printf(OUTPUTH "extern const char $var\[%d];\n", length($datan) + 1);
}
}
close(OUTPUTC);
close(OUTPUTH);
}
stringify("webclient-strings");
exit 0;

View File

@ -0,0 +1,31 @@
http_http "http://"
http_200 "200 "
http_301 "301 "
http_302 "302 "
http_get "GET "
http_10 "HTTP/1.0"
http_11 "HTTP/1.1"
http_content_type "content-type: "
http_texthtml "text/html"
http_location "location: "
http_host "host: "
http_crnl "\r\n"
http_index_html "/index.html"
http_404_html "/404.html"
http_content_type_html "Content-type: text/html\r\n\r\n"
http_content_type_css "Content-type: text/css\r\n\r\n"
http_content_type_text "Content-type: text/text\r\n\r\n"
http_content_type_png "Content-type: image/png\r\n\r\n"
http_content_type_gif "Content-type: image/gif\r\n\r\n"
http_content_type_jpg "Content-type: image/jpeg\r\n\r\n"
http_content_type_binary "Content-type: application/octet-stream\r\n\r\n"
http_html ".html"
http_shtml ".shtml"
http_htm ".htm"
http_css ".css"
http_png ".png"
http_gif ".gif"
http_jpg ".jpg"
http_text ".text"
http_txt ".txt"
http_user_agent_fields "Connection: close\r\nUser-Agent: uIP/1.0 (; http://www.sics.se/~adam/uip/)\r\n\r\n"

View File

@ -0,0 +1,93 @@
const char http_http[8] =
/* "http://" */
{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0 };
const char http_200[5] =
/* "200 " */
{0x32, 0x30, 0x30, 0x20, 0 };
const char http_301[5] =
/* "301 " */
{0x33, 0x30, 0x31, 0x20, 0 };
const char http_302[5] =
/* "302 " */
{0x33, 0x30, 0x32, 0x20, 0 };
const char http_get[5] =
/* "GET " */
{0x47, 0x45, 0x54, 0x20, 0 };
const char http_10[9] =
/* "HTTP/1.0" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0 };
const char http_11[9] =
/* "HTTP/1.1" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0 };
const char http_content_type[15] =
/* "content-type: " */
{0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0 };
const char http_texthtml[10] =
/* "text/html" */
{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0 };
const char http_location[11] =
/* "location: " */
{0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0 };
const char http_host[7] =
/* "host: " */
{0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0 };
const char http_crnl[3] =
/* "\r\n" */
{0xd, 0xa, 0 };
const char http_index_html[12] =
/* "/index.html" */
{0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0 };
const char http_404_html[10] =
/* "/404.html" */
{0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0 };
const char http_content_type_html[28] =
/* "Content-type: text/html\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, 0 };
const char http_content_type_css [27] =
/* "Content-type: text/css\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0xd, 0xa, 0xd, 0xa, 0 };
const char http_content_type_text[28] =
/* "Content-type: text/text\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x78, 0x74, 0xd, 0xa, 0xd, 0xa, 0 };
const char http_content_type_png [28] =
/* "Content-type: image/png\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 0xd, 0xa, 0 };
const char http_content_type_gif [28] =
/* "Content-type: image/gif\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0xd, 0xa, 0xd, 0xa, 0 };
const char http_content_type_jpg [29] =
/* "Content-type: image/jpeg\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0xd, 0xa, 0xd, 0xa, 0 };
const char http_content_type_binary[43] =
/* "Content-type: application/octet-stream\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xd, 0xa, 0xd, 0xa, 0 };
const char http_html[6] =
/* ".html" */
{0x2e, 0x68, 0x74, 0x6d, 0x6c, 0 };
const char http_shtml[7] =
/* ".shtml" */
{0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0 };
const char http_htm[5] =
/* ".htm" */
{0x2e, 0x68, 0x74, 0x6d, 0 };
const char http_css[5] =
/* ".css" */
{0x2e, 0x63, 0x73, 0x73, 0 };
const char http_png[5] =
/* ".png" */
{0x2e, 0x70, 0x6e, 0x67, 0 };
const char http_gif[5] =
/* ".gif" */
{0x2e, 0x67, 0x69, 0x66, 0 };
const char http_jpg[5] =
/* ".jpg" */
{0x2e, 0x6a, 0x70, 0x67, 0 };
const char http_text[6] =
/* ".text" */
{0x2e, 0x74, 0x65, 0x78, 0x74, 0 };
const char http_txt[5] =
/* ".txt" */
{0x2e, 0x74, 0x78, 0x74, 0 };
const char http_user_agent_fields[77] =
/* "Connection: close\r\nUser-Agent: uIP/1.0 (; http://www.sics.se/~adam/uip/)\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x28, 0x3b, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0xd, 0xa, 0 };

View File

@ -0,0 +1,31 @@
extern const char http_http[8];
extern const char http_200[5];
extern const char http_301[5];
extern const char http_302[5];
extern const char http_get[5];
extern const char http_10[9];
extern const char http_11[9];
extern const char http_content_type[15];
extern const char http_texthtml[10];
extern const char http_location[11];
extern const char http_host[7];
extern const char http_crnl[3];
extern const char http_index_html[12];
extern const char http_404_html[10];
extern const char http_content_type_html[28];
extern const char http_content_type_css [27];
extern const char http_content_type_text[28];
extern const char http_content_type_png [28];
extern const char http_content_type_gif [28];
extern const char http_content_type_jpg [29];
extern const char http_content_type_binary[43];
extern const char http_html[6];
extern const char http_shtml[7];
extern const char http_htm[5];
extern const char http_css[5];
extern const char http_png[5];
extern const char http_gif[5];
extern const char http_jpg[5];
extern const char http_text[6];
extern const char http_txt[5];
extern const char http_user_agent_fields[77];

View File

@ -0,0 +1,439 @@
/**
* \addtogroup apps
* @{
*/
/**
* \defgroup webclient Web client
* @{
*
* This example shows a HTTP client that is able to download web pages
* and files from web servers. It requires a number of callback
* functions to be implemented by the module that utilizes the code:
* webclient_datahandler(), webclient_connected(),
* webclient_timedout(), webclient_aborted(), webclient_closed().
*/
/**
* \file
* Implementation of the HTTP client.
* \author Adam Dunkels <adam@dunkels.com>
*/
/*
* Copyright (c) 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. 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: webclient.c,v 1.2 2006/06/11 21:46:37 adam Exp $
*
*/
#include "uip.h"
#include "uiplib.h"
#include "webclient.h"
#include "resolv.h"
#include <string.h>
#define WEBCLIENT_TIMEOUT 100
#define WEBCLIENT_STATE_STATUSLINE 0
#define WEBCLIENT_STATE_HEADERS 1
#define WEBCLIENT_STATE_DATA 2
#define WEBCLIENT_STATE_CLOSE 3
#define HTTPFLAG_NONE 0
#define HTTPFLAG_OK 1
#define HTTPFLAG_MOVED 2
#define HTTPFLAG_ERROR 3
#define ISO_nl 0x0a
#define ISO_cr 0x0d
#define ISO_space 0x20
static struct webclient_state s;
/*-----------------------------------------------------------------------------------*/
char *
webclient_mimetype(void)
{
return s.mimetype;
}
/*-----------------------------------------------------------------------------------*/
char *
webclient_filename(void)
{
return s.file;
}
/*-----------------------------------------------------------------------------------*/
char *
webclient_hostname(void)
{
return s.host;
}
/*-----------------------------------------------------------------------------------*/
unsigned short
webclient_port(void)
{
return s.port;
}
/*-----------------------------------------------------------------------------------*/
void
webclient_init(void)
{
}
/*-----------------------------------------------------------------------------------*/
static void
init_connection(void)
{
s.state = WEBCLIENT_STATE_STATUSLINE;
s.getrequestleft = sizeof(http_get) - 1 + 1 +
sizeof(http_10) - 1 +
sizeof(http_crnl) - 1 +
sizeof(http_host) - 1 +
sizeof(http_crnl) - 1 +
strlen(http_user_agent_fields) +
strlen(s.file) + strlen(s.host);
s.getrequestptr = 0;
s.httpheaderlineptr = 0;
}
/*-----------------------------------------------------------------------------------*/
void
webclient_close(void)
{
s.state = WEBCLIENT_STATE_CLOSE;
}
/*-----------------------------------------------------------------------------------*/
unsigned char
webclient_get(char *host, u16_t port, char *file)
{
struct uip_conn *conn;
uip_ipaddr_t *ipaddr;
static uip_ipaddr_t addr;
/* First check if the host is an IP address. */
ipaddr = &addr;
if(uiplib_ipaddrconv(host, (unsigned char *)addr) == 0) {
ipaddr = (uip_ipaddr_t *)resolv_lookup(host);
if(ipaddr == NULL) {
return 0;
}
}
conn = uip_connect(ipaddr, htons(port));
if(conn == NULL) {
return 0;
}
s.port = port;
strncpy(s.file, file, sizeof(s.file));
strncpy(s.host, host, sizeof(s.host));
init_connection();
return 1;
}
/*-----------------------------------------------------------------------------------*/
static unsigned char *
copy_string(unsigned char *dest,
const unsigned char *src, unsigned char len)
{
strncpy(dest, src, len);
return dest + len;
}
/*-----------------------------------------------------------------------------------*/
static void
senddata(void)
{
u16_t len;
char *getrequest;
char *cptr;
if(s.getrequestleft > 0) {
cptr = getrequest = (char *)uip_appdata;
cptr = copy_string(cptr, http_get, sizeof(http_get) - 1);
cptr = copy_string(cptr, s.file, strlen(s.file));
*cptr++ = ISO_space;
cptr = copy_string(cptr, http_10, sizeof(http_10) - 1);
cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1);
cptr = copy_string(cptr, http_host, sizeof(http_host) - 1);
cptr = copy_string(cptr, s.host, strlen(s.host));
cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1);
cptr = copy_string(cptr, http_user_agent_fields,
strlen(http_user_agent_fields));
len = s.getrequestleft > uip_mss()?
uip_mss():
s.getrequestleft;
uip_send(&(getrequest[s.getrequestptr]), len);
}
}
/*-----------------------------------------------------------------------------------*/
static void
acked(void)
{
u16_t len;
if(s.getrequestleft > 0) {
len = s.getrequestleft > uip_mss()?
uip_mss():
s.getrequestleft;
s.getrequestleft -= len;
s.getrequestptr += len;
}
}
/*-----------------------------------------------------------------------------------*/
static u16_t
parse_statusline(u16_t len)
{
char *cptr;
while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) {
s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata;
++((char *)uip_appdata);
--len;
if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
if((strncmp(s.httpheaderline, http_10,
sizeof(http_10) - 1) == 0) ||
(strncmp(s.httpheaderline, http_11,
sizeof(http_11) - 1) == 0)) {
cptr = &(s.httpheaderline[9]);
s.httpflag = HTTPFLAG_NONE;
if(strncmp(cptr, http_200, sizeof(http_200) - 1) == 0) {
/* 200 OK */
s.httpflag = HTTPFLAG_OK;
} else if(strncmp(cptr, http_301, sizeof(http_301) - 1) == 0 ||
strncmp(cptr, http_302, sizeof(http_302) - 1) == 0) {
/* 301 Moved permanently or 302 Found. Location: header line
will contain thw new location. */
s.httpflag = HTTPFLAG_MOVED;
} else {
s.httpheaderline[s.httpheaderlineptr - 1] = 0;
}
} else {
uip_abort();
webclient_aborted();
return 0;
}
/* We're done parsing the status line, so we reset the pointer
and start parsing the HTTP headers.*/
s.httpheaderlineptr = 0;
s.state = WEBCLIENT_STATE_HEADERS;
break;
} else {
++s.httpheaderlineptr;
}
}
return len;
}
/*-----------------------------------------------------------------------------------*/
static char
casecmp(char *str1, const char *str2, char len)
{
static char c;
while(len > 0) {
c = *str1;
/* Force lower-case characters. */
if(c & 0x40) {
c |= 0x20;
}
if(*str2 != c) {
return 1;
}
++str1;
++str2;
--len;
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
static u16_t
parse_headers(u16_t len)
{
char *cptr;
static unsigned char i;
while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) {
s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata;
++((char *)uip_appdata);
--len;
if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
/* We have an entire HTTP header line in s.httpheaderline, so
we parse it. */
if(s.httpheaderline[0] == ISO_cr) {
/* This was the last header line (i.e., and empty "\r\n"), so
we are done with the headers and proceed with the actual
data. */
s.state = WEBCLIENT_STATE_DATA;
return len;
}
s.httpheaderline[s.httpheaderlineptr - 1] = 0;
/* Check for specific HTTP header fields. */
if(casecmp(s.httpheaderline, http_content_type,
sizeof(http_content_type) - 1) == 0) {
/* Found Content-type field. */
cptr = strchr(s.httpheaderline, ';');
if(cptr != NULL) {
*cptr = 0;
}
strncpy(s.mimetype, s.httpheaderline +
sizeof(http_content_type) - 1, sizeof(s.mimetype));
} else if(casecmp(s.httpheaderline, http_location,
sizeof(http_location) - 1) == 0) {
cptr = s.httpheaderline +
sizeof(http_location) - 1;
if(strncmp(cptr, http_http, 7) == 0) {
cptr += 7;
for(i = 0; i < s.httpheaderlineptr - 7; ++i) {
if(*cptr == 0 ||
*cptr == '/' ||
*cptr == ' ' ||
*cptr == ':') {
s.host[i] = 0;
break;
}
s.host[i] = *cptr;
++cptr;
}
}
strncpy(s.file, cptr, sizeof(s.file));
/* s.file[s.httpheaderlineptr - i] = 0;*/
}
/* We're done parsing, so we reset the pointer and start the
next line. */
s.httpheaderlineptr = 0;
} else {
++s.httpheaderlineptr;
}
}
return len;
}
/*-----------------------------------------------------------------------------------*/
static void
newdata(void)
{
u16_t len;
len = uip_datalen();
if(s.state == WEBCLIENT_STATE_STATUSLINE) {
len = parse_statusline(len);
}
if(s.state == WEBCLIENT_STATE_HEADERS && len > 0) {
len = parse_headers(len);
}
if(len > 0 && s.state == WEBCLIENT_STATE_DATA &&
s.httpflag != HTTPFLAG_MOVED) {
webclient_datahandler((char *)uip_appdata, len);
}
}
/*-----------------------------------------------------------------------------------*/
void
webclient_appcall(void)
{
if(uip_connected()) {
s.timer = 0;
s.state = WEBCLIENT_STATE_STATUSLINE;
senddata();
webclient_connected();
return;
}
if(s.state == WEBCLIENT_STATE_CLOSE) {
webclient_closed();
uip_abort();
return;
}
if(uip_aborted()) {
webclient_aborted();
}
if(uip_timedout()) {
webclient_timedout();
}
if(uip_acked()) {
s.timer = 0;
acked();
}
if(uip_newdata()) {
s.timer = 0;
newdata();
}
if(uip_rexmit() ||
uip_newdata() ||
uip_acked()) {
senddata();
} else if(uip_poll()) {
++s.timer;
if(s.timer == WEBCLIENT_TIMEOUT) {
webclient_timedout();
uip_abort();
return;
}
/* senddata();*/
}
if(uip_closed()) {
if(s.httpflag != HTTPFLAG_MOVED) {
/* Send NULL data to signal EOF. */
webclient_datahandler(NULL, 0);
} else {
if(resolv_lookup(s.host) == NULL) {
resolv_query(s.host);
}
webclient_get(s.host, s.port, s.file);
}
}
}
/*-----------------------------------------------------------------------------------*/
/** @} */
/** @} */

View File

@ -0,0 +1,228 @@
/**
* \addtogroup webclient
* @{
*/
/**
* \file
* Header file for the HTTP client.
* \author Adam Dunkels <adam@dunkels.com>
*/
/*
* Copyright (c) 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. 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: webclient.h,v 1.2 2006/06/11 21:46:37 adam Exp $
*
*/
#ifndef __WEBCLIENT_H__
#define __WEBCLIENT_H__
#include "webclient-strings.h"
#include "uipopt.h"
#define WEBCLIENT_CONF_MAX_URLLEN 100
struct webclient_state {
u8_t timer;
u8_t state;
u8_t httpflag;
u16_t port;
char host[40];
char file[WEBCLIENT_CONF_MAX_URLLEN];
u16_t getrequestptr;
u16_t getrequestleft;
char httpheaderline[200];
u16_t httpheaderlineptr;
char mimetype[32];
};
typedef struct webclient_state uip_tcp_appstate_t;
#define UIP_APPCALL webclient_appcall
/**
* Callback function that is called from the webclient code when HTTP
* data has been received.
*
* This function must be implemented by the module that uses the
* webclient code. The function is called from the webclient module
* when HTTP data has been received. The function is not called when
* HTTP headers are received, only for the actual data.
*
* \note This function is called many times, repetedly, when data is
* being received, and not once when all data has been received.
*
* \param data A pointer to the data that has been received.
* \param len The length of the data that has been received.
*/
void webclient_datahandler(char *data, u16_t len);
/**
* Callback function that is called from the webclient code when the
* HTTP connection has been connected to the web server.
*
* This function must be implemented by the module that uses the
* webclient code.
*/
void webclient_connected(void);
/**
* Callback function that is called from the webclient code if the
* HTTP connection to the web server has timed out.
*
* This function must be implemented by the module that uses the
* webclient code.
*/
void webclient_timedout(void);
/**
* Callback function that is called from the webclient code if the
* HTTP connection to the web server has been aborted by the web
* server.
*
* This function must be implemented by the module that uses the
* webclient code.
*/
void webclient_aborted(void);
/**
* Callback function that is called from the webclient code when the
* HTTP connection to the web server has been closed.
*
* This function must be implemented by the module that uses the
* webclient code.
*/
void webclient_closed(void);
/**
* Initialize the webclient module.
*/
void webclient_init(void);
/**
* Open an HTTP connection to a web server and ask for a file using
* the GET method.
*
* This function opens an HTTP connection to the specified web server
* and requests the specified file using the GET method. When the HTTP
* connection has been connected, the webclient_connected() callback
* function is called and when the HTTP data arrives the
* webclient_datahandler() callback function is called.
*
* The callback function webclient_timedout() is called if the web
* server could not be contacted, and the webclient_aborted() callback
* function is called if the HTTP connection is aborted by the web
* server.
*
* When the HTTP request has been completed and the HTTP connection is
* closed, the webclient_closed() callback function will be called.
*
* \note If the function is passed a host name, it must already be in
* the resolver cache in order for the function to connect to the web
* server. It is therefore up to the calling module to implement the
* resolver calls and the signal handler used for reporting a resolv
* query answer.
*
* \param host A pointer to a string containing either a host name or
* a numerical IP address in dotted decimal notation (e.g., 192.168.23.1).
*
* \param port The port number to which to connect, in host byte order.
*
* \param file A pointer to the name of the file to get.
*
* \retval 0 if the host name could not be found in the cache, or
* if a TCP connection could not be created.
*
* \retval 1 if the connection was initiated.
*/
unsigned char webclient_get(char *host, u16_t port, char *file);
/**
* Close the currently open HTTP connection.
*/
void webclient_close(void);
void webclient_appcall(void);
/**
* Obtain the MIME type of the current HTTP data stream.
*
* \return A pointer to a string contaning the MIME type. The string
* may be empty if no MIME type was reported by the web server.
*/
char *webclient_mimetype(void);
/**
* Obtain the filename of the current HTTP data stream.
*
* The filename of an HTTP request may be changed by the web server,
* and may therefore not be the same as when the original GET request
* was made with webclient_get(). This function is used for obtaining
* the current filename.
*
* \return A pointer to the current filename.
*/
char *webclient_filename(void);
/**
* Obtain the hostname of the current HTTP data stream.
*
* The hostname of the web server of an HTTP request may be changed
* by the web server, and may therefore not be the same as when the
* original GET request was made with webclient_get(). This function
* is used for obtaining the current hostname.
*
* \return A pointer to the current hostname.
*/
char *webclient_hostname(void);
/**
* Obtain the port number of the current HTTP data stream.
*
* The port number of an HTTP request may be changed by the web
* server, and may therefore not be the same as when the original GET
* request was made with webclient_get(). This function is used for
* obtaining the current port number.
*
* \return The port number of the current HTTP data stream, in host byte order.
*/
unsigned short webclient_port(void);
#endif /* __WEBCLIENT_H__ */
/** @} */

View File

@ -0,0 +1 @@
APP_SOURCES += httpd.c http-strings.c httpd-fs.c httpd-cgi.c

View File

@ -0,0 +1,35 @@
http_http "http://"
http_200 "200 "
http_301 "301 "
http_302 "302 "
http_get "GET "
http_10 "HTTP/1.0"
http_11 "HTTP/1.1"
http_content_type "content-type: "
http_texthtml "text/html"
http_location "location: "
http_host "host: "
http_crnl "\r\n"
http_index_html "/index.html"
http_404_html "/404.html"
http_referer "Referer:"
http_header_200 "HTTP/1.0 200 OK\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n"
http_header_404 "HTTP/1.0 404 Not found\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n"
http_content_type_plain "Content-type: text/plain\r\n\r\n"
http_content_type_html "Content-type: text/html\r\n\r\n"
http_content_type_css "Content-type: text/css\r\n\r\n"
http_content_type_text "Content-type: text/text\r\n\r\n"
http_content_type_png "Content-type: image/png\r\n\r\n"
http_content_type_gif "Content-type: image/gif\r\n\r\n"
http_content_type_jpg "Content-type: image/jpeg\r\n\r\n"
http_content_type_binary "Content-type: application/octet-stream\r\n\r\n"
http_html ".html"
http_shtml ".shtml"
http_htm ".htm"
http_css ".css"
http_png ".png"
http_gif ".gif"
http_jpg ".jpg"
http_text ".txt"
http_txt ".txt"

View File

@ -0,0 +1,102 @@
const char http_http[8] =
/* "http://" */
{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };
const char http_200[5] =
/* "200 " */
{0x32, 0x30, 0x30, 0x20, };
const char http_301[5] =
/* "301 " */
{0x33, 0x30, 0x31, 0x20, };
const char http_302[5] =
/* "302 " */
{0x33, 0x30, 0x32, 0x20, };
const char http_get[5] =
/* "GET " */
{0x47, 0x45, 0x54, 0x20, };
const char http_10[9] =
/* "HTTP/1.0" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, };
const char http_11[9] =
/* "HTTP/1.1" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, };
const char http_content_type[15] =
/* "content-type: " */
{0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, };
const char http_texthtml[10] =
/* "text/html" */
{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, };
const char http_location[11] =
/* "location: " */
{0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, };
const char http_host[7] =
/* "host: " */
{0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, };
const char http_crnl[3] =
/* "\r\n" */
{0xd, 0xa, };
const char http_index_html[12] =
/* "/index.html" */
{0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };
const char http_404_html[10] =
/* "/404.html" */
{0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };
const char http_referer[9] =
/* "Referer:" */
{0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, 0x3a, };
const char http_header_200[84] =
/* "HTTP/1.0 200 OK\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };
const char http_header_404[91] =
/* "HTTP/1.0 404 Not found\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };
const char http_content_type_plain[29] =
/* "Content-type: text/plain\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_html[28] =
/* "Content-type: text/html\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_css [27] =
/* "Content-type: text/css\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_text[28] =
/* "Content-type: text/text\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x78, 0x74, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_png [28] =
/* "Content-type: image/png\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_gif [28] =
/* "Content-type: image/gif\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_jpg [29] =
/* "Content-type: image/jpeg\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_binary[43] =
/* "Content-type: application/octet-stream\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xd, 0xa, 0xd, 0xa, };
const char http_html[6] =
/* ".html" */
{0x2e, 0x68, 0x74, 0x6d, 0x6c, };
const char http_shtml[7] =
/* ".shtml" */
{0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, };
const char http_htm[5] =
/* ".htm" */
{0x2e, 0x68, 0x74, 0x6d, };
const char http_css[5] =
/* ".css" */
{0x2e, 0x63, 0x73, 0x73, };
const char http_png[5] =
/* ".png" */
{0x2e, 0x70, 0x6e, 0x67, };
const char http_gif[5] =
/* ".gif" */
{0x2e, 0x67, 0x69, 0x66, };
const char http_jpg[5] =
/* ".jpg" */
{0x2e, 0x6a, 0x70, 0x67, };
const char http_text[5] =
/* ".txt" */
{0x2e, 0x74, 0x78, 0x74, };
const char http_txt[5] =
/* ".txt" */
{0x2e, 0x74, 0x78, 0x74, };

View File

@ -0,0 +1,34 @@
extern const char http_http[8];
extern const char http_200[5];
extern const char http_301[5];
extern const char http_302[5];
extern const char http_get[5];
extern const char http_10[9];
extern const char http_11[9];
extern const char http_content_type[15];
extern const char http_texthtml[10];
extern const char http_location[11];
extern const char http_host[7];
extern const char http_crnl[3];
extern const char http_index_html[12];
extern const char http_404_html[10];
extern const char http_referer[9];
extern const char http_header_200[84];
extern const char http_header_404[91];
extern const char http_content_type_plain[29];
extern const char http_content_type_html[28];
extern const char http_content_type_css [27];
extern const char http_content_type_text[28];
extern const char http_content_type_png [28];
extern const char http_content_type_gif [28];
extern const char http_content_type_jpg [29];
extern const char http_content_type_binary[43];
extern const char http_html[6];
extern const char http_shtml[7];
extern const char http_htm[5];
extern const char http_css[5];
extern const char http_png[5];
extern const char http_gif[5];
extern const char http_jpg[5];
extern const char http_text[5];
extern const char http_txt[5];

View File

@ -0,0 +1,203 @@
/**
* \addtogroup httpd
* @{
*/
/**
* \file
* Web server script interface
* \author
* Adam Dunkels <adam@sics.se>
*
*/
/*
* Copyright (c) 2001-2006, 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. 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: httpd-cgi.c,v 1.2 2006/06/11 21:46:37 adam Exp $
*
*/
#include "uip.h"
#include "psock.h"
#include "httpd.h"
#include "httpd-cgi.h"
#include "httpd-fs.h"
#include <stdio.h>
#include <string.h>
HTTPD_CGI_CALL(file, "file-stats", file_stats);
HTTPD_CGI_CALL(tcp, "tcp-connections", tcp_stats);
HTTPD_CGI_CALL(net, "net-stats", net_stats);
static const struct httpd_cgi_call *calls[] = { &file, &tcp, &net, NULL };
/*---------------------------------------------------------------------------*/
static
PT_THREAD(nullfunction(struct httpd_state *s, char *ptr))
{
PSOCK_BEGIN(&s->sout);
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
httpd_cgifunction
httpd_cgi(char *name)
{
const struct httpd_cgi_call **f;
/* Find the matching name in the table, return the function. */
for(f = calls; *f != NULL; ++f) {
if(strncmp((*f)->name, name, strlen((*f)->name)) == 0) {
return (*f)->function;
}
}
return nullfunction;
}
/*---------------------------------------------------------------------------*/
static unsigned short
generate_file_stats(void *arg)
{
char *f = (char *)arg;
return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, "%5u", httpd_fs_count(f));
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(file_stats(struct httpd_state *s, char *ptr))
{
PSOCK_BEGIN(&s->sout);
PSOCK_GENERATOR_SEND(&s->sout, generate_file_stats, strchr(ptr, ' ') + 1);
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
static const char closed[] = /* "CLOSED",*/
{0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0};
static const char syn_rcvd[] = /* "SYN-RCVD",*/
{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};
static const char fin_wait_1[] = /* "FIN-WAIT-1",*/
{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49,
0x54, 0x2d, 0x31, 0};
static const char fin_wait_2[] = /* "FIN-WAIT-2",*/
{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49,
0x54, 0x2d, 0x32, 0};
static const char closing[] = /* "CLOSING",*/
{0x43, 0x4c, 0x4f, 0x53, 0x49,
0x4e, 0x47, 0};
static const char time_wait[] = /* "TIME-WAIT,"*/
{0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41,
0x49, 0x54, 0};
static const char last_ack[] = /* "LAST-ACK"*/
{0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43,
0x4b, 0};
static const char *states[] = {
closed,
syn_rcvd,
syn_sent,
established,
fin_wait_1,
fin_wait_2,
closing,
time_wait,
last_ack};
static unsigned short
generate_tcp_stats(void *arg)
{
struct uip_conn *conn;
struct httpd_state *s = (struct httpd_state *)arg;
conn = &uip_conns[s->count];
return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE,
"<tr><td>%d</td><td>%u.%u.%u.%u:%u</td><td>%s</td><td>%u</td><td>%u</td><td>%c %c</td></tr>\r\n",
htons(conn->lport),
htons(conn->ripaddr[0]) >> 8,
htons(conn->ripaddr[0]) & 0xff,
htons(conn->ripaddr[1]) >> 8,
htons(conn->ripaddr[1]) & 0xff,
htons(conn->rport),
states[conn->tcpstateflags & UIP_TS_MASK],
conn->nrtx,
conn->timer,
(uip_outstanding(conn))? '*':' ',
(uip_stopped(conn))? '!':' ');
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(tcp_stats(struct httpd_state *s, char *ptr))
{
PSOCK_BEGIN(&s->sout);
for(s->count = 0; s->count < UIP_CONNS; ++s->count) {
if((uip_conns[s->count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) {
PSOCK_GENERATOR_SEND(&s->sout, generate_tcp_stats, s);
}
}
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
static unsigned short
generate_net_stats(void *arg)
{
struct httpd_state *s = (struct httpd_state *)arg;
return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE,
"%5u\n", ((uip_stats_t *)&uip_stat)[s->count]);
}
static
PT_THREAD(net_stats(struct httpd_state *s, char *ptr))
{
PSOCK_BEGIN(&s->sout);
#if UIP_STATISTICS
for(s->count = 0; s->count < sizeof(uip_stat) / sizeof(uip_stats_t);
++s->count) {
PSOCK_GENERATOR_SEND(&s->sout, generate_net_stats, s);
}
#endif /* UIP_STATISTICS */
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -0,0 +1,84 @@
/**
* \addtogroup httpd
* @{
*/
/**
* \file
* Web server script interface header file
* \author
* Adam Dunkels <adam@sics.se>
*
*/
/*
* 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. 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: httpd-cgi.h,v 1.2 2006/06/11 21:46:38 adam Exp $
*
*/
#ifndef __HTTPD_CGI_H__
#define __HTTPD_CGI_H__
#include "psock.h"
#include "httpd.h"
typedef PT_THREAD((* httpd_cgifunction)(struct httpd_state *, char *));
httpd_cgifunction httpd_cgi(char *name);
struct httpd_cgi_call {
const char *name;
const httpd_cgifunction function;
};
/**
* \brief HTTPD CGI function declaration
* \param name The C variable name of the function
* \param str The string name of the function, used in the script file
* \param function A pointer to the function that implements it
*
* This macro is used for declaring a HTTPD CGI
* function. This function is then added to the list of
* HTTPD CGI functions with the httpd_cgi_add() function.
*
* \hideinitializer
*/
#define HTTPD_CGI_CALL(name, str, function) \
static PT_THREAD(function(struct httpd_state *, char *)); \
static const struct httpd_cgi_call name = {str, function}
void httpd_cgi_init(void);
#endif /* __HTTPD_CGI_H__ */
/** @} */

View File

@ -0,0 +1,132 @@
/*
* 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.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: httpd-fs.c,v 1.1 2006/06/07 09:13:08 adam Exp $
*/
#include "httpd.h"
#include "httpd-fs.h"
#include "httpd-fsdata.h"
#ifndef NULL
#define NULL 0
#endif /* NULL */
#include "httpd-fsdata.c"
#if HTTPD_FS_STATISTICS
static u16_t count[HTTPD_FS_NUMFILES];
#endif /* HTTPD_FS_STATISTICS */
/*-----------------------------------------------------------------------------------*/
static u8_t
httpd_fs_strcmp(const char *str1, const char *str2)
{
u8_t i;
i = 0;
loop:
if(str2[i] == 0 ||
str1[i] == '\r' ||
str1[i] == '\n') {
return 0;
}
if(str1[i] != str2[i]) {
return 1;
}
++i;
goto loop;
}
/*-----------------------------------------------------------------------------------*/
int
httpd_fs_open(const char *name, struct httpd_fs_file *file)
{
#if HTTPD_FS_STATISTICS
u16_t i = 0;
#endif /* HTTPD_FS_STATISTICS */
struct httpd_fsdata_file_noconst *f;
for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT;
f != NULL;
f = (struct httpd_fsdata_file_noconst *)f->next) {
if(httpd_fs_strcmp(name, f->name) == 0) {
file->data = f->data;
file->len = f->len;
#if HTTPD_FS_STATISTICS
++count[i];
#endif /* HTTPD_FS_STATISTICS */
return 1;
}
#if HTTPD_FS_STATISTICS
++i;
#endif /* HTTPD_FS_STATISTICS */
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
void
httpd_fs_init(void)
{
#if HTTPD_FS_STATISTICS
u16_t i;
for(i = 0; i < HTTPD_FS_NUMFILES; i++) {
count[i] = 0;
}
#endif /* HTTPD_FS_STATISTICS */
}
/*-----------------------------------------------------------------------------------*/
#if HTTPD_FS_STATISTICS
u16_t httpd_fs_count
(char *name)
{
struct httpd_fsdata_file_noconst *f;
u16_t i;
i = 0;
for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT;
f != NULL;
f = (struct httpd_fsdata_file_noconst *)f->next) {
if(httpd_fs_strcmp(name, f->name) == 0) {
return count[i];
}
++i;
}
return 0;
}
#endif /* HTTPD_FS_STATISTICS */
/*-----------------------------------------------------------------------------------*/

View File

@ -0,0 +1,57 @@
/*
* 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.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: httpd-fs.h,v 1.1 2006/06/07 09:13:08 adam Exp $
*/
#ifndef __HTTPD_FS_H__
#define __HTTPD_FS_H__
#define HTTPD_FS_STATISTICS 1
struct httpd_fs_file {
char *data;
int len;
};
/* file must be allocated by caller and will be filled in
by the function. */
int httpd_fs_open(const char *name, struct httpd_fs_file *file);
#ifdef HTTPD_FS_STATISTICS
#if HTTPD_FS_STATISTICS == 1
u16_t httpd_fs_count(char *name);
#endif /* HTTPD_FS_STATISTICS */
#endif /* HTTPD_FS_STATISTICS */
void httpd_fs_init(void);
#endif /* __HTTPD_FS_H__ */

View File

@ -0,0 +1,8 @@
<html>
<body bgcolor="white">
<center>
<h1>404 - file not found</h1>
<h3>Go <a href="/">here</a> instead.</h3>
</center>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

View File

@ -0,0 +1,35 @@
%!: /header.html
<h1>File statistics</h1>
<center>
<table width="300">
<tr><td><a href="/index.html">/index.html</a></td>
<td>%! file-stats /index.html
</td><td><img src="/fade.png" height=10 width=%! file-stats /index.html
> </td></tr>
<tr><td><a href="/files.shtml">/files.shtml</a></td>
<td>%! file-stats /files.shtml
</td><td><img src="/fade.png" height=10 width=%! file-stats /files.shtml
> </td></tr>
<tr><td><a href="/tcp.shtml">/tcp.shtml</a></td>
<td>%! file-stats /tcp.shtml
</td><td><img src="/fade.png" height=10 width=%! file-stats /tcp.shtml
> </td></tr>
<tr><td><a href="/stats.shtml">/stats.shtml</a></td>
<td>%! file-stats /stats.shtml
</td><td><img src="/fade.png" height=10 width=%! file-stats /stats.shtml
> </td></tr>
<tr><td><a href="/style.css">/style.css</a></td>
<td>%! file-stats /style.css
</td><td><img src="/fade.png" height=10 width=%! file-stats /style.css
> </td></tr>
<tr><td><a href="/404.html">/404.html</a></td>
<td>%! file-stats /404.html
</td><td><img src="/fade.png" height=10 width=%! file-stats /404.html
> </td></tr>
<tr><td><a href="/fade.png">/fade.png</a></td>
<td>%! file-stats /fade.png
</td><td><img src="/fade.png" height=10 width=%! file-stats /fade.png
> </td></tr>
</table>
</center>
%!: /footer.html

View File

@ -0,0 +1,2 @@
</body>
</html>

View File

@ -0,0 +1,18 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Welcome to the uIP web server!</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#fffeec" text="black">
<div class="menu">
<div class="menubox"><a href="/">Front page</a></div>
<div class="menubox"><a href="files.shtml">File statistics</a></div>
<div class="menubox"><a href="stats.shtml">Network statistics</a></div>
<div class="menubox"><a href="tcp.shtml">Network
connections</a></div>
<br>
</div>
<div class="contentblock">

View File

@ -0,0 +1,29 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Welcome to the uIP web server!</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#fffeec" text="black">
<div class="menu">
<div class="menubox"><a href="/">Front page</a></div>
<div class="menubox"><a href="files.shtml">File statistics</a></div>
<div class="menubox"><a href="stats.shtml">Network statistics</a></div>
<div class="menubox"><a href="tcp.shtml">Network
connections</a></div>
<br>
</div>
<div class="contentblock">
<p>
These web pages are served by a small web server running on top of
the <a href="http://www.sics.se/~adam/uip/">uIP embedded TCP/IP
stack</a>.
</p>
<p>
Click on the links above for web server statistics.
</p>
</body>
</html>

View File

@ -0,0 +1,5 @@
%!: /header.html
<h1>System processes</h1><br><table width="100%">
<tr><th>ID</th><th>Name</th><th>Priority</th><th>Poll handler</th><th>Event handler</th><th>Procstate</th></tr>
%! processes
%!: /footer.html

View File

@ -0,0 +1,31 @@
%!: /header.html
<h1>Network statistics</h1>
<center>
<table width="300" border="0">
<tr><td><pre>
IP Packets received
Packets sent
Packets dropped
IP errors IP version/header length
IP length, high byte
IP length, low byte
IP fragments
Header checksum
Wrong protocol
ICMP Packets received
Packets sent
Packets dropped
Type errors
TCP Packets received
Packets sent
Packets dropped
Checksum errors
Data packets without ACKs
Resets
Retransmissions
No connection avaliable
Connection attempts to closed ports
</pre></td><td><pre>%! net-stats
</pre></table>
</center>
%!: /footer.html

View File

@ -0,0 +1,92 @@
h1
{
text-align: center;
font-size:14pt;
font-family:arial,helvetica;
font-weight:bold;
padding:10px;
}
body
{
background-color: #fffeec;
color:black;
font-size:8pt;
font-family:arial,helvetica;
}
.menu
{
margin: 4px;
width:60%;
padding:2px;
border: solid 1px;
background-color: #fffcd2;
text-align:left;
font-size:9pt;
font-family:arial,helvetica;
}
div.menubox
{
width: 25%;
border: 0;
float: left;
text-align: center;
}
.contentblock
{
margin: 4px;
width:60%;
padding:2px;
border: 1px dotted;
background-color: white;
font-size:8pt;
font-family:arial,helvetica;
}
p.intro
{
margin-left:20px;
margin-right:20px;
font-size:10pt;
/* font-weight:bold; */
font-family:arial,helvetica;
}
p.clink
{
font-size:12pt;
font-family:courier,monospace;
text-align:center;
}
p.clink9
{
font-size:9pt;
font-family:courier,monospace;
text-align:center;
}
p
{
padding-left:10px;
}
p.right
{
text-align:right;
}

View File

@ -0,0 +1,5 @@
%!: /header.html
<h1>Current connections</h1><br><table width="100%">
<tr><th>Local</th><th>Remote</th><th>State</th><th>Retransmissions</th><th>Timer</th><th>Flags</th></tr>
%! tcp-connections
%!: /footer.html

View File

@ -0,0 +1,607 @@
static const unsigned char data_processes_shtml[] = {
/* /processes.shtml */
0x2f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0,
0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65,
0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x68, 0x31,
0x3e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x70, 0x72,
0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x3c, 0x2f, 0x68,
0x31, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x74, 0x61, 0x62,
0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22,
0x31, 0x30, 0x30, 0x25, 0x22, 0x3e, 0xa, 0x3c, 0x74, 0x72,
0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x49, 0x44, 0x3c, 0x2f, 0x74,
0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x4e, 0x61, 0x6d, 0x65,
0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x50,
0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x3c, 0x2f, 0x74,
0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x50, 0x6f, 0x6c, 0x6c,
0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x3c, 0x2f,
0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x45, 0x76, 0x65,
0x6e, 0x74, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72,
0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x50,
0x72, 0x6f, 0x63, 0x73, 0x74, 0x61, 0x74, 0x65, 0x3c, 0x2f,
0x74, 0x68, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x25,
0x21, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65,
0x73, 0xa, 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x66, 0x6f, 0x6f,
0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0};
static const unsigned char data_404_html[] = {
/* /404.html */
0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x20, 0x20, 0x3c,
0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c,
0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 0x22,
0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x63, 0x65, 0x6e,
0x74, 0x65, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d,
0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20,
0x66, 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e,
0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x33,
0x3e, 0x47, 0x6f, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65,
0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x68, 0x65, 0x72, 0x65,
0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65,
0x61, 0x64, 0x2e, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0xa, 0x20,
0x20, 0x20, 0x20, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65,
0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64,
0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e,
0};
static const unsigned char data_files_shtml[] = {
/* /files.shtml */
0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0,
0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65,
0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x68, 0x31,
0x3e, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74,
0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68, 0x31,
0x3e, 0xa, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69,
0x64, 0x74, 0x68, 0x3d, 0x22, 0x33, 0x30, 0x30, 0x22, 0x3e,
0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c,
0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x69,
0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22,
0x3e, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74,
0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64,
0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66,
0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20,
0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d,
0x6c, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64,
0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d,
0x22, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, 0x70, 0x6e, 0x67,
0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x31,
0x30, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x25, 0x21,
0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74,
0x73, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68,
0x74, 0x6d, 0x6c, 0xa, 0x3e, 0x20, 0x3c, 0x2f, 0x74, 0x64,
0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, 0x74, 0x72,
0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72,
0x65, 0x66, 0x3d, 0x22, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73,
0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, 0x66,
0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c,
0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa,
0x3c, 0x74, 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c,
0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x66,
0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c,
0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e,
0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22,
0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, 0x70, 0x6e, 0x67, 0x22,
0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x31, 0x30,
0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x25, 0x21, 0x20,
0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73,
0x20, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68,
0x74, 0x6d, 0x6c, 0xa, 0x3e, 0x20, 0x3c, 0x2f, 0x74, 0x64,
0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, 0x74, 0x72,
0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72,
0x65, 0x66, 0x3d, 0x22, 0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73,
0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, 0x74, 0x63, 0x70,
0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e,
0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e,
0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74,
0x61, 0x74, 0x73, 0x20, 0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73,
0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e,
0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73,
0x72, 0x63, 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e,
0x70, 0x6e, 0x67, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68,
0x74, 0x3d, 0x31, 0x30, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68,
0x3d, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73,
0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x74, 0x63, 0x70, 0x2e,
0x73, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3e, 0x20, 0x3c, 0x2f,
0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c,
0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20,
0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x73, 0x74, 0x61,
0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e,
0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74,
0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64,
0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66,
0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20,
0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74,
0x6d, 0x6c, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74,
0x64, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63,
0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, 0x70, 0x6e,
0x67, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d,
0x31, 0x30, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x25,
0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61,
0x74, 0x73, 0x20, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e,
0x73, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3e, 0x20, 0x3c, 0x2f,
0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c,
0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20,
0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x73, 0x74, 0x79,
0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x3e, 0x2f, 0x73,
0x74, 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0x3c, 0x2f,
0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74,
0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d,
0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x73, 0x74, 0x79,
0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0xa, 0x3c, 0x2f, 0x74,
0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x69, 0x6d, 0x67,
0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64,
0x65, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x68, 0x65, 0x69,
0x67, 0x68, 0x74, 0x3d, 0x31, 0x30, 0x20, 0x77, 0x69, 0x64,
0x74, 0x68, 0x3d, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65,
0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x73, 0x74,
0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0xa, 0x3e, 0x20,
0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e,
0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c,
0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x34,
0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f,
0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3c, 0x2f,
0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74,
0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d,
0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x34, 0x30, 0x34,
0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x2f, 0x74, 0x64,
0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20,
0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, 0x65,
0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67,
0x68, 0x74, 0x3d, 0x31, 0x30, 0x20, 0x77, 0x69, 0x64, 0x74,
0x68, 0x3d, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d,
0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x34, 0x30, 0x34,
0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3e, 0x20, 0x3c, 0x2f,
0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c,
0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20,
0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64,
0x65, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x3e, 0x2f, 0x66, 0x61,
0x64, 0x65, 0x2e, 0x70, 0x6e, 0x67, 0x3c, 0x2f, 0x61, 0x3e,
0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e,
0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74,
0x61, 0x74, 0x73, 0x20, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e,
0x70, 0x6e, 0x67, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c,
0x74, 0x64, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72,
0x63, 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, 0x70,
0x6e, 0x67, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74,
0x3d, 0x31, 0x30, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d,
0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74,
0x61, 0x74, 0x73, 0x20, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e,
0x70, 0x6e, 0x67, 0xa, 0x3e, 0x20, 0x3c, 0x2f, 0x74, 0x64,
0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, 0x2f, 0x74,
0x61, 0x62, 0x6c, 0x65, 0x3e, 0xa, 0x3c, 0x2f, 0x63, 0x65,
0x6e, 0x74, 0x65, 0x72, 0x3e, 0xa, 0x25, 0x21, 0x3a, 0x20,
0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74,
0x6d, 0x6c, 0xa, 0};
static const unsigned char data_footer_html[] = {
/* /footer.html */
0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0};
static const unsigned char data_header_html[] = {
/* /header.html */
0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20,
0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49,
0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f,
0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20,
0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45,
0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72,
0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34,
0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64,
0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa,
0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20,
0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e,
0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f,
0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x49, 0x50, 0x20, 0x77,
0x65, 0x62, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x21,
0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x20,
0x20, 0x20, 0x20, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72,
0x65, 0x6c, 0x3d, 0x22, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73,
0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65,
0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73,
0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74,
0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x3e, 0x20,
0x20, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64,
0x3e, 0xa, 0x20, 0x20, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20,
0x62, 0x67, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23,
0x66, 0x66, 0x66, 0x65, 0x65, 0x63, 0x22, 0x20, 0x74, 0x65,
0x78, 0x74, 0x3d, 0x22, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x22,
0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20,
0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e,
0x75, 0x22, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76,
0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65,
0x6e, 0x75, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20,
0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x46,
0x72, 0x6f, 0x6e, 0x74, 0x20, 0x70, 0x61, 0x67, 0x65, 0x3c,
0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa,
0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61,
0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x6f,
0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66,
0x3d, 0x22, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68,
0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x46, 0x69, 0x6c, 0x65, 0x20,
0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73,
0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e,
0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c,
0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x62,
0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65,
0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73,
0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x4e, 0x65, 0x74, 0x77,
0x6f, 0x72, 0x6b, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73,
0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f,
0x64, 0x69, 0x76, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69,
0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d,
0x65, 0x6e, 0x75, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61,
0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, 0x63, 0x70,
0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x4e, 0x65,
0x74, 0x77, 0x6f, 0x72, 0x6b, 0xa, 0x20, 0x20, 0x63, 0x6f,
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c,
0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa,
0x20, 0x20, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c,
0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, 0x20, 0x20, 0xa, 0x20,
0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73,
0x73, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3e, 0xa, 0};
static const unsigned char data_index_html[] = {
/* /index.html */
0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20,
0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49,
0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f,
0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20,
0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45,
0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72,
0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34,
0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64,
0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa,
0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20,
0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e,
0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f,
0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x49, 0x50, 0x20, 0x77,
0x65, 0x62, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x21,
0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x20,
0x20, 0x20, 0x20, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72,
0x65, 0x6c, 0x3d, 0x22, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73,
0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65,
0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73,
0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74,
0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x3e, 0x20,
0x20, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64,
0x3e, 0xa, 0x20, 0x20, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20,
0x62, 0x67, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23,
0x66, 0x66, 0x66, 0x65, 0x65, 0x63, 0x22, 0x20, 0x74, 0x65,
0x78, 0x74, 0x3d, 0x22, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x22,
0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20,
0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e,
0x75, 0x22, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76,
0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65,
0x6e, 0x75, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20,
0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x46,
0x72, 0x6f, 0x6e, 0x74, 0x20, 0x70, 0x61, 0x67, 0x65, 0x3c,
0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa,
0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61,
0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x6f,
0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66,
0x3d, 0x22, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68,
0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x46, 0x69, 0x6c, 0x65, 0x20,
0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73,
0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e,
0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c,
0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x62,
0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65,
0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73,
0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x4e, 0x65, 0x74, 0x77,
0x6f, 0x72, 0x6b, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73,
0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f,
0x64, 0x69, 0x76, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69,
0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d,
0x65, 0x6e, 0x75, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61,
0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, 0x63, 0x70,
0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x4e, 0x65,
0x74, 0x77, 0x6f, 0x72, 0x6b, 0xa, 0x20, 0x20, 0x63, 0x6f,
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c,
0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa,
0x20, 0x20, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c,
0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c,
0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d,
0x22, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x62, 0x6c,
0x6f, 0x63, 0x6b, 0x22, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x70,
0x3e, 0xa, 0x20, 0x20, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20,
0x77, 0x65, 0x62, 0x20, 0x70, 0x61, 0x67, 0x65, 0x73, 0x20,
0x61, 0x72, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64,
0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x73, 0x6d, 0x61, 0x6c,
0x6c, 0x20, 0x77, 0x65, 0x62, 0x20, 0x73, 0x65, 0x72, 0x76,
0x65, 0x72, 0x20, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67,
0x20, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x70, 0x20, 0x6f, 0x66,
0xa, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3c, 0x61, 0x20,
0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70,
0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63,
0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d,
0x2f, 0x75, 0x69, 0x70, 0x2f, 0x22, 0x3e, 0x75, 0x49, 0x50,
0x20, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20,
0x54, 0x43, 0x50, 0x2f, 0x49, 0x50, 0xa, 0x20, 0x20, 0x73,
0x74, 0x61, 0x63, 0x6b, 0x3c, 0x2f, 0x61, 0x3e, 0x2e, 0xa,
0x20, 0x20, 0x3c, 0x2f, 0x70, 0x3e, 0xa, 0x20, 0x20, 0x3c,
0x70, 0x3e, 0xa, 0x20, 0x20, 0x43, 0x6c, 0x69, 0x63, 0x6b,
0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69,
0x6e, 0x6b, 0x73, 0x20, 0x61, 0x62, 0x6f, 0x76, 0x65, 0x20,
0x66, 0x6f, 0x72, 0x20, 0x77, 0x65, 0x62, 0x20, 0x73, 0x65,
0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69,
0x73, 0x74, 0x69, 0x63, 0x73, 0x2e, 0xa, 0x20, 0x20, 0x3c,
0x2f, 0x70, 0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x62,
0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d,
0x6c, 0x3e, 0xa, 0};
static const unsigned char data_style_css[] = {
/* /style.css */
0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0,
0x68, 0x31, 0x20, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x74, 0x65,
0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x20,
0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0xa, 0x20, 0x20,
0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a,
0x31, 0x34, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f,
0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a,
0x61, 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, 0x76,
0x65, 0x74, 0x69, 0x63, 0x61, 0x3b, 0xa, 0x20, 0x20, 0x66,
0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74,
0x3a, 0x62, 0x6f, 0x6c, 0x64, 0x3b, 0xa, 0x20, 0x20, 0x70,
0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x31, 0x30, 0x70,
0x78, 0x3b, 0x20, 0xa, 0x7d, 0xa, 0xa, 0x62, 0x6f, 0x64,
0x79, 0xa, 0x7b, 0xa, 0xa, 0x20, 0x20, 0x62, 0x61, 0x63,
0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f,
0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x66, 0x66, 0x65,
0x65, 0x63, 0x3b, 0xa, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
0x72, 0x3a, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x3b, 0xa, 0xa,
0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a,
0x65, 0x3a, 0x38, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66,
0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79,
0x3a, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c,
0x76, 0x65, 0x74, 0x69, 0x63, 0x61, 0x3b, 0xa, 0x7d, 0xa,
0xa, 0x2e, 0x6d, 0x65, 0x6e, 0x75, 0xa, 0x7b, 0xa, 0x20,
0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x34,
0x70, 0x78, 0x3b, 0xa, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74,
0x68, 0x3a, 0x36, 0x30, 0x25, 0x3b, 0xa, 0xa, 0x20, 0x20,
0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x32, 0x70,
0x78, 0x3b, 0xa, 0x9, 0xa, 0x20, 0x20, 0x62, 0x6f, 0x72,
0x64, 0x65, 0x72, 0x3a, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64,
0x20, 0x31, 0x70, 0x78, 0x3b, 0xa, 0x20, 0x20, 0x62, 0x61,
0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63,
0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x66, 0x66,
0x63, 0x64, 0x32, 0x3b, 0xa, 0x20, 0x20, 0x74, 0x65, 0x78,
0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x6c, 0x65,
0x66, 0x74, 0x3b, 0xa, 0x20, 0x20, 0xa, 0x20, 0x20, 0x66,
0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x39,
0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74,
0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x61, 0x72,
0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, 0x76, 0x65, 0x74,
0x69, 0x63, 0x61, 0x3b, 0x20, 0x20, 0xa, 0x7d, 0xa, 0xa,
0x64, 0x69, 0x76, 0x2e, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x6f,
0x78, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74,
0x68, 0x3a, 0x20, 0x32, 0x35, 0x25, 0x3b, 0xa, 0x20, 0x20,
0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x30, 0x3b,
0xa, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x20,
0x6c, 0x65, 0x66, 0x74, 0x3b, 0xa, 0x74, 0x65, 0x78, 0x74,
0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x20, 0x63, 0x65,
0x6e, 0x74, 0x65, 0x72, 0x3b, 0xa, 0x7d, 0xa, 0xa, 0x2e,
0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x62, 0x6c, 0x6f,
0x63, 0x6b, 0xa, 0x7b, 0x20, 0x20, 0xa, 0x20, 0x20, 0x6d,
0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x34, 0x70, 0x78,
0x3b, 0xa, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a,
0x36, 0x30, 0x25, 0x3b, 0xa, 0xa, 0x20, 0x20, 0x70, 0x61,
0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x32, 0x70, 0x78, 0x3b,
0xa, 0xa, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72,
0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x64, 0x6f, 0x74, 0x74,
0x65, 0x64, 0x3b, 0xa, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b,
0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c,
0x6f, 0x72, 0x3a, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, 0x3b,
0xa, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73,
0x69, 0x7a, 0x65, 0x3a, 0x38, 0x70, 0x74, 0x3b, 0xa, 0x20,
0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69,
0x6c, 0x79, 0x3a, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x68,
0x65, 0x6c, 0x76, 0x65, 0x74, 0x69, 0x63, 0x61, 0x3b, 0x20,
0x20, 0xa, 0xa, 0x7d, 0xa, 0xa, 0x70, 0x2e, 0x69, 0x6e,
0x74, 0x72, 0x6f, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x6d, 0x61,
0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a,
0x32, 0x30, 0x70, 0x78, 0x3b, 0xa, 0x20, 0x20, 0x6d, 0x61,
0x72, 0x67, 0x69, 0x6e, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74,
0x3a, 0x32, 0x30, 0x70, 0x78, 0x3b, 0xa, 0xa, 0x20, 0x20,
0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a,
0x31, 0x30, 0x70, 0x74, 0x3b, 0xa, 0x2f, 0x2a, 0x20, 0x20,
0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68,
0x74, 0x3a, 0x62, 0x6f, 0x6c, 0x64, 0x3b, 0x20, 0x2a, 0x2f,
0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61,
0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x61, 0x72, 0x69, 0x61, 0x6c,
0x2c, 0x68, 0x65, 0x6c, 0x76, 0x65, 0x74, 0x69, 0x63, 0x61,
0x3b, 0x20, 0x20, 0xa, 0x7d, 0xa, 0xa, 0x70, 0x2e, 0x63,
0x6c, 0x69, 0x6e, 0x6b, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x66,
0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31,
0x32, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e,
0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x63,
0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, 0x2c, 0x6d, 0x6f, 0x6e,
0x6f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3b, 0x20, 0x20, 0xa,
0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69,
0x67, 0x6e, 0x3a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b,
0xa, 0x7d, 0xa, 0xa, 0x70, 0x2e, 0x63, 0x6c, 0x69, 0x6e,
0x6b, 0x39, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e,
0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x39, 0x70, 0x74,
0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66,
0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x63, 0x6f, 0x75, 0x72,
0x69, 0x65, 0x72, 0x2c, 0x6d, 0x6f, 0x6e, 0x6f, 0x73, 0x70,
0x61, 0x63, 0x65, 0x3b, 0x20, 0x20, 0xa, 0x20, 0x20, 0x74,
0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a,
0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0xa, 0x7d, 0xa,
0xa, 0xa, 0x70, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x70, 0x61,
0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x66, 0x74,
0x3a, 0x31, 0x30, 0x70, 0x78, 0x3b, 0xa, 0x7d, 0xa, 0xa,
0x70, 0x2e, 0x72, 0x69, 0x67, 0x68, 0x74, 0xa, 0x7b, 0xa,
0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69,
0x67, 0x6e, 0x3a, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x20,
0xa, 0x7d, 0xa, 0xa, 0};
static const unsigned char data_tcp_shtml[] = {
/* /tcp.shtml */
0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0,
0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65,
0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x68, 0x31,
0x3e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x63,
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c,
0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74,
0x68, 0x3d, 0x22, 0x31, 0x30, 0x30, 0x25, 0x22, 0x3e, 0xa,
0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x4c, 0x6f,
0x63, 0x61, 0x6c, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74,
0x68, 0x3e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x3c, 0x2f,
0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x53, 0x74, 0x61,
0x74, 0x65, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68,
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, 0x46,
0x6c, 0x61, 0x67, 0x73, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c,
0x2f, 0x74, 0x72, 0x3e, 0xa, 0x25, 0x21, 0x20, 0x74, 0x63,
0x70, 0x2d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0xa, 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x66,
0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c,
0};
static const unsigned char data_fade_png[] = {
/* /fade.png */
0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, 0x70, 0x6e, 0x67, 0,
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 00, 00,
00, 0xd, 0x49, 0x48, 0x44, 0x52, 00, 00, 00, 0x4,
00, 00, 00, 0xa, 0x8, 0x2, 00, 00, 00, 0x1c,
0x99, 0x68, 0x59, 00, 00, 00, 0x9, 0x70, 0x48, 0x59,
0x73, 00, 00, 0xb, 0x13, 00, 00, 0xb, 0x13, 0x1,
00, 0x9a, 0x9c, 0x18, 00, 00, 00, 0x7, 0x74, 0x49,
0x4d, 0x45, 0x7, 0xd6, 0x6, 0x8, 0x14, 0x1b, 0x39, 0xaf,
0x5b, 0xc0, 0xe3, 00, 00, 00, 0x1d, 0x74, 0x45, 0x58,
0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 00, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74,
0x68, 0x20, 0x54, 0x68, 0x65, 0x20, 0x47, 0x49, 0x4d, 0x50,
0xef, 0x64, 0x25, 0x6e, 00, 00, 00, 0x3a, 0x49, 0x44,
0x41, 0x54, 0x8, 0xd7, 0x75, 0x8c, 0x31, 0x12, 00, 0x10,
0x10, 0xc4, 0x2e, 0x37, 0x9e, 0x40, 0x65, 0xfd, 0xff, 0x83,
0xf4, 0xa, 0x1c, 0x8d, 0x54, 0x9b, 0xc9, 0xcc, 0x9a, 0x3d,
0x90, 0x73, 0x71, 0x67, 0x91, 0xd4, 0x74, 0x36, 0xa9, 0x55,
0x1, 0xf8, 0x29, 0x58, 0xc8, 0xbf, 0x48, 0xc4, 0x81, 0x74,
0xb, 0xa3, 0xf, 0x7c, 0xdb, 0x4, 0xe8, 0x40, 0x5, 0xdf,
0xa1, 0xf3, 0xfc, 0x73, 00, 00, 00, 00, 0x49, 0x45,
0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0};
static const unsigned char data_stats_shtml[] = {
/* /stats.shtml */
0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0,
0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65,
0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x68, 0x31,
0x3e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x73,
0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c,
0x2f, 0x68, 0x31, 0x3e, 0xa, 0x3c, 0x63, 0x65, 0x6e, 0x74,
0x65, 0x72, 0x3e, 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65,
0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x33, 0x30,
0x30, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d,
0x22, 0x30, 0x22, 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c,
0x74, 0x64, 0x3e, 0x3c, 0x70, 0x72, 0x65, 0x3e, 0xa, 0x49,
0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20,
0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0xa, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20,
0x73, 0x65, 0x6e, 0x74, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20,
0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64,
0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0xa, 0x49, 0x50, 0x20,
0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x20, 0x20, 0x20, 0x20,
0x49, 0x50, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6c, 0x65,
0x6e, 0x67, 0x74, 0x68, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50,
0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x20, 0x68,
0x69, 0x67, 0x68, 0x20, 0x62, 0x79, 0x74, 0x65, 0xa, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x49, 0x50, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74,
0x68, 0x2c, 0x20, 0x6c, 0x6f, 0x77, 0x20, 0x62, 0x79, 0x74,
0x65, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, 0x66, 0x72,
0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0xa, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x63, 0x68,
0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0xa, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x57, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x63, 0x6f, 0x6c, 0xa, 0x49, 0x43, 0x4d, 0x50, 0x9,
0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65,
0x74, 0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65,
0x64, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65,
0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xa, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64,
0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0xa, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x54, 0x79, 0x70, 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72,
0x73, 0xa, 0x54, 0x43, 0x50, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65,
0x74, 0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65,
0x64, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65,
0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xa, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64,
0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0xa, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x20, 0x65,
0x72, 0x72, 0x6f, 0x72, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44,
0x61, 0x74, 0x61, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74,
0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20,
0x41, 0x43, 0x4b, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65,
0x73, 0x65, 0x74, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65,
0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x69,
0x6f, 0x6e, 0x73, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20,
0x4e, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x20, 0x61, 0x76, 0x61, 0x6c, 0x69, 0x61,
0x62, 0x6c, 0x65, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20,
0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x20, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, 0x20,
0x74, 0x6f, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x20,
0x70, 0x6f, 0x72, 0x74, 0x73, 0xa, 0x3c, 0x2f, 0x70, 0x72,
0x65, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64,
0x3e, 0x3c, 0x70, 0x72, 0x65, 0x3e, 0x25, 0x21, 0x20, 0x6e,
0x65, 0x74, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0xa, 0x3c,
0x2f, 0x70, 0x72, 0x65, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62,
0x6c, 0x65, 0x3e, 0xa, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74,
0x65, 0x72, 0x3e, 0xa, 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x66,
0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c,
0xa, 0};
const struct httpd_fsdata_file file_processes_shtml[] = {{NULL, data_processes_shtml, data_processes_shtml + 17, sizeof(data_processes_shtml) - 17}};
const struct httpd_fsdata_file file_404_html[] = {{file_processes_shtml, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};
const struct httpd_fsdata_file file_files_shtml[] = {{file_404_html, data_files_shtml, data_files_shtml + 13, sizeof(data_files_shtml) - 13}};
const struct httpd_fsdata_file file_footer_html[] = {{file_files_shtml, data_footer_html, data_footer_html + 13, sizeof(data_footer_html) - 13}};
const struct httpd_fsdata_file file_header_html[] = {{file_footer_html, data_header_html, data_header_html + 13, sizeof(data_header_html) - 13}};
const struct httpd_fsdata_file file_index_html[] = {{file_header_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};
const struct httpd_fsdata_file file_style_css[] = {{file_index_html, data_style_css, data_style_css + 11, sizeof(data_style_css) - 11}};
const struct httpd_fsdata_file file_tcp_shtml[] = {{file_style_css, data_tcp_shtml, data_tcp_shtml + 11, sizeof(data_tcp_shtml) - 11}};
const struct httpd_fsdata_file file_fade_png[] = {{file_tcp_shtml, data_fade_png, data_fade_png + 10, sizeof(data_fade_png) - 10}};
const struct httpd_fsdata_file file_stats_shtml[] = {{file_fade_png, data_stats_shtml, data_stats_shtml + 13, sizeof(data_stats_shtml) - 13}};
#define HTTPD_FS_ROOT file_stats_shtml
#define HTTPD_FS_NUMFILES 10

View File

@ -0,0 +1,64 @@
/*
* 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.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: httpd-fsdata.h,v 1.1 2006/06/07 09:13:08 adam Exp $
*/
#ifndef __HTTPD_FSDATA_H__
#define __HTTPD_FSDATA_H__
#include "uip.h"
struct httpd_fsdata_file {
const struct httpd_fsdata_file *next;
const char *name;
const char *data;
const int len;
#ifdef HTTPD_FS_STATISTICS
#if HTTPD_FS_STATISTICS == 1
u16_t count;
#endif /* HTTPD_FS_STATISTICS */
#endif /* HTTPD_FS_STATISTICS */
};
struct httpd_fsdata_file_noconst {
struct httpd_fsdata_file *next;
char *name;
char *data;
int len;
#ifdef HTTPD_FS_STATISTICS
#if HTTPD_FS_STATISTICS == 1
u16_t count;
#endif /* HTTPD_FS_STATISTICS */
#endif /* HTTPD_FS_STATISTICS */
};
#endif /* __HTTPD_FSDATA_H__ */

View File

@ -0,0 +1,338 @@
/**
* \addtogroup apps
* @{
*/
/**
* \defgroup httpd Web server
* @{
* The uIP web server is a very simplistic implementation of an HTTP
* server. It can serve web pages and files from a read-only ROM
* filesystem, and provides a very small scripting language.
*/
/**
* \file
* Web server
* \author
* Adam Dunkels <adam@sics.se>
*/
/*
* Copyright (c) 2004, 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. 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.
*
* This file is part of the uIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: httpd.c,v 1.2 2006/06/11 21:46:38 adam Exp $
*/
#include "uip.h"
#include "httpd.h"
#include "httpd-fs.h"
#include "httpd-cgi.h"
#include "http-strings.h"
#include <string.h>
#define STATE_WAITING 0
#define STATE_OUTPUT 1
#define ISO_nl 0x0a
#define ISO_space 0x20
#define ISO_bang 0x21
#define ISO_percent 0x25
#define ISO_period 0x2e
#define ISO_slash 0x2f
#define ISO_colon 0x3a
/*---------------------------------------------------------------------------*/
static unsigned short
generate_part_of_file(void *state)
{
struct httpd_state *s = (struct httpd_state *)state;
if(s->file.len > uip_mss()) {
s->len = uip_mss();
} else {
s->len = s->file.len;
}
memcpy(uip_appdata, s->file.data, s->len);
return s->len;
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(send_file(struct httpd_state *s))
{
PSOCK_BEGIN(&s->sout);
do {
PSOCK_GENERATOR_SEND(&s->sout, generate_part_of_file, s);
s->file.len -= s->len;
s->file.data += s->len;
} while(s->file.len > 0);
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(send_part_of_file(struct httpd_state *s))
{
PSOCK_BEGIN(&s->sout);
PSOCK_SEND(&s->sout, s->file.data, s->len);
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
static void
next_scriptstate(struct httpd_state *s)
{
char *p;
p = strchr(s->scriptptr, ISO_nl) + 1;
s->scriptlen -= (unsigned short)(p - s->scriptptr);
s->scriptptr = p;
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_script(struct httpd_state *s))
{
char *ptr;
PT_BEGIN(&s->scriptpt);
while(s->file.len > 0) {
/* Check if we should start executing a script. */
if(*s->file.data == ISO_percent &&
*(s->file.data + 1) == ISO_bang) {
s->scriptptr = s->file.data + 3;
s->scriptlen = s->file.len - 3;
if(*(s->scriptptr - 1) == ISO_colon) {
httpd_fs_open(s->scriptptr + 1, &s->file);
PT_WAIT_THREAD(&s->scriptpt, send_file(s));
} else {
PT_WAIT_THREAD(&s->scriptpt,
httpd_cgi(s->scriptptr)(s, s->scriptptr));
}
next_scriptstate(s);
/* The script is over, so we reset the pointers and continue
sending the rest of the file. */
s->file.data = s->scriptptr;
s->file.len = s->scriptlen;
} else {
/* See if we find the start of script marker in the block of HTML
to be sent. */
if(s->file.len > uip_mss()) {
s->len = uip_mss();
} else {
s->len = s->file.len;
}
if(*s->file.data == ISO_percent) {
ptr = strchr(s->file.data + 1, ISO_percent);
} else {
ptr = strchr(s->file.data, ISO_percent);
}
if(ptr != NULL &&
ptr != s->file.data) {
s->len = (int)(ptr - s->file.data);
if(s->len >= uip_mss()) {
s->len = uip_mss();
}
}
PT_WAIT_THREAD(&s->scriptpt, send_part_of_file(s));
s->file.data += s->len;
s->file.len -= s->len;
}
}
PT_END(&s->scriptpt);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr))
{
char *ptr;
PSOCK_BEGIN(&s->sout);
PSOCK_SEND_STR(&s->sout, statushdr);
ptr = strrchr(s->filename, ISO_period);
if(ptr == NULL) {
PSOCK_SEND_STR(&s->sout, http_content_type_binary);
} else if(strncmp(http_html, ptr, 5) == 0 ||
strncmp(http_shtml, ptr, 6) == 0) {
PSOCK_SEND_STR(&s->sout, http_content_type_html);
} else if(strncmp(http_css, ptr, 4) == 0) {
PSOCK_SEND_STR(&s->sout, http_content_type_css);
} else if(strncmp(http_png, ptr, 4) == 0) {
PSOCK_SEND_STR(&s->sout, http_content_type_png);
} else if(strncmp(http_gif, ptr, 4) == 0) {
PSOCK_SEND_STR(&s->sout, http_content_type_gif);
} else if(strncmp(http_jpg, ptr, 4) == 0) {
PSOCK_SEND_STR(&s->sout, http_content_type_jpg);
} else {
PSOCK_SEND_STR(&s->sout, http_content_type_plain);
}
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_output(struct httpd_state *s))
{
char *ptr;
PT_BEGIN(&s->outputpt);
if(!httpd_fs_open(s->filename, &s->file)) {
httpd_fs_open(http_404_html, &s->file);
strcpy(s->filename, http_404_html);
PT_WAIT_THREAD(&s->outputpt,
send_headers(s,
http_header_404));
PT_WAIT_THREAD(&s->outputpt,
send_file(s));
} else {
PT_WAIT_THREAD(&s->outputpt,
send_headers(s,
http_header_200));
ptr = strchr(s->filename, ISO_period);
if(ptr != NULL && strncmp(ptr, http_shtml, 6) == 0) {
PT_INIT(&s->scriptpt);
PT_WAIT_THREAD(&s->outputpt, handle_script(s));
} else {
PT_WAIT_THREAD(&s->outputpt,
send_file(s));
}
}
PSOCK_CLOSE(&s->sout);
PT_END(&s->outputpt);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_input(struct httpd_state *s))
{
PSOCK_BEGIN(&s->sin);
PSOCK_READTO(&s->sin, ISO_space);
if(strncmp(s->inputbuf, http_get, 4) != 0) {
PSOCK_CLOSE_EXIT(&s->sin);
}
PSOCK_READTO(&s->sin, ISO_space);
if(s->inputbuf[0] != ISO_slash) {
PSOCK_CLOSE_EXIT(&s->sin);
}
if(s->inputbuf[1] == ISO_space) {
strncpy(s->filename, http_index_html, sizeof(s->filename));
} else {
s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
}
/* httpd_log_file(uip_conn->ripaddr, s->filename);*/
s->state = STATE_OUTPUT;
while(1) {
PSOCK_READTO(&s->sin, ISO_nl);
if(strncmp(s->inputbuf, http_referer, 8) == 0) {
s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
/* httpd_log(&s->inputbuf[9]);*/
}
}
PSOCK_END(&s->sin);
}
/*---------------------------------------------------------------------------*/
static void
handle_connection(struct httpd_state *s)
{
handle_input(s);
if(s->state == STATE_OUTPUT) {
handle_output(s);
}
}
/*---------------------------------------------------------------------------*/
void
httpd_appcall(void)
{
struct httpd_state *s = (struct httpd_state *)&(uip_conn->appstate);
if(uip_closed() || uip_aborted() || uip_timedout()) {
} else if(uip_connected()) {
PSOCK_INIT(&s->sin, s->inputbuf, sizeof(s->inputbuf) - 1);
PSOCK_INIT(&s->sout, s->inputbuf, sizeof(s->inputbuf) - 1);
PT_INIT(&s->outputpt);
s->state = STATE_WAITING;
/* timer_set(&s->timer, CLOCK_SECOND * 100);*/
s->timer = 0;
handle_connection(s);
} else if(s != NULL) {
if(uip_poll()) {
++s->timer;
if(s->timer >= 20) {
uip_abort();
}
} else {
s->timer = 0;
}
handle_connection(s);
} else {
uip_abort();
}
}
/*---------------------------------------------------------------------------*/
/**
* \brief Initialize the web server
*
* This function initializes the web server and should be
* called at system boot-up.
*/
void
httpd_init(void)
{
uip_listen(HTONS(80));
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2001-2005, 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. 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: httpd.h,v 1.2 2006/06/11 21:46:38 adam Exp $
*
*/
#ifndef __HTTPD_H__
#define __HTTPD_H__
#include "psock.h"
#include "httpd-fs.h"
struct httpd_state {
unsigned char timer;
struct psock sin, sout;
struct pt outputpt, scriptpt;
char inputbuf[50];
char filename[20];
char state;
struct httpd_fs_file file;
int len;
char *scriptptr;
int scriptlen;
unsigned short count;
};
void httpd_init(void);
void httpd_appcall(void);
void httpd_log(char *msg);
void httpd_log_file(u16_t *requester, char *file);
#endif /* __HTTPD_H__ */

View File

@ -0,0 +1,78 @@
#!/usr/bin/perl
open(OUTPUT, "> httpd-fsdata.c");
chdir("httpd-fs");
opendir(DIR, ".");
@files = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);
closedir(DIR);
foreach $file (@files) {
if(-d $file && $file !~ /^\./) {
print "Processing directory $file\n";
opendir(DIR, $file);
@newfiles = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);
closedir(DIR);
printf "Adding files @newfiles\n";
@files = (@files, map { $_ = "$file/$_" } @newfiles);
next;
}
}
foreach $file (@files) {
if(-f $file) {
print "Adding file $file\n";
open(FILE, $file) || die "Could not open file $file\n";
$file =~ s-^-/-;
$fvar = $file;
$fvar =~ s-/-_-g;
$fvar =~ s-\.-_-g;
# for AVR, add PROGMEM here
print(OUTPUT "static const unsigned char data".$fvar."[] = {\n");
print(OUTPUT "\t/* $file */\n\t");
for($j = 0; $j < length($file); $j++) {
printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1)));
}
printf(OUTPUT "0,\n");
$i = 0;
while(read(FILE, $data, 1)) {
if($i == 0) {
print(OUTPUT "\t");
}
printf(OUTPUT "%#02x, ", unpack("C", $data));
$i++;
if($i == 10) {
print(OUTPUT "\n");
$i = 0;
}
}
print(OUTPUT "0};\n\n");
close(FILE);
push(@fvars, $fvar);
push(@pfiles, $file);
}
}
for($i = 0; $i < @fvars; $i++) {
$file = $pfiles[$i];
$fvar = $fvars[$i];
if($i == 0) {
$prevfile = "NULL";
} else {
$prevfile = "file" . $fvars[$i - 1];
}
print(OUTPUT "const struct httpd_fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, ");
print(OUTPUT "data$fvar + ". (length($file) + 1) .", ");
print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n");
}
print(OUTPUT "#define HTTPD_FS_ROOT file$fvars[$i - 1]\n\n");
print(OUTPUT "#define HTTPD_FS_NUMFILES $i\n");

View File

@ -0,0 +1,40 @@
#!/usr/bin/perl
sub stringify {
my $name = shift(@_);
open(OUTPUTC, "> $name.c");
open(OUTPUTH, "> $name.h");
open(FILE, "$name");
while(<FILE>) {
if(/(.+) "(.+)"/) {
$var = $1;
$data = $2;
$datan = $data;
$datan =~ s/\\r/\r/g;
$datan =~ s/\\n/\n/g;
$datan =~ s/\\01/\01/g;
$datan =~ s/\\0/\0/g;
printf(OUTPUTC "const char $var\[%d] = \n", length($datan) + 1);
printf(OUTPUTC "/* \"$data\" */\n");
printf(OUTPUTC "{");
for($j = 0; $j < length($datan); $j++) {
printf(OUTPUTC "%#02x, ", unpack("C", substr($datan, $j, 1)));
}
printf(OUTPUTC "};\n");
printf(OUTPUTH "extern const char $var\[%d];\n", length($datan) + 1);
}
}
close(OUTPUTC);
close(OUTPUTH);
}
stringify("http-strings");
exit 0;

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 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. 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: webserver.h,v 1.2 2006/06/11 21:46:38 adam Exp $
*
*/
#ifndef __WEBSERVER_H__
#define __WEBSERVER_H__
#include "httpd.h"
typedef struct httpd_state uip_tcp_appstate_t;
/* UIP_APPCALL: the name of the application function. This function
must return void and take no arguments (i.e., C type "void
appfunc(void)"). */
#ifndef UIP_APPCALL
#define UIP_APPCALL httpd_appcall
#endif
#endif /* __WEBSERVER_H__ */

104
android/uip/lib/memb.c Normal file
View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2004, 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: memb.c,v 1.1 2006/06/12 08:21:43 adam Exp $
*/
/**
* \addtogroup memb
* @{
*/
/**
* \file
* Memory block allocation routines.
* \author Adam Dunkels <adam@sics.se>
*/
#include <string.h>
#include "memb.h"
/*---------------------------------------------------------------------------*/
void
memb_init(struct memb_blocks *m)
{
memset(m->count, 0, m->num);
memset(m->mem, 0, m->size * m->num);
}
/*---------------------------------------------------------------------------*/
void *
memb_alloc(struct memb_blocks *m)
{
int i;
for(i = 0; i < m->num; ++i) {
if(m->count[i] == 0) {
/* If this block was unused, we increase the reference count to
indicate that it now is used and return a pointer to the
memory block. */
++(m->count[i]);
return (void *)((char *)m->mem + (i * m->size));
}
}
/* No free block was found, so we return NULL to indicate failure to
allocate block. */
return NULL;
}
/*---------------------------------------------------------------------------*/
char
memb_free(struct memb_blocks *m, void *ptr)
{
int i;
char *ptr2;
/* Walk through the list of blocks and try to find the block to
which the pointer "ptr" points to. */
ptr2 = (char *)m->mem;
for(i = 0; i < m->num; ++i) {
if(ptr2 == (char *)ptr) {
/* We've found to block to which "ptr" points so we decrease the
reference count and return the new value of it. */
if(m->count[i] > 0) {
/* Make sure that we don't deallocate free memory. */
--(m->count[i]);
}
return m->count[i];
}
ptr2 += m->size;
}
return -1;
}
/*---------------------------------------------------------------------------*/
/** @} */

142
android/uip/lib/memb.h Normal file
View File

@ -0,0 +1,142 @@
/*
* Copyright (c) 2004, 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: memb.h,v 1.1 2006/06/12 08:21:43 adam Exp $
*/
/**
* \defgroup memb Memory block management functions
*
* The memory block allocation routines provide a simple yet powerful
* set of functions for managing a set of memory blocks of fixed
* size. A set of memory blocks is statically declared with the
* MEMB() macro. Memory blocks are allocated from the declared
* memory by the memb_alloc() function, and are deallocated with the
* memb_free() function.
*
* \note Because of namespace clashes only one MEMB() can be
* declared per C module, and the name scope of a MEMB() memory
* block is local to each C module.
*
* The following example shows how to declare and use a memory block
* called "cmem" which has 8 chunks of memory with each memory chunk
* being 20 bytes large.
*
* @{
*/
/**
* \file
* Memory block allocation routines.
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#ifndef __MEMB_H__
#define __MEMB_H__
/*
* Here we define a C preprocessing macro for concatenating to
* strings. We need use two macros in order to allow concatenation of
* two #defined macros.
*/
#define MEMB_CONCAT2(s1, s2) s1##s2
#define MEMB_CONCAT(s1, s2) MEMB_CONCAT2(s1, s2)
/**
* Declare a memory block.
*
* This macro is used to staticall declare a block of memory that can
* be used by the block allocation functions. The macro statically
* declares a C array with a size that matches the specified number of
* blocks and their individual sizes.
*
* Example:
\code
MEMB(connections, sizeof(struct connection), 16);
\endcode
*
* \param name The name of the memory block (later used with
* memb_init(), memb_alloc() and memb_free()).
*
* \param size The size of each memory chunk, in bytes.
*
* \param num The total number of memory chunks in the block.
*
*/
#define MEMB(name, structure, num) \
static char MEMB_CONCAT(name,_memb_count)[num]; \
static structure MEMB_CONCAT(name,_memb_mem)[num]; \
static struct memb_blocks name = {sizeof(structure), num, \
MEMB_CONCAT(name,_memb_count), \
(void *)MEMB_CONCAT(name,_memb_mem)}
struct memb_blocks {
unsigned short size;
unsigned short num;
char *count;
void *mem;
};
/**
* Initialize a memory block that was declared with MEMB().
*
* \param m A memory block previosly declared with MEMB().
*/
void memb_init(struct memb_blocks *m);
/**
* Allocate a memory block from a block of memory declared with MEMB().
*
* \param m A memory block previosly declared with MEMB().
*/
void *memb_alloc(struct memb_blocks *m);
/**
* Deallocate a memory block from a memory block previously declared
* with MEMB().
*
* \param m m A memory block previosly declared with MEMB().
*
* \param ptr A pointer to the memory block that is to be deallocated.
*
* \return The new reference count for the memory block (should be 0
* if successfully deallocated) or -1 if the pointer "ptr" did not
* point to a legal memory block.
*/
char memb_free(struct memb_blocks *m, void *ptr);
/** @} */
#endif /* __MEMB_H__ */

View File

@ -0,0 +1,98 @@
* A new API: protosockets that are similar to BSD sockets but does not
require any underlying multithreading system.
* Very rudimentary IPv6 support
* New application: DHCP client. Web server rewritten with protosockets.
* Removed uIP zero-copy functionality in order to simplify uIP device
driver coding: outbound packets are now *always* stored in full in
the uip_buf buffer.
* Checksum computation is now part of uip.c, but it still is possible
to implement them in assembly code by specifying a configuration
option. Checksum code now runs on architectures with 2-byte alignment.
* Added TCP persistent timer.
* Made all IP address representations use the new uip_ipaddr_ip
datatype for clarity.
* Updated window behavior so that sending to a host with a small open
window works better now.
* UDP API change: uip_udp_new() now takes port numbers in network byte
order like TCP functions.
* Allow reception of packets when no IP address is configured to make
DHCP work.
* Moved Ethernet address into main uIP module from ARP module.
* Made constants explicit #defines and moved them out of the code
(header sizes, TCP options, TCP header length field).
* If uip_len is less than that reported by the IP header, the packet
is discarded. If uip_len is greater than the length reported by the
IP header, uip_len is adjusted.
* Moved header size definitions into header file.
* Added uIP call for polling an application without triggering any
timer events. Removed redundant assignments of uip_len and uip_slen.
* Removed compiler warning about icmp_input label being defined when
UIP_PINGADDRCONF was not used.
* Added UIP_APPDATA_SIZE macro that holds the available buffer size
for user data.
* Added uip_udp_bind() call.
* Moved checksum code into main uIP module.
* Switched the TCP, UDP and IP header structures to be structs rather
than typedefs.
* Prefixed TCP state names with UIP_ to avoid name space
contamination.
* Changed declarations of uip_appdatap and friends to void * to avoid
explicit typecasts.
* Bugfixes
o TCP: Fixed bug with high byte of peer window size.
o TCP: Fixed bug that in some cases prevented concurrent reception and
transmission of TCP data.
o TCP: uip_connect() didn't correctly calculate age of TIME_WAIT
connections.
o TCP: Array index for uip_conns[] array was out of bounds in
comparison. Comparison changed to make index within bounds.
o TCP: if the remote host crashes and tries to reestablish an old
connection, uIP should respond with an ACK with the correct
sequence and acknowledgment numbers, to which the remote host
should respond with an ACK. uIP did not respond with the correct
ACK.
o TCP: Fixed check for SYNACK segment: now checks only relevant TCP
control flags and discards flags reserved for future expansion.
o TCP: Fixed bug where uIP did not inform application that a connection
had been aborted during an active open.
o TCP: FIN segment was accepted even though application had stopped
incoming data with uip_stop().
o TCP: A FINACK segment would not always correctly acknowledge data.
o UDP: checksums are now calculated after all fields have been
filled in.
o UDP: network byte order on lastport in uip_udp_new().
o IP: memset() bugs in IP fragment reassembly code fixed.

View File

@ -0,0 +1,47 @@
ifdef APPS
APPDIRS = $(foreach APP, $(APPS), ../apps/$(APP))
-include $(foreach APP, $(APPS), ../apps/$(APP)/Makefile.$(APP))
CFLAGS += $(addprefix -I../apps/,$(APPS))
endif
ifndef CCDEP
CCDEP = $(CC)
endif
ifndef CCDEPCFLAGS
CCDEPCFLAGS = $(CFLAGS)
endif
ifndef OBJECTDIR
OBJECTDIR = obj
endif
ifeq (${wildcard $(OBJECTDIR)},)
DUMMY := ${shell mkdir $(OBJECTDIR)}
endif
vpath %.c . ../uip ../lib $(APPDIRS)
$(OBJECTDIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
$(OBJECTDIR)/%.d: %.c
@set -e; rm -f $@; \
$(CCDEP) -MM $(CCDEPCFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,$(OBJECTDIR)/\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
UIP_SOURCES=uip.c uip_arp.c uiplib.c psock.c timer.c uip-neighbor.c
ifneq ($(MAKECMDGOALS),clean)
-include $(addprefix $(OBJECTDIR)/,$(UIP_SOURCES:.c=.d) \
$(APP_SOURCES:.c=.d))
endif
uip.a: ${addprefix $(OBJECTDIR)/, $(UIP_SOURCES:.c=.o)}
$(AR) rcf $@ $^
apps.a: ${addprefix $(OBJECTDIR)/, $(APP_SOURCES:.c=.o)}
$(AR) rcf $@ $^

88
android/uip/uip/clock.h Normal file
View File

@ -0,0 +1,88 @@
/**
* \defgroup clock Clock interface
*
* The clock interface is the interface between the \ref timer "timer library"
* and the platform specific clock functionality. The clock
* interface must be implemented for each platform that uses the \ref
* timer "timer library".
*
* The clock interface does only one this: it measures time. The clock
* interface provides a macro, CLOCK_SECOND, which corresponds to one
* second of system time.
*
* \sa \ref timer "Timer library"
*
* @{
*/
/*
* Copyright (c) 2004, 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: clock.h,v 1.3 2006/06/11 21:46:39 adam Exp $
*/
#ifndef __CLOCK_H__
#define __CLOCK_H__
#include "clock-arch.h"
/**
* Initialize the clock library.
*
* This function initializes the clock library and should be called
* from the main() function of the system.
*
*/
void clock_init(void);
/**
* Get the current clock time.
*
* This function returns the current system clock time.
*
* \return The current clock time, measured in system ticks.
*/
clock_time_t clock_time(void);
/**
* A second, measured in system clock time.
*
* \hideinitializer
*/
#ifdef CLOCK_CONF_SECOND
#define CLOCK_SECOND CLOCK_CONF_SECOND
#else
#define CLOCK_SECOND (clock_time_t)32
#endif
#endif /* __CLOCK_H__ */
/** @} */

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2004-2005, 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: lc-addrlabels.h,v 1.3 2006/06/12 08:00:30 adam Exp $
*/
/**
* \addtogroup lc
* @{
*/
/**
* \file
* Implementation of local continuations based on the "Labels as
* values" feature of gcc
* \author
* Adam Dunkels <adam@sics.se>
*
* This implementation of local continuations is based on a special
* feature of the GCC C compiler called "labels as values". This
* feature allows assigning pointers with the address of the code
* corresponding to a particular C label.
*
* For more information, see the GCC documentation:
* http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
*
* Thanks to dividuum for finding the nice local scope label
* implementation.
*/
#ifndef __LC_ADDRLABELS_H__
#define __LC_ADDRLABELS_H__
/** \hideinitializer */
typedef void * lc_t;
#define LC_INIT(s) s = NULL
#define LC_RESUME(s) \
do { \
if(s != NULL) { \
goto *s; \
} \
} while(0)
#define LC_SET(s) \
do { ({ __label__ resume; resume: (s) = &&resume; }); }while(0)
#define LC_END(s)
#endif /* __LC_ADDRLABELS_H__ */
/** @} */

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2004-2005, 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: lc-switch.h,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
/**
* \addtogroup lc
* @{
*/
/**
* \file
* Implementation of local continuations based on switch() statment
* \author Adam Dunkels <adam@sics.se>
*
* This implementation of local continuations uses the C switch()
* statement to resume execution of a function somewhere inside the
* function's body. The implementation is based on the fact that
* switch() statements are able to jump directly into the bodies of
* control structures such as if() or while() statmenets.
*
* This implementation borrows heavily from Simon Tatham's coroutines
* implementation in C:
* http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
*/
#ifndef __LC_SWITCH_H__
#define __LC_SWTICH_H__
/* WARNING! lc implementation using switch() does not work if an
LC_SET() is done within another switch() statement! */
/** \hideinitializer */
typedef unsigned short lc_t;
#define LC_INIT(s) s = 0;
#define LC_RESUME(s) switch(s) { case 0:
#define LC_SET(s) s = __LINE__; case __LINE__:
#define LC_END(s) }
#endif /* __LC_SWITCH_H__ */
/** @} */

131
android/uip/uip/lc.h Normal file
View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2004-2005, 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: lc.h,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
/**
* \addtogroup pt
* @{
*/
/**
* \defgroup lc Local continuations
* @{
*
* Local continuations form the basis for implementing protothreads. A
* local continuation can be <i>set</i> in a specific function to
* capture the state of the function. After a local continuation has
* been set can be <i>resumed</i> in order to restore the state of the
* function at the point where the local continuation was set.
*
*
*/
/**
* \file lc.h
* Local continuations
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#ifdef DOXYGEN
/**
* Initialize a local continuation.
*
* This operation initializes the local continuation, thereby
* unsetting any previously set continuation state.
*
* \hideinitializer
*/
#define LC_INIT(lc)
/**
* Set a local continuation.
*
* The set operation saves the state of the function at the point
* where the operation is executed. As far as the set operation is
* concerned, the state of the function does <b>not</b> include the
* call-stack or local (automatic) variables, but only the program
* counter and such CPU registers that needs to be saved.
*
* \hideinitializer
*/
#define LC_SET(lc)
/**
* Resume a local continuation.
*
* The resume operation resumes a previously set local continuation, thus
* restoring the state in which the function was when the local
* continuation was set. If the local continuation has not been
* previously set, the resume operation does nothing.
*
* \hideinitializer
*/
#define LC_RESUME(lc)
/**
* Mark the end of local continuation usage.
*
* The end operation signifies that local continuations should not be
* used any more in the function. This operation is not needed for
* most implementations of local continuation, but is required by a
* few implementations.
*
* \hideinitializer
*/
#define LC_END(lc)
/**
* \var typedef lc_t;
*
* The local continuation type.
*
* \hideinitializer
*/
#endif /* DOXYGEN */
#ifndef __LC_H__
#define __LC_H__
#ifdef LC_CONF_INCLUDE
#include LC_CONF_INCLUDE
#else
#include "lc-switch.h"
#endif /* LC_CONF_INCLUDE */
#endif /* __LC_H__ */
/** @} */
/** @} */

338
android/uip/uip/psock.c Normal file
View File

@ -0,0 +1,338 @@
/*
* Copyright (c) 2004, 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
#include <stdio.h>
#include <string.h>
#include "uipopt.h"
#include "psock.h"
#include "uip.h"
#define STATE_NONE 0
#define STATE_ACKED 1
#define STATE_READ 2
#define STATE_BLOCKED_NEWDATA 3
#define STATE_BLOCKED_CLOSE 4
#define STATE_BLOCKED_SEND 5
#define STATE_DATA_SENT 6
/*
* Return value of the buffering functions that indicates that a
* buffer was not filled by incoming data.
*
*/
#define BUF_NOT_FULL 0
#define BUF_NOT_FOUND 0
/*
* Return value of the buffering functions that indicates that a
* buffer was completely filled by incoming data.
*
*/
#define BUF_FULL 1
/*
* Return value of the buffering functions that indicates that an
* end-marker byte was found.
*
*/
#define BUF_FOUND 2
/*---------------------------------------------------------------------------*/
static void
buf_setup(struct psock_buf *buf,
u8_t *bufptr, u16_t bufsize)
{
buf->ptr = bufptr;
buf->left = bufsize;
}
/*---------------------------------------------------------------------------*/
static u8_t
buf_bufdata(struct psock_buf *buf, u16_t len,
u8_t **dataptr, u16_t *datalen)
{
if(*datalen < buf->left) {
memcpy(buf->ptr, *dataptr, *datalen);
buf->ptr += *datalen;
buf->left -= *datalen;
*dataptr += *datalen;
*datalen = 0;
return BUF_NOT_FULL;
} else if(*datalen == buf->left) {
memcpy(buf->ptr, *dataptr, *datalen);
buf->ptr += *datalen;
buf->left = 0;
*dataptr += *datalen;
*datalen = 0;
return BUF_FULL;
} else {
memcpy(buf->ptr, *dataptr, buf->left);
buf->ptr += buf->left;
*datalen -= buf->left;
*dataptr += buf->left;
buf->left = 0;
return BUF_FULL;
}
}
/*---------------------------------------------------------------------------*/
static u8_t
buf_bufto(register struct psock_buf *buf, u8_t endmarker,
register u8_t **dataptr, register u16_t *datalen)
{
u8_t c;
while(buf->left > 0 && *datalen > 0) {
c = *buf->ptr = **dataptr;
++*dataptr;
++buf->ptr;
--*datalen;
--buf->left;
if(c == endmarker) {
return BUF_FOUND;
}
}
if(*datalen == 0) {
return BUF_NOT_FOUND;
}
while(*datalen > 0) {
c = **dataptr;
--*datalen;
++*dataptr;
if(c == endmarker) {
return BUF_FOUND | BUF_FULL;
}
}
return BUF_FULL;
}
/*---------------------------------------------------------------------------*/
static char
send_data(register struct psock *s)
{
if(s->state != STATE_DATA_SENT || uip_rexmit()) {
if(s->sendlen > uip_mss()) {
uip_send(s->sendptr, uip_mss());
} else {
uip_send(s->sendptr, s->sendlen);
}
s->state = STATE_DATA_SENT;
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static char
data_acked(register struct psock *s)
{
if(s->state == STATE_DATA_SENT && uip_acked()) {
if(s->sendlen > uip_mss()) {
s->sendlen -= uip_mss();
s->sendptr += uip_mss();
} else {
s->sendptr += s->sendlen;
s->sendlen = 0;
}
s->state = STATE_ACKED;
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
PT_THREAD(psock_send(register struct psock *s, const char *buf,
unsigned int len))
{
PT_BEGIN(&s->psockpt);
/* If there is no data to send, we exit immediately. */
if(len == 0) {
PT_EXIT(&s->psockpt);
}
/* Save the length of and a pointer to the data that is to be
sent. */
s->sendptr = buf;
s->sendlen = len;
s->state = STATE_NONE;
/* We loop here until all data is sent. The s->sendlen variable is
updated by the data_sent() function. */
while(s->sendlen > 0) {
/*
* The condition for this PT_WAIT_UNTIL is a little tricky: the
* protothread will wait here until all data has been acknowledged
* (data_acked() returns true) and until all data has been sent
* (send_data() returns true). The two functions data_acked() and
* send_data() must be called in succession to ensure that all
* data is sent. Therefore the & operator is used instead of the
* && operator, which would cause only the data_acked() function
* to be called when it returns false.
*/
PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
}
s->state = STATE_NONE;
PT_END(&s->psockpt);
}
/*---------------------------------------------------------------------------*/
PT_THREAD(psock_generator_send(register struct psock *s,
unsigned short (*generate)(void *), void *arg))
{
PT_BEGIN(&s->psockpt);
/* Ensure that there is a generator function to call. */
if(generate == NULL) {
PT_EXIT(&s->psockpt);
}
/* Call the generator function to generate the data in the
uip_appdata buffer. */
s->sendlen = generate(arg);
s->sendptr = uip_appdata;
s->state = STATE_NONE;
do {
/* Call the generator function again if we are called to perform a
retransmission. */
if(uip_rexmit()) {
generate(arg);
}
/* Wait until all data is sent and acknowledged. */
PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
} while(s->sendlen > 0);
s->state = STATE_NONE;
PT_END(&s->psockpt);
}
/*---------------------------------------------------------------------------*/
u16_t
psock_datalen(struct psock *psock)
{
return psock->bufsize - psock->buf.left;
}
/*---------------------------------------------------------------------------*/
char
psock_newdata(struct psock *s)
{
if(s->readlen > 0) {
/* There is data in the uip_appdata buffer that has not yet been
read with the PSOCK_READ functions. */
return 1;
} else if(s->state == STATE_READ) {
/* All data in uip_appdata buffer already consumed. */
s->state = STATE_BLOCKED_NEWDATA;
return 0;
} else if(uip_newdata()) {
/* There is new data that has not been consumed. */
return 1;
} else {
/* There is no new data. */
return 0;
}
}
/*---------------------------------------------------------------------------*/
PT_THREAD(psock_readto(register struct psock *psock, unsigned char c))
{
PT_BEGIN(&psock->psockpt);
buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
/* XXX: Should add buf_checkmarker() before do{} loop, if
incoming data has been handled while waiting for a write. */
do {
if(psock->readlen == 0) {
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
psock->state = STATE_READ;
psock->readptr = (u8_t *)uip_appdata;
psock->readlen = uip_datalen();
}
} while((buf_bufto(&psock->buf, c,
&psock->readptr,
&psock->readlen) & BUF_FOUND) == 0);
if(psock_datalen(psock) == 0) {
psock->state = STATE_NONE;
PT_RESTART(&psock->psockpt);
}
PT_END(&psock->psockpt);
}
/*---------------------------------------------------------------------------*/
PT_THREAD(psock_readbuf(register struct psock *psock))
{
PT_BEGIN(&psock->psockpt);
buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
/* XXX: Should add buf_checkmarker() before do{} loop, if
incoming data has been handled while waiting for a write. */
do {
if(psock->readlen == 0) {
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
printf("Waited for newdata\n");
psock->state = STATE_READ;
psock->readptr = (u8_t *)uip_appdata;
psock->readlen = uip_datalen();
}
} while(buf_bufdata(&psock->buf, psock->bufsize,
&psock->readptr,
&psock->readlen) != BUF_FULL);
if(psock_datalen(psock) == 0) {
psock->state = STATE_NONE;
PT_RESTART(&psock->psockpt);
}
PT_END(&psock->psockpt);
}
/*---------------------------------------------------------------------------*/
void
psock_init(register struct psock *psock, char *buffer, unsigned int buffersize)
{
psock->state = STATE_NONE;
psock->readlen = 0;
psock->bufptr = buffer;
psock->bufsize = buffersize;
buf_setup(&psock->buf, buffer, buffersize);
PT_INIT(&psock->pt);
PT_INIT(&psock->psockpt);
}
/*---------------------------------------------------------------------------*/

380
android/uip/uip/psock.h Normal file
View File

@ -0,0 +1,380 @@
/*
* Copyright (c) 2004, 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: psock.h,v 1.3 2006/06/12 08:00:30 adam Exp $
*/
/**
* \defgroup psock Protosockets library
* @{
*
* The protosocket library provides an interface to the uIP stack that is
* similar to the traditional BSD socket interface. Unlike programs
* written for the ordinary uIP event-driven interface, programs
* written with the protosocket library are executed in a sequential
* fashion and does not have to be implemented as explicit state
* machines.
*
* Protosockets only work with TCP connections.
*
* The protosocket library uses \ref pt protothreads to provide
* sequential control flow. This makes the protosockets lightweight in
* terms of memory, but also means that protosockets inherits the
* functional limitations of protothreads. Each protosocket lives only
* within a single function. Automatic variables (stack variables) are
* not retained across a protosocket library function call.
*
* \note Because the protosocket library uses protothreads, local
* variables will not always be saved across a call to a protosocket
* library function. It is therefore advised that local variables are
* used with extreme care.
*
* The protosocket library provides functions for sending data without
* having to deal with retransmissions and acknowledgements, as well
* as functions for reading data without having to deal with data
* being split across more than one TCP segment.
*
* Because each protosocket runs as a protothread, the protosocket has to be
* started with a call to PSOCK_BEGIN() at the start of the function
* in which the protosocket is used. Similarly, the protosocket protothread can
* be terminated by a call to PSOCK_EXIT().
*
*/
/**
* \file
* Protosocket library header file
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#ifndef __PSOCK_H__
#define __PSOCK_H__
#include "uipopt.h"
#include "pt.h"
/*
* The structure that holds the state of a buffer.
*
* This structure holds the state of a uIP buffer. The structure has
* no user-visible elements, but is used through the functions
* provided by the library.
*
*/
struct psock_buf {
u8_t *ptr;
unsigned short left;
};
/**
* The representation of a protosocket.
*
* The protosocket structrure is an opaque structure with no user-visible
* elements.
*/
struct psock {
struct pt pt, psockpt; /* Protothreads - one that's using the psock
functions, and one that runs inside the
psock functions. */
const u8_t *sendptr; /* Pointer to the next data to be sent. */
u8_t *readptr; /* Pointer to the next data to be read. */
char *bufptr; /* Pointer to the buffer used for buffering
incoming data. */
u16_t sendlen; /* The number of bytes left to be sent. */
u16_t readlen; /* The number of bytes left to be read. */
struct psock_buf buf; /* The structure holding the state of the
input buffer. */
unsigned int bufsize; /* The size of the input buffer. */
unsigned char state; /* The state of the protosocket. */
};
void psock_init(struct psock *psock, char *buffer, unsigned int buffersize);
/**
* Initialize a protosocket.
*
* This macro initializes a protosocket and must be called before the
* protosocket is used. The initialization also specifies the input buffer
* for the protosocket.
*
* \param psock (struct psock *) A pointer to the protosocket to be
* initialized
*
* \param buffer (char *) A pointer to the input buffer for the
* protosocket.
*
* \param buffersize (unsigned int) The size of the input buffer.
*
* \hideinitializer
*/
#define PSOCK_INIT(psock, buffer, buffersize) \
psock_init(psock, buffer, buffersize)
/**
* Start the protosocket protothread in a function.
*
* This macro starts the protothread associated with the protosocket and
* must come before other protosocket calls in the function it is used.
*
* \param psock (struct psock *) A pointer to the protosocket to be
* started.
*
* \hideinitializer
*/
#define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt))
PT_THREAD(psock_send(struct psock *psock, const char *buf, unsigned int len));
/**
* Send data.
*
* This macro sends data over a protosocket. The protosocket protothread blocks
* until all data has been sent and is known to have been received by
* the remote end of the TCP connection.
*
* \param psock (struct psock *) A pointer to the protosocket over which
* data is to be sent.
*
* \param data (char *) A pointer to the data that is to be sent.
*
* \param datalen (unsigned int) The length of the data that is to be
* sent.
*
* \hideinitializer
*/
#define PSOCK_SEND(psock, data, datalen) \
PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, data, datalen))
/**
* \brief Send a null-terminated string.
* \param psock Pointer to the protosocket.
* \param str The string to be sent.
*
* This function sends a null-terminated string over the
* protosocket.
*
* \hideinitializer
*/
#define PSOCK_SEND_STR(psock, str) \
PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, str, strlen(str)))
PT_THREAD(psock_generator_send(struct psock *psock,
unsigned short (*f)(void *), void *arg));
/**
* \brief Generate data with a function and send it
* \param psock Pointer to the protosocket.
* \param generator Pointer to the generator function
* \param arg Argument to the generator function
*
* This function generates data and sends it over the
* protosocket. This can be used to dynamically generate
* data for a transmission, instead of generating the data
* in a buffer beforehand. This function reduces the need for
* buffer memory. The generator function is implemented by
* the application, and a pointer to the function is given
* as an argument with the call to PSOCK_GENERATOR_SEND().
*
* The generator function should place the generated data
* directly in the uip_appdata buffer, and return the
* length of the generated data. The generator function is
* called by the protosocket layer when the data first is
* sent, and once for every retransmission that is needed.
*
* \hideinitializer
*/
#define PSOCK_GENERATOR_SEND(psock, generator, arg) \
PT_WAIT_THREAD(&((psock)->pt), \
psock_generator_send(psock, generator, arg))
/**
* Close a protosocket.
*
* This macro closes a protosocket and can only be called from within the
* protothread in which the protosocket lives.
*
* \param psock (struct psock *) A pointer to the protosocket that is to
* be closed.
*
* \hideinitializer
*/
#define PSOCK_CLOSE(psock) uip_close()
PT_THREAD(psock_readbuf(struct psock *psock));
/**
* Read data until the buffer is full.
*
* This macro will block waiting for data and read the data into the
* input buffer specified with the call to PSOCK_INIT(). Data is read
* until the buffer is full..
*
* \param psock (struct psock *) A pointer to the protosocket from which
* data should be read.
*
* \hideinitializer
*/
#define PSOCK_READBUF(psock) \
PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock))
PT_THREAD(psock_readto(struct psock *psock, unsigned char c));
/**
* Read data up to a specified character.
*
* This macro will block waiting for data and read the data into the
* input buffer specified with the call to PSOCK_INIT(). Data is only
* read until the specifieed character appears in the data stream.
*
* \param psock (struct psock *) A pointer to the protosocket from which
* data should be read.
*
* \param c (char) The character at which to stop reading.
*
* \hideinitializer
*/
#define PSOCK_READTO(psock, c) \
PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c))
/**
* The length of the data that was previously read.
*
* This macro returns the length of the data that was previously read
* using PSOCK_READTO() or PSOCK_READ().
*
* \param psock (struct psock *) A pointer to the protosocket holding the data.
*
* \hideinitializer
*/
#define PSOCK_DATALEN(psock) psock_datalen(psock)
u16_t psock_datalen(struct psock *psock);
/**
* Exit the protosocket's protothread.
*
* This macro terminates the protothread of the protosocket and should
* almost always be used in conjunction with PSOCK_CLOSE().
*
* \sa PSOCK_CLOSE_EXIT()
*
* \param psock (struct psock *) A pointer to the protosocket.
*
* \hideinitializer
*/
#define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt))
/**
* Close a protosocket and exit the protosocket's protothread.
*
* This macro closes a protosocket and exits the protosocket's protothread.
*
* \param psock (struct psock *) A pointer to the protosocket.
*
* \hideinitializer
*/
#define PSOCK_CLOSE_EXIT(psock) \
do { \
PSOCK_CLOSE(psock); \
PSOCK_EXIT(psock); \
} while(0)
/**
* Declare the end of a protosocket's protothread.
*
* This macro is used for declaring that the protosocket's protothread
* ends. It must always be used together with a matching PSOCK_BEGIN()
* macro.
*
* \param psock (struct psock *) A pointer to the protosocket.
*
* \hideinitializer
*/
#define PSOCK_END(psock) PT_END(&((psock)->pt))
char psock_newdata(struct psock *s);
/**
* Check if new data has arrived on a protosocket.
*
* This macro is used in conjunction with the PSOCK_WAIT_UNTIL()
* macro to check if data has arrived on a protosocket.
*
* \param psock (struct psock *) A pointer to the protosocket.
*
* \hideinitializer
*/
#define PSOCK_NEWDATA(psock) psock_newdata(psock)
/**
* Wait until a condition is true.
*
* This macro blocks the protothread until the specified condition is
* true. The macro PSOCK_NEWDATA() can be used to check if new data
* arrives when the protosocket is waiting.
*
* Typically, this macro is used as follows:
*
\code
PT_THREAD(thread(struct psock *s, struct timer *t))
{
PSOCK_BEGIN(s);
PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t));
if(PSOCK_NEWDATA(s)) {
PSOCK_READTO(s, '\n');
} else {
handle_timed_out(s);
}
PSOCK_END(s);
}
\endcode
*
* \param psock (struct psock *) A pointer to the protosocket.
* \param condition The condition to wait for.
*
* \hideinitializer
*/
#define PSOCK_WAIT_UNTIL(psock, condition) \
PT_WAIT_UNTIL(&((psock)->pt), (condition));
#define PSOCK_WAIT_THREAD(psock, condition) \
PT_WAIT_THREAD(&((psock)->pt), (condition))
#endif /* __PSOCK_H__ */
/** @} */

323
android/uip/uip/pt.h Normal file
View File

@ -0,0 +1,323 @@
/*
* Copyright (c) 2004-2005, 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
/**
* \addtogroup pt
* @{
*/
/**
* \file
* Protothreads implementation.
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#ifndef __PT_H__
#define __PT_H__
#include "lc.h"
struct pt {
lc_t lc;
};
#define PT_WAITING 0
#define PT_EXITED 1
#define PT_ENDED 2
#define PT_YIELDED 3
/**
* \name Initialization
* @{
*/
/**
* Initialize a protothread.
*
* Initializes a protothread. Initialization must be done prior to
* starting to execute the protothread.
*
* \param pt A pointer to the protothread control structure.
*
* \sa PT_SPAWN()
*
* \hideinitializer
*/
#define PT_INIT(pt) LC_INIT((pt)->lc)
/** @} */
/**
* \name Declaration and definition
* @{
*/
/**
* Declaration of a protothread.
*
* This macro is used to declare a protothread. All protothreads must
* be declared with this macro.
*
* \param name_args The name and arguments of the C function
* implementing the protothread.
*
* \hideinitializer
*/
#define PT_THREAD(name_args) char name_args
/**
* Declare the start of a protothread inside the C function
* implementing the protothread.
*
* This macro is used to declare the starting point of a
* protothread. It should be placed at the start of the function in
* which the protothread runs. All C statements above the PT_BEGIN()
* invokation will be executed each time the protothread is scheduled.
*
* \param pt A pointer to the protothread control structure.
*
* \hideinitializer
*/
#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
/**
* Declare the end of a protothread.
*
* This macro is used for declaring that a protothread ends. It must
* always be used together with a matching PT_BEGIN() macro.
*
* \param pt A pointer to the protothread control structure.
*
* \hideinitializer
*/
#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
PT_INIT(pt); return PT_ENDED; }
/** @} */
/**
* \name Blocked wait
* @{
*/
/**
* Block and wait until condition is true.
*
* This macro blocks the protothread until the specified condition is
* true.
*
* \param pt A pointer to the protothread control structure.
* \param condition The condition.
*
* \hideinitializer
*/
#define PT_WAIT_UNTIL(pt, condition) \
do { \
LC_SET((pt)->lc); \
if(!(condition)) { \
return PT_WAITING; \
} \
} while(0)
/**
* Block and wait while condition is true.
*
* This function blocks and waits while condition is true. See
* PT_WAIT_UNTIL().
*
* \param pt A pointer to the protothread control structure.
* \param cond The condition.
*
* \hideinitializer
*/
#define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond))
/** @} */
/**
* \name Hierarchical protothreads
* @{
*/
/**
* Block and wait until a child protothread completes.
*
* This macro schedules a child protothread. The current protothread
* will block until the child protothread completes.
*
* \note The child protothread must be manually initialized with the
* PT_INIT() function before this function is used.
*
* \param pt A pointer to the protothread control structure.
* \param thread The child protothread with arguments
*
* \sa PT_SPAWN()
*
* \hideinitializer
*/
#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
/**
* Spawn a child protothread and wait until it exits.
*
* This macro spawns a child protothread and waits until it exits. The
* macro can only be used within a protothread.
*
* \param pt A pointer to the protothread control structure.
* \param child A pointer to the child protothread's control structure.
* \param thread The child protothread with arguments
*
* \hideinitializer
*/
#define PT_SPAWN(pt, child, thread) \
do { \
PT_INIT((child)); \
PT_WAIT_THREAD((pt), (thread)); \
} while(0)
/** @} */
/**
* \name Exiting and restarting
* @{
*/
/**
* Restart the protothread.
*
* This macro will block and cause the running protothread to restart
* its execution at the place of the PT_BEGIN() call.
*
* \param pt A pointer to the protothread control structure.
*
* \hideinitializer
*/
#define PT_RESTART(pt) \
do { \
PT_INIT(pt); \
return PT_WAITING; \
} while(0)
/**
* Exit the protothread.
*
* This macro causes the protothread to exit. If the protothread was
* spawned by another protothread, the parent protothread will become
* unblocked and can continue to run.
*
* \param pt A pointer to the protothread control structure.
*
* \hideinitializer
*/
#define PT_EXIT(pt) \
do { \
PT_INIT(pt); \
return PT_EXITED; \
} while(0)
/** @} */
/**
* \name Calling a protothread
* @{
*/
/**
* Schedule a protothread.
*
* This function shedules a protothread. The return value of the
* function is non-zero if the protothread is running or zero if the
* protothread has exited.
*
* \param f The call to the C function implementing the protothread to
* be scheduled
*
* \hideinitializer
*/
#define PT_SCHEDULE(f) ((f) == PT_WAITING)
/** @} */
/**
* \name Yielding from a protothread
* @{
*/
/**
* Yield from the current protothread.
*
* This function will yield the protothread, thereby allowing other
* processing to take place in the system.
*
* \param pt A pointer to the protothread control structure.
*
* \hideinitializer
*/
#define PT_YIELD(pt) \
do { \
PT_YIELD_FLAG = 0; \
LC_SET((pt)->lc); \
if(PT_YIELD_FLAG == 0) { \
return PT_YIELDED; \
} \
} while(0)
/**
* \brief Yield from the protothread until a condition occurs.
* \param pt A pointer to the protothread control structure.
* \param cond The condition.
*
* This function will yield the protothread, until the
* specified condition evaluates to true.
*
*
* \hideinitializer
*/
#define PT_YIELD_UNTIL(pt, cond) \
do { \
PT_YIELD_FLAG = 0; \
LC_SET((pt)->lc); \
if((PT_YIELD_FLAG == 0) || !(cond)) { \
return PT_YIELDED; \
} \
} while(0)
/** @} */
#endif /* __PT_H__ */
/** @} */

127
android/uip/uip/timer.c Normal file
View File

@ -0,0 +1,127 @@
/**
* \addtogroup timer
* @{
*/
/**
* \file
* Timer library implementation.
* \author
* Adam Dunkels <adam@sics.se>
*/
/*
* Copyright (c) 2004, 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: timer.c,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
#include "clock.h"
#include "timer.h"
/*---------------------------------------------------------------------------*/
/**
* Set a timer.
*
* This function is used to set a timer for a time sometime in the
* future. The function timer_expired() will evaluate to true after
* the timer has expired.
*
* \param t A pointer to the timer
* \param interval The interval before the timer expires.
*
*/
void
timer_set(struct timer *t, clock_time_t interval)
{
t->interval = interval;
t->start = clock_time();
}
/*---------------------------------------------------------------------------*/
/**
* Reset the timer with the same interval.
*
* This function resets the timer with the same interval that was
* given to the timer_set() function. The start point of the interval
* is the exact time that the timer last expired. Therefore, this
* function will cause the timer to be stable over time, unlike the
* timer_rester() function.
*
* \param t A pointer to the timer.
*
* \sa timer_restart()
*/
void
timer_reset(struct timer *t)
{
t->start += t->interval;
}
/*---------------------------------------------------------------------------*/
/**
* Restart the timer from the current point in time
*
* This function restarts a timer with the same interval that was
* given to the timer_set() function. The timer will start at the
* current time.
*
* \note A periodic timer will drift if this function is used to reset
* it. For preioric timers, use the timer_reset() function instead.
*
* \param t A pointer to the timer.
*
* \sa timer_reset()
*/
void
timer_restart(struct timer *t)
{
t->start = clock_time();
}
/*---------------------------------------------------------------------------*/
/**
* Check if a timer has expired.
*
* This function tests if a timer has expired and returns true or
* false depending on its status.
*
* \param t A pointer to the timer
*
* \return Non-zero if the timer has expired, zero otherwise.
*
*/
int
timer_expired(struct timer *t)
{
return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval;
}
/*---------------------------------------------------------------------------*/
/** @} */

86
android/uip/uip/timer.h Normal file
View File

@ -0,0 +1,86 @@
/**
* \defgroup timer Timer library
*
* The timer library provides functions for setting, resetting and
* restarting timers, and for checking if a timer has expired. An
* application must "manually" check if its timers have expired; this
* is not done automatically.
*
* A timer is declared as a \c struct \c timer and all access to the
* timer is made by a pointer to the declared timer.
*
* \note The timer library uses the \ref clock "Clock library" to
* measure time. Intervals should be specified in the format used by
* the clock library.
*
* @{
*/
/**
* \file
* Timer library header file.
* \author
* Adam Dunkels <adam@sics.se>
*/
/*
* Copyright (c) 2004, 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: timer.h,v 1.3 2006/06/11 21:46:39 adam Exp $
*/
#ifndef __TIMER_H__
#define __TIMER_H__
#include "clock.h"
/**
* A timer.
*
* This structure is used for declaring a timer. The timer must be set
* with timer_set() before it can be used.
*
* \hideinitializer
*/
struct timer {
clock_time_t start;
clock_time_t interval;
};
void timer_set(struct timer *t, clock_time_t interval);
void timer_reset(struct timer *t);
void timer_restart(struct timer *t);
int timer_expired(struct timer *t);
#endif /* __TIMER_H__ */
/** @} */

532
android/uip/uip/uip-fw.c Normal file
View File

@ -0,0 +1,532 @@
/*
* Copyright (c) 2004, 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: uip-fw.c,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
/**
* \addtogroup uip
* @{
*/
/**
* \defgroup uipfw uIP packet forwarding
* @{
*
*/
/**
* \file
* uIP packet forwarding.
* \author Adam Dunkels <adam@sics.se>
*
* This file implements a number of simple functions which do packet
* forwarding over multiple network interfaces with uIP.
*
*/
#include "uip.h"
#include "uip_arch.h"
#include "uip-fw.h"
#include <string.h> /* for memcpy() */
/*
* The list of registered network interfaces.
*/
static struct uip_fw_netif *netifs = NULL;
/*
* A pointer to the default network interface.
*/
static struct uip_fw_netif *defaultnetif = NULL;
struct tcpip_hdr {
/* IP header. */
u8_t vhl,
tos;
u16_t len,
ipid,
ipoffset;
u8_t 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;
u8_t urgp[2];
u8_t optdata[4];
};
struct icmpip_hdr {
/* IP header. */
u8_t vhl,
tos,
len[2],
ipid[2],
ipoffset[2],
ttl,
proto;
u16_t ipchksum;
u16_t srcipaddr[2],
destipaddr[2];
/* ICMP (echo) header. */
u8_t type, icode;
u16_t icmpchksum;
u16_t id, seqno;
u8_t payload[1];
};
/* ICMP ECHO. */
#define ICMP_ECHO 8
/* ICMP TIME-EXCEEDED. */
#define ICMP_TE 11
/*
* Pointer to the TCP/IP headers of the packet in the uip_buf buffer.
*/
#define BUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
/*
* Pointer to the ICMP/IP headers of the packet in the uip_buf buffer.
*/
#define ICMPBUF ((struct icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
/*
* Certain fields of an IP packet that are used for identifying
* duplicate packets.
*/
struct fwcache_entry {
u16_t timer;
u16_t srcipaddr[2];
u16_t destipaddr[2];
u16_t ipid;
u8_t proto;
u8_t unused;
#if notdef
u16_t payload[2];
#endif
#if UIP_REASSEMBLY > 0
u16_t len, offset;
#endif
};
/*
* The number of packets to remember when looking for duplicates.
*/
#ifdef UIP_CONF_FWCACHE_SIZE
#define FWCACHE_SIZE UIP_CONF_FWCACHE_SIZE
#else
#define FWCACHE_SIZE 2
#endif
/*
* A cache of packet header fields which are used for
* identifying duplicate packets.
*/
static struct fwcache_entry fwcache[FWCACHE_SIZE];
/**
* \internal
* The time that a packet cache is active.
*/
#define FW_TIME 20
/*------------------------------------------------------------------------------*/
/**
* Initialize the uIP packet forwarding module.
*/
/*------------------------------------------------------------------------------*/
void
uip_fw_init(void)
{
struct uip_fw_netif *t;
defaultnetif = NULL;
while(netifs != NULL) {
t = netifs;
netifs = netifs->next;
t->next = NULL;
}
}
/*------------------------------------------------------------------------------*/
/**
* \internal
* Check if an IP address is within the network defined by an IP
* address and a netmask.
*
* \param ipaddr The IP address to be checked.
* \param netipaddr The IP address of the network.
* \param netmask The netmask of the network.
*
* \return Non-zero if IP address is in network, zero otherwise.
*/
/*------------------------------------------------------------------------------*/
static unsigned char
ipaddr_maskcmp(u16_t *ipaddr, u16_t *netipaddr, u16_t *netmask)
{
return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) &&
(ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]);
}
/*------------------------------------------------------------------------------*/
/**
* \internal
* Send out an ICMP TIME-EXCEEDED message.
*
* This function replaces the packet in the uip_buf buffer with the
* ICMP packet.
*/
/*------------------------------------------------------------------------------*/
static void
time_exceeded(void)
{
u16_t tmp16;
/* We don't send out ICMP errors for ICMP messages. */
if(ICMPBUF->proto == UIP_PROTO_ICMP) {
uip_len = 0;
return;
}
/* Copy fields from packet header into payload of this ICMP packet. */
memcpy(&(ICMPBUF->payload[0]), ICMPBUF, 28);
/* Set the ICMP type and code. */
ICMPBUF->type = ICMP_TE;
ICMPBUF->icode = 0;
/* Calculate the ICMP checksum. */
ICMPBUF->icmpchksum = 0;
ICMPBUF->icmpchksum = ~uip_chksum((u16_t *)&(ICMPBUF->type), 36);
/* Set the IP destination address to be the source address of the
original packet. */
tmp16= BUF->destipaddr[0];
BUF->destipaddr[0] = BUF->srcipaddr[0];
BUF->srcipaddr[0] = tmp16;
tmp16 = BUF->destipaddr[1];
BUF->destipaddr[1] = BUF->srcipaddr[1];
BUF->srcipaddr[1] = tmp16;
/* Set our IP address as the source address. */
BUF->srcipaddr[0] = uip_hostaddr[0];
BUF->srcipaddr[1] = uip_hostaddr[1];
/* The size of the ICMP time exceeded packet is 36 + the size of the
IP header (20) = 56. */
uip_len = 56;
ICMPBUF->len[0] = 0;
ICMPBUF->len[1] = uip_len;
/* Fill in the other fields in the IP header. */
ICMPBUF->vhl = 0x45;
ICMPBUF->tos = 0;
ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0;
ICMPBUF->ttl = UIP_TTL;
ICMPBUF->proto = UIP_PROTO_ICMP;
/* Calculate IP checksum. */
ICMPBUF->ipchksum = 0;
ICMPBUF->ipchksum = ~(uip_ipchksum());
}
/*------------------------------------------------------------------------------*/
/**
* \internal
* Register a packet in the forwarding cache so that it won't be
* forwarded again.
*/
/*------------------------------------------------------------------------------*/
static void
fwcache_register(void)
{
struct fwcache_entry *fw;
int i, oldest;
oldest = FW_TIME;
fw = NULL;
/* Find the oldest entry in the cache. */
for(i = 0; i < FWCACHE_SIZE; ++i) {
if(fwcache[i].timer == 0) {
fw = &fwcache[i];
break;
} else if(fwcache[i].timer <= oldest) {
fw = &fwcache[i];
oldest = fwcache[i].timer;
}
}
fw->timer = FW_TIME;
fw->ipid = BUF->ipid;
fw->srcipaddr[0] = BUF->srcipaddr[0];
fw->srcipaddr[1] = BUF->srcipaddr[1];
fw->destipaddr[0] = BUF->destipaddr[0];
fw->destipaddr[1] = BUF->destipaddr[1];
fw->proto = BUF->proto;
#if notdef
fw->payload[0] = BUF->srcport;
fw->payload[1] = BUF->destport;
#endif
#if UIP_REASSEMBLY > 0
fw->len = BUF->len;
fw->offset = BUF->ipoffset;
#endif
}
/*------------------------------------------------------------------------------*/
/**
* \internal
* Find a network interface for the IP packet in uip_buf.
*/
/*------------------------------------------------------------------------------*/
static struct uip_fw_netif *
find_netif(void)
{
struct uip_fw_netif *netif;
/* Walk through every network interface to check for a match. */
for(netif = netifs; netif != NULL; netif = netif->next) {
if(ipaddr_maskcmp(BUF->destipaddr, netif->ipaddr,
netif->netmask)) {
/* If there was a match, we break the loop. */
return netif;
}
}
/* If no matching netif was found, we use default netif. */
return defaultnetif;
}
/*------------------------------------------------------------------------------*/
/**
* Output an IP packet on the correct network interface.
*
* The IP packet should be present in the uip_buf buffer and its
* length in the global uip_len variable.
*
* \retval UIP_FW_ZEROLEN Indicates that a zero-length packet
* transmission was attempted and that no packet was sent.
*
* \retval UIP_FW_NOROUTE No suitable network interface could be found
* for the outbound packet, and the packet was not sent.
*
* \return The return value from the actual network interface output
* function is passed unmodified as a return value.
*/
/*------------------------------------------------------------------------------*/
u8_t
uip_fw_output(void)
{
struct uip_fw_netif *netif;
if(uip_len == 0) {
return UIP_FW_ZEROLEN;
}
fwcache_register();
#if UIP_BROADCAST
/* Link local broadcasts go out on all interfaces. */
if(/*BUF->proto == UIP_PROTO_UDP &&*/
BUF->destipaddr[0] == 0xffff &&
BUF->destipaddr[1] == 0xffff) {
if(defaultnetif != NULL) {
defaultnetif->output();
}
for(netif = netifs; netif != NULL; netif = netif->next) {
netif->output();
}
return UIP_FW_OK;
}
#endif /* UIP_BROADCAST */
netif = find_netif();
/* printf("uip_fw_output: netif %p ->output %p len %d\n", netif,
netif->output,
uip_len);*/
if(netif == NULL) {
return UIP_FW_NOROUTE;
}
/* If we now have found a suitable network interface, we call its
output function to send out the packet. */
return netif->output();
}
/*------------------------------------------------------------------------------*/
/**
* Forward an IP packet in the uip_buf buffer.
*
*
*
* \return UIP_FW_FORWARDED if the packet was forwarded, UIP_FW_LOCAL if
* the packet should be processed locally.
*/
/*------------------------------------------------------------------------------*/
u8_t
uip_fw_forward(void)
{
struct fwcache_entry *fw;
/* First check if the packet is destined for ourselves and return 0
to indicate that the packet should be processed locally. */
if(BUF->destipaddr[0] == uip_hostaddr[0] &&
BUF->destipaddr[1] == uip_hostaddr[1]) {
return UIP_FW_LOCAL;
}
/* If we use ping IP address configuration, and our IP address is
not yet configured, we should intercept all ICMP echo packets. */
#if UIP_PINGADDRCONF
if((uip_hostaddr[0] | uip_hostaddr[1]) == 0 &&
BUF->proto == UIP_PROTO_ICMP &&
ICMPBUF->type == ICMP_ECHO) {
return UIP_FW_LOCAL;
}
#endif /* UIP_PINGADDRCONF */
/* Check if the packet is in the forwarding cache already, and if so
we drop it. */
for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
if(fw->timer != 0 &&
#if UIP_REASSEMBLY > 0
fw->len == BUF->len &&
fw->offset == BUF->ipoffset &&
#endif
fw->ipid == BUF->ipid &&
fw->srcipaddr[0] == BUF->srcipaddr[0] &&
fw->srcipaddr[1] == BUF->srcipaddr[1] &&
fw->destipaddr[0] == BUF->destipaddr[0] &&
fw->destipaddr[1] == BUF->destipaddr[1] &&
#if notdef
fw->payload[0] == BUF->srcport &&
fw->payload[1] == BUF->destport &&
#endif
fw->proto == BUF->proto) {
/* Drop packet. */
return UIP_FW_FORWARDED;
}
}
/* If the TTL reaches zero we produce an ICMP time exceeded message
in the uip_buf buffer and forward that packet back to the sender
of the packet. */
if(BUF->ttl <= 1) {
/* No time exceeded for broadcasts and multicasts! */
if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
return UIP_FW_LOCAL;
}
time_exceeded();
}
/* Decrement the TTL (time-to-live) value in the IP header */
BUF->ttl = BUF->ttl - 1;
/* Update the IP checksum. */
if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) {
BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1;
} else {
BUF->ipchksum = BUF->ipchksum + HTONS(0x0100);
}
if(uip_len > 0) {
uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
uip_fw_output();
}
#if UIP_BROADCAST
if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
return UIP_FW_LOCAL;
}
#endif /* UIP_BROADCAST */
/* Return non-zero to indicate that the packet was forwarded and that no
other processing should be made. */
return UIP_FW_FORWARDED;
}
/*------------------------------------------------------------------------------*/
/**
* Register a network interface with the forwarding module.
*
* \param netif A pointer to the network interface that is to be
* registered.
*/
/*------------------------------------------------------------------------------*/
void
uip_fw_register(struct uip_fw_netif *netif)
{
netif->next = netifs;
netifs = netif;
}
/*------------------------------------------------------------------------------*/
/**
* Register a default network interface.
*
* All packets that don't go out on any of the other interfaces will
* be routed to the default interface.
*
* \param netif A pointer to the network interface that is to be
* registered.
*/
/*------------------------------------------------------------------------------*/
void
uip_fw_default(struct uip_fw_netif *netif)
{
defaultnetif = netif;
}
/*------------------------------------------------------------------------------*/
/**
* Perform periodic processing.
*/
/*------------------------------------------------------------------------------*/
void
uip_fw_periodic(void)
{
struct fwcache_entry *fw;
for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
if(fw->timer > 0) {
--fw->timer;
}
}
}
/*------------------------------------------------------------------------------*/

176
android/uip/uip/uip-fw.h Normal file
View File

@ -0,0 +1,176 @@
/**
* \addtogroup uipfw
* @{
*/
/**
* \file
* uIP packet forwarding header file.
* \author Adam Dunkels <adam@sics.se>
*/
/*
* Copyright (c) 2004, 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: uip-fw.h,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
#ifndef __UIP_FW_H__
#define __UIP_FW_H__
#include "uip.h"
/**
* Representation of a uIP network interface.
*/
struct uip_fw_netif {
struct uip_fw_netif *next; /**< Pointer to the next interface when
linked in a list. */
u16_t ipaddr[2]; /**< The IP address of this interface. */
u16_t netmask[2]; /**< The netmask of the interface. */
u8_t (* output)(void);
/**< A pointer to the function that
sends a packet. */
};
/**
* Intantiating macro for a uIP network interface.
*
* Example:
\code
struct uip_fw_netif slipnetif =
{UIP_FW_NETIF(192,168,76,1, 255,255,255,0, slip_output)};
\endcode
* \param ip1,ip2,ip3,ip4 The IP address of the network interface.
*
* \param nm1,nm2,nm3,nm4 The netmask of the network interface.
*
* \param outputfunc A pointer to the output function of the network interface.
*
* \hideinitializer
*/
#define UIP_FW_NETIF(ip1,ip2,ip3,ip4, nm1,nm2,nm3,nm4, outputfunc) \
NULL, \
{HTONS((ip1 << 8) | ip2), HTONS((ip3 << 8) | ip4)}, \
{HTONS((nm1 << 8) | nm2), HTONS((nm3 << 8) | nm4)}, \
outputfunc
/**
* Set the IP address of a network interface.
*
* \param netif A pointer to the uip_fw_netif structure for the network interface.
*
* \param addr A pointer to an IP address.
*
* \hideinitializer
*/
#define uip_fw_setipaddr(netif, addr) \
do { (netif)->ipaddr[0] = ((u16_t *)(addr))[0]; \
(netif)->ipaddr[1] = ((u16_t *)(addr))[1]; } while(0)
/**
* Set the netmask of a network interface.
*
* \param netif A pointer to the uip_fw_netif structure for the network interface.
*
* \param addr A pointer to an IP address representing the netmask.
*
* \hideinitializer
*/
#define uip_fw_setnetmask(netif, addr) \
do { (netif)->netmask[0] = ((u16_t *)(addr))[0]; \
(netif)->netmask[1] = ((u16_t *)(addr))[1]; } while(0)
void uip_fw_init(void);
u8_t uip_fw_forward(void);
u8_t uip_fw_output(void);
void uip_fw_register(struct uip_fw_netif *netif);
void uip_fw_default(struct uip_fw_netif *netif);
void uip_fw_periodic(void);
/**
* A non-error message that indicates that a packet should be
* processed locally.
*
* \hideinitializer
*/
#define UIP_FW_LOCAL 0
/**
* A non-error message that indicates that something went OK.
*
* \hideinitializer
*/
#define UIP_FW_OK 0
/**
* A non-error message that indicates that a packet was forwarded.
*
* \hideinitializer
*/
#define UIP_FW_FORWARDED 1
/**
* A non-error message that indicates that a zero-length packet
* transmission was attempted, and that no packet was sent.
*
* \hideinitializer
*/
#define UIP_FW_ZEROLEN 2
/**
* An error message that indicates that a packet that was too large
* for the outbound network interface was detected.
*
* \hideinitializer
*/
#define UIP_FW_TOOLARGE 3
/**
* An error message that indicates that no suitable interface could be
* found for an outbound packet.
*
* \hideinitializer
*/
#define UIP_FW_NOROUTE 4
/**
* An error message that indicates that a packet that should be
* forwarded or output was dropped.
*
* \hideinitializer
*/
#define UIP_FW_DROPPED 5
#endif /* __UIP_FW_H__ */
/** @} */

View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 2006, 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.
*
* This file is part of the uIP TCP/IP stack
*
* $Id: uip-neighbor.c,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
/**
* \file
* Database of link-local neighbors, used by IPv6 code and
* to be used by a future ARP code rewrite.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "uip-neighbor.h"
#include <string.h>
#define MAX_TIME 128
#ifdef UIP_NEIGHBOR_CONF_ENTRIES
#define ENTRIES UIP_NEIGHBOR_CONF_ENTRIES
#else /* UIP_NEIGHBOR_CONF_ENTRIES */
#define ENTRIES 8
#endif /* UIP_NEIGHBOR_CONF_ENTRIES */
struct neighbor_entry {
uip_ipaddr_t ipaddr;
struct uip_neighbor_addr addr;
u8_t time;
};
static struct neighbor_entry entries[ENTRIES];
/*---------------------------------------------------------------------------*/
void
uip_neighbor_init(void)
{
int i;
for(i = 0; i < ENTRIES; ++i) {
entries[i].time = MAX_TIME;
}
}
/*---------------------------------------------------------------------------*/
void
uip_neighbor_periodic(void)
{
int i;
for(i = 0; i < ENTRIES; ++i) {
if(entries[i].time < MAX_TIME) {
entries[i].time++;
}
}
}
/*---------------------------------------------------------------------------*/
void
uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr)
{
int i, oldest;
u8_t oldest_time;
printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3],
addr->addr.addr[4], addr->addr.addr[5]);
/* Find the first unused entry or the oldest used entry. */
oldest_time = 0;
oldest = 0;
for(i = 0; i < ENTRIES; ++i) {
if(entries[i].time == MAX_TIME) {
oldest = i;
break;
}
if(uip_ipaddr_cmp(entries[i].ipaddr, addr)) {
oldest = i;
break;
}
if(entries[i].time > oldest_time) {
oldest = i;
oldest_time = entries[i].time;
}
}
/* Use the oldest or first free entry (either pointed to by the
"oldest" variable). */
entries[oldest].time = 0;
uip_ipaddr_copy(entries[oldest].ipaddr, ipaddr);
memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr));
}
/*---------------------------------------------------------------------------*/
static struct neighbor_entry *
find_entry(uip_ipaddr_t ipaddr)
{
int i;
for(i = 0; i < ENTRIES; ++i) {
if(uip_ipaddr_cmp(entries[i].ipaddr, ipaddr)) {
return &entries[i];
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
void
uip_neighbor_update(uip_ipaddr_t ipaddr)
{
struct neighbor_entry *e;
e = find_entry(ipaddr);
if(e != NULL) {
e->time = 0;
}
}
/*---------------------------------------------------------------------------*/
struct uip_neighbor_addr *
uip_neighbor_lookup(uip_ipaddr_t ipaddr)
{
struct neighbor_entry *e;
e = find_entry(ipaddr);
if(e != NULL) {
/* printf("Lookup neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
e->addr.addr.addr[0], e->addr.addr.addr[1], e->addr.addr.addr[2], e->addr.addr.addr[3],
e->addr.addr.addr[4], e->addr.addr.addr[5]);*/
return &e->addr;
}
return NULL;
}
/*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2006, 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.
*
* This file is part of the uIP TCP/IP stack
*
* $Id: uip-neighbor.h,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
/**
* \file
* Header file for database of link-local neighbors, used by
* IPv6 code and to be used by future ARP code.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __UIP_NEIGHBOR_H__
#define __UIP_NEIGHBOR_H__
#include "uip.h"
struct uip_neighbor_addr {
#if UIP_NEIGHBOR_CONF_ADDRTYPE
UIP_NEIGHBOR_CONF_ADDRTYPE addr;
#else
struct uip_eth_addr addr;
#endif
};
void uip_neighbor_init(void);
void uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr);
void uip_neighbor_update(uip_ipaddr_t ipaddr);
struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t ipaddr);
void uip_neighbor_periodic(void);
#endif /* __UIP-NEIGHBOR_H__ */

136
android/uip/uip/uip-split.c Normal file
View File

@ -0,0 +1,136 @@
/*
* Copyright (c) 2004, 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: uip-split.c,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
#include <string.h>
#include "uip-split.h"
#include "uip.h"
#include "uip-fw.h"
#include "uip_arch.h"
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
/*-----------------------------------------------------------------------------*/
void
uip_split_output(void)
{
u16_t tcplen, len1, len2;
/* We only try to split maximum sized TCP segments. */
if(BUF->proto == UIP_PROTO_TCP &&
uip_len == UIP_BUFSIZE - UIP_LLH_LEN) {
tcplen = uip_len - UIP_TCPIP_HLEN;
/* Split the segment in two. If the original packet length was
odd, we make the second packet one byte larger. */
len1 = len2 = tcplen / 2;
if(len1 + len2 < tcplen) {
++len2;
}
/* Create the first packet. This is done by altering the length
field of the IP header and updating the checksums. */
uip_len = len1 + UIP_TCPIP_HLEN;
#if UIP_CONF_IPV6
/* For IPv6, the IP length field does not include the IPv6 IP header
length. */
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* UIP_CONF_IPV6 */
BUF->len[0] = uip_len >> 8;
BUF->len[1] = uip_len & 0xff;
#endif /* UIP_CONF_IPV6 */
/* Recalculate the TCP checksum. */
BUF->tcpchksum = 0;
BUF->tcpchksum = ~(uip_tcpchksum());
#if !UIP_CONF_IPV6
/* Recalculate the IP checksum. */
BUF->ipchksum = 0;
BUF->ipchksum = ~(uip_ipchksum());
#endif /* UIP_CONF_IPV6 */
/* Transmit the first packet. */
/* uip_fw_output();*/
tcpip_output();
/* Now, create the second packet. To do this, it is not enough to
just alter the length field, but we must also update the TCP
sequence number and point the uip_appdata to a new place in
memory. This place is detemined by the length of the first
packet (len1). */
uip_len = len2 + UIP_TCPIP_HLEN;
#if UIP_CONF_IPV6
/* For IPv6, the IP length field does not include the IPv6 IP header
length. */
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* UIP_CONF_IPV6 */
BUF->len[0] = uip_len >> 8;
BUF->len[1] = uip_len & 0xff;
#endif /* UIP_CONF_IPV6 */
/* uip_appdata += len1;*/
memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2);
uip_add32(BUF->seqno, len1);
BUF->seqno[0] = uip_acc32[0];
BUF->seqno[1] = uip_acc32[1];
BUF->seqno[2] = uip_acc32[2];
BUF->seqno[3] = uip_acc32[3];
/* Recalculate the TCP checksum. */
BUF->tcpchksum = 0;
BUF->tcpchksum = ~(uip_tcpchksum());
#if !UIP_CONF_IPV6
/* Recalculate the IP checksum. */
BUF->ipchksum = 0;
BUF->ipchksum = ~(uip_ipchksum());
#endif /* UIP_CONF_IPV6 */
/* Transmit the second packet. */
/* uip_fw_output();*/
tcpip_output();
} else {
/* uip_fw_output();*/
tcpip_output();
}
}
/*-----------------------------------------------------------------------------*/

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2004, 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.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: uip-split.h,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
/**
* \addtogroup uip
* @{
*/
/**
* \defgroup uipsplit uIP TCP throughput booster hack
* @{
*
* The basic uIP TCP implementation only allows each TCP connection to
* have a single TCP segment in flight at any given time. Because of
* the delayed ACK algorithm employed by most TCP receivers, uIP's
* limit on the amount of in-flight TCP segments seriously reduces the
* maximum achievable throughput for sending data from uIP.
*
* The uip-split module is a hack which tries to remedy this
* situation. By splitting maximum sized outgoing TCP segments into
* two, the delayed ACK algorithm is not invoked at TCP
* receivers. This improves the throughput when sending data from uIP
* by orders of magnitude.
*
* The uip-split module uses the uip-fw module (uIP IP packet
* forwarding) for sending packets. Therefore, the uip-fw module must
* be set up with the appropriate network interfaces for this module
* to work.
*/
/**
* \file
* Module for splitting outbound TCP segments in two to avoid the
* delayed ACK throughput degradation.
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#ifndef __UIP_SPLIT_H__
#define __UIP_SPLIT_H__
/**
* Handle outgoing packets.
*
* This function inspects an outgoing packet in the uip_buf buffer and
* sends it out using the uip_fw_output() function. If the packet is a
* full-sized TCP segment it will be split into two segments and
* transmitted separately. This function should be called instead of
* the actual device driver output function, or the uip_fw_output()
* function.
*
* The headers of the outgoing packet is assumed to be in the uip_buf
* buffer and the payload is assumed to be wherever uip_appdata
* points. The length of the outgoing packet is assumed to be in the
* uip_len variable.
*
*/
void uip_split_output(void);
#endif /* __UIP_SPLIT_H__ */
/** @} */
/** @} */

1897
android/uip/uip/uip.c Normal file

File diff suppressed because it is too large Load Diff

1603
android/uip/uip/uip.h Normal file

File diff suppressed because it is too large Load Diff

138
android/uip/uip/uip_arch.h Normal file
View File

@ -0,0 +1,138 @@
/**
* \addtogroup uip
* {@
*/
/**
* \defgroup uiparch Architecture specific uIP functions
* @{
*
* The functions in the architecture specific module implement the IP
* check sum and 32-bit additions.
*
* The IP checksum calculation is the most computationally expensive
* operation in the TCP/IP stack and it therefore pays off to
* implement this in efficient assembler. The purpose of the uip-arch
* module is to let the checksum functions to be implemented in
* architecture specific assembler.
*
*/
/**
* \file
* Declarations of architecture specific functions.
* \author Adam Dunkels <adam@dunkels.com>
*/
/*
* 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. 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 2006/06/07 09:15:19 adam Exp $
*
*/
#ifndef __UIP_ARCH_H__
#define __UIP_ARCH_H__
#include "uip.h"
/**
* Carry out a 32-bit addition.
*
* Because not all architectures for which uIP is intended has native
* 32-bit arithmetic, uIP uses an external C function for doing the
* required 32-bit additions in the TCP protocol processing. This
* function should add the two arguments and place the result in the
* global variable uip_acc32.
*
* \note The 32-bit integer pointed to by the op32 parameter and the
* result in the uip_acc32 variable are in network byte order (big
* endian).
*
* \param op32 A pointer to a 4-byte array representing a 32-bit
* integer in network byte order (big endian).
*
* \param op16 A 16-bit integer in host byte order.
*/
void uip_add32(u8_t *op32, u16_t op16);
/**
* Calculate the Internet checksum over a buffer.
*
* The Internet checksum is the one's complement of the one's
* complement sum of all 16-bit words in the buffer.
*
* See RFC1071.
*
* \note This function is not called in the current version of uIP,
* but future versions might make use of it.
*
* \param buf A pointer to the buffer over which the checksum is to be
* computed.
*
* \param len The length of the buffer over which the checksum is to
* be computed.
*
* \return The Internet checksum of the buffer.
*/
u16_t uip_chksum(u16_t *buf, u16_t len);
/**
* Calculate the IP header checksum of the packet header in uip_buf.
*
* The IP header checksum is the Internet checksum of the 20 bytes of
* the IP header.
*
* \return The IP header checksum of the IP header in the uip_buf
* buffer.
*/
u16_t uip_ipchksum(void);
/**
* Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
*
* The TCP checksum is the Internet checksum of data contents of the
* TCP segment, and a pseudo-header as defined in RFC793.
*
* \note The uip_appdata pointer that points to the packet data may
* point anywhere in memory, so it is not possible to simply calculate
* the Internet checksum of the contents of the uip_buf buffer.
*
* \return The TCP checksum of the TCP segment in uip_buf and pointed
* to by uip_appdata.
*/
u16_t uip_tcpchksum(void);
u16_t uip_udpchksum(void);
/** @} */
/** @} */
#endif /* __UIP_ARCH_H__ */

423
android/uip/uip/uip_arp.c Normal file
View File

@ -0,0 +1,423 @@
/**
* \addtogroup uip
* @{
*/
/**
* \defgroup uiparp uIP Address Resolution Protocol
* @{
*
* The Address Resolution Protocol ARP is used for mapping between IP
* addresses and link level addresses such as the Ethernet MAC
* addresses. ARP uses broadcast queries to ask for the link level
* address of a known IP address and the host which is configured with
* the IP address for which the query was meant, will respond with its
* link level address.
*
* \note This ARP implementation only supports Ethernet.
*/
/**
* \file
* Implementation of the ARP Address Resolution Protocol.
* \author Adam Dunkels <adam@dunkels.com>
*
*/
/*
* Copyright (c) 2001-2003, 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. 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.8 2006/06/02 23:36:21 adam Exp $
*
*/
#include "uip_arp.h"
#include <string.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 broadcast_ethaddr =
{{0xff,0xff,0xff,0xff,0xff,0xff}};
static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff};
static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
static u16_t ipaddr[2];
static u8_t i, c;
static u8_t arptime;
static u8_t tmpage;
#define BUF ((struct arp_hdr *)&uip_buf[0])
#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
/*-----------------------------------------------------------------------------------*/
/**
* Initialize the ARP module.
*
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_init(void)
{
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
memset(arp_table[i].ipaddr, 0, 4);
}
}
/*-----------------------------------------------------------------------------------*/
/**
* Periodic ARP processing function.
*
* This function performs periodic timer processing in the ARP module
* and should be called at regular intervals. The recommended interval
* is 10 seconds between the calls.
*
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_timer(void)
{
struct arp_entry *tabptr;
++arptime;
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
arptime - tabptr->time >= UIP_ARP_MAXAGE) {
memset(tabptr->ipaddr, 0, 4);
}
}
}
/*-----------------------------------------------------------------------------------*/
static void
uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
{
register struct arp_entry *tabptr;
/* 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) {
tabptr = &arp_table[i];
/* Only check those entries that are actually in use. */
if(tabptr->ipaddr[0] != 0 &&
tabptr->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] == tabptr->ipaddr[0] &&
ipaddr[1] == tabptr->ipaddr[1]) {
/* An old entry found, update this and return. */
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
tabptr->time = arptime;
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) {
tabptr = &arp_table[i];
if(tabptr->ipaddr[0] == 0 &&
tabptr->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) {
tabptr = &arp_table[i];
if(arptime - tabptr->time > tmpage) {
tmpage = arptime - tabptr->time;
c = i;
}
}
i = c;
tabptr = &arp_table[i];
}
/* Now, i is the ARP table entry which we will fill with the new
information. */
memcpy(tabptr->ipaddr, ipaddr, 4);
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
tabptr->time = arptime;
}
/*-----------------------------------------------------------------------------------*/
/**
* ARP processing for incoming IP packets
*
* This function should be called by the device driver when an IP
* packet has been received. The function will check if the address is
* in the ARP cache, and if so the ARP cache entry will be
* refreshed. If no ARP cache entry was found, a new one is created.
*
* This function expects an IP packet with a prepended Ethernet header
* in the uip_buf[] buffer, and the length of the packet in the global
* variable uip_len.
*/
/*-----------------------------------------------------------------------------------*/
#if 0
void
uip_arp_ipin(void)
{
uip_len -= sizeof(struct uip_eth_hdr);
/* 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] & uip_netmask[0]) !=
(uip_hostaddr[0] & uip_netmask[0])) {
return;
}
if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
(uip_hostaddr[1] & uip_netmask[1])) {
return;
}
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
return;
}
#endif /* 0 */
/*-----------------------------------------------------------------------------------*/
/**
* ARP processing for incoming ARP packets.
*
* This function should be called by the device driver when an ARP
* packet has been received. The function will act differently
* depending on the ARP packet type: if it is a reply for a request
* that we previously sent out, the ARP cache will be filled in with
* the values from the ARP reply. If the incoming ARP packet is an ARP
* request for our IP address, an ARP reply packet is created and put
* into the uip_buf[] buffer.
*
* When the function returns, the value of the global variable uip_len
* indicates whether the device driver should send out a packet or
* not. If uip_len is zero, no packet should be sent. If uip_len is
* non-zero, it contains the length of the outbound packet that is
* present in the uip_buf[] buffer.
*
* This function expects an ARP packet with a prepended Ethernet
* header in the uip_buf[] buffer, and the length of the packet in the
* global variable uip_len.
*/
/*-----------------------------------------------------------------------------------*/
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(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
/* First, we register the one who made the request in our ARP
table, since it is likely that we will do more communication
with this host in the future. */
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
/* The reply opcode is 2. */
BUF->opcode = HTONS(2);
memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
BUF->dipaddr[0] = BUF->sipaddr[0];
BUF->dipaddr[1] = BUF->sipaddr[1];
BUF->sipaddr[0] = uip_hostaddr[0];
BUF->sipaddr[1] = uip_hostaddr[1];
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(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
}
break;
}
return;
}
/*-----------------------------------------------------------------------------------*/
/**
* Prepend Ethernet header to an outbound IP packet and see if we need
* to send out an ARP request.
*
* This function should be called before sending out an IP packet. The
* function checks the destination IP address of the IP packet to see
* what Ethernet MAC address that should be used as a destination MAC
* address on the Ethernet.
*
* If the destination IP address is in the local network (determined
* by logical ANDing of netmask and our IP address), the function
* checks the ARP cache to see if an entry for the destination IP
* address is found. If so, an Ethernet header is prepended and the
* function returns. If no ARP cache entry is found for the
* destination IP address, the packet in the uip_buf[] is replaced by
* an ARP request packet for the IP address. The IP packet is dropped
* and it is assumed that they higher level protocols (e.g., TCP)
* eventually will retransmit the dropped packet.
*
* If the destination IP address is not on the local network, the IP
* address of the default router is used instead.
*
* When the function returns, a packet is present in the uip_buf[]
* buffer, and the length of the packet is in the global variable
* uip_len.
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_out(void)
{
struct arp_entry *tabptr;
/* 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. */
/* First check if destination is a local broadcast. */
if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) {
memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
} else {
/* Check if the destination address is on the local network. */
if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
/* 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. */
uip_ipaddr_copy(ipaddr, uip_draddr);
} else {
/* Else, we use the destination IP address. */
uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
}
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
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. */
memset(BUF->ethhdr.dest.addr, 0xff, 6);
memset(BUF->dhwaddr.addr, 0x00, 6);
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
uip_ipaddr_copy(BUF->dipaddr, ipaddr);
uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
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[UIP_TCPIP_HLEN + UIP_LLH_LEN];
uip_len = sizeof(struct arp_hdr);
return;
}
/* Build an ethernet header. */
memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
}
memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
uip_len += sizeof(struct uip_eth_hdr);
}
/*-----------------------------------------------------------------------------------*/
/** @} */
/** @} */

144
android/uip/uip/uip_arp.h Normal file
View File

@ -0,0 +1,144 @@
/**
* \addtogroup uip
* @{
*/
/**
* \addtogroup uiparp
* @{
*/
/**
* \file
* Macros and definitions for the ARP module.
* \author Adam Dunkels <adam@dunkels.com>
*/
/*
* Copyright (c) 2001-2003, 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. 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.5 2006/06/11 21:46:39 adam Exp $
*
*/
#ifndef __UIP_ARP_H__
#define __UIP_ARP_H__
#include "uip.h"
extern struct uip_eth_addr uip_ethaddr;
/**
* The Ethernet header.
*/
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
#define UIP_ETHTYPE_IP6 0x86dd
/* 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);*/
#define uip_arp_ipin()
/* 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);
/** @} */
/**
* \addtogroup uipconffunc
* @{
*/
/**
* Specifiy the Ethernet MAC address.
*
* The ARP code needs to know the MAC address of the Ethernet card in
* order to be able to respond to ARP queries and to generate working
* Ethernet headers.
*
* \note This macro only specifies the Ethernet MAC address to the ARP
* code. It cannot be used to change the MAC address of the Ethernet
* card.
*
* \param eaddr A pointer to a struct uip_eth_addr containing the
* Ethernet MAC address of the Ethernet card.
*
* \hideinitializer
*/
#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \
uip_ethaddr.addr[1] = eaddr.addr[1];\
uip_ethaddr.addr[2] = eaddr.addr[2];\
uip_ethaddr.addr[3] = eaddr.addr[3];\
uip_ethaddr.addr[4] = eaddr.addr[4];\
uip_ethaddr.addr[5] = eaddr.addr[5];} while(0)
/** @} */
/** @} */
#endif /* __UIP_ARP_H__ */

74
android/uip/uip/uiplib.c Normal file
View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2004, Adam Dunkels and the 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. 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: uiplib.c,v 1.2 2006/06/12 08:00:31 adam Exp $
*
*/
#include "uip.h"
#include "uiplib.h"
/*-----------------------------------------------------------------------------------*/
unsigned char
uiplib_ipaddrconv(char *addrstr, unsigned char *ipaddr)
{
unsigned char tmp;
char c;
unsigned char i, j;
tmp = 0;
for(i = 0; i < 4; ++i) {
j = 0;
do {
c = *addrstr;
++j;
if(j > 4) {
return 0;
}
if(c == '.' || c == 0) {
*ipaddr = tmp;
++ipaddr;
tmp = 0;
} else if(c >= '0' && c <= '9') {
tmp = (tmp * 10) + (c - '0');
} else {
return 0;
}
++addrstr;
} while(c != '.' && c != 0);
}
return 1;
}
/*-----------------------------------------------------------------------------------*/

71
android/uip/uip/uiplib.h Normal file
View File

@ -0,0 +1,71 @@
/**
* \file
* Various uIP library functions.
* \author
* Adam Dunkels <adam@sics.se>
*
*/
/*
* Copyright (c) 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. 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: uiplib.h,v 1.1 2006/06/07 09:15:19 adam Exp $
*
*/
#ifndef __UIPLIB_H__
#define __UIPLIB_H__
/**
* \addtogroup uipconvfunc
* @{
*/
/**
* Convert a textual representation of an IP address to a numerical representation.
*
* This function takes a textual representation of an IP address in
* the form a.b.c.d and converts it into a 4-byte array that can be
* used by other uIP functions.
*
* \param addrstr A pointer to a string containing the IP address in
* textual form.
*
* \param addr A pointer to a 4-byte array that will be filled in with
* the numerical representation of the address.
*
* \retval 0 If the IP address could not be parsed.
* \retval Non-zero If the IP address was parsed.
*/
unsigned char uiplib_ipaddrconv(char *addrstr, unsigned char *addr);
/** @} */
#endif /* __UIPLIB_H__ */

541
android/uip/uip/uipopt.h Normal file
View File

@ -0,0 +1,541 @@
/**
* \defgroup uipopt Configuration options for uIP
* @{
*
* uIP is configured using the per-project configuration file
* uipopt.h. This file contains all compile-time options for uIP and
* should be tweaked to match each specific project. The uIP
* distribution contains a documented example "uipopt.h" that can be
* copied and modified for each project.
*
* \note Most of the configuration options in the uipopt.h should not
* be changed, but rather the per-project uip-conf.h file.
*/
/**
* \file
* Configuration options for uIP.
* \author Adam Dunkels <adam@dunkels.com>
*
* 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.
*/
/*
* Copyright (c) 2001-2003, 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. 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.4 2006/06/12 08:00:31 adam Exp $
*
*/
#ifndef __UIPOPT_H__
#define __UIPOPT_H__
#ifndef UIP_LITTLE_ENDIAN
#define UIP_LITTLE_ENDIAN 3412
#endif /* UIP_LITTLE_ENDIAN */
#ifndef UIP_BIG_ENDIAN
#define UIP_BIG_ENDIAN 1234
#endif /* UIP_BIG_ENDIAN */
#include "uip-conf.h"
/*------------------------------------------------------------------------------*/
/**
* \name Static configuration options
* @{
*
* These configuration options can be used for setting the IP address
* settings statically, but only if UIP_FIXEDADDR is set to 1. The
* configuration options for a specific node 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.
*/
/**
* Determines if uIP should use a fixed IP address or not.
*
* If uIP should use a fixed IP address, the settings are set in the
* uipopt.h file. If not, the macros uip_sethostaddr(),
* uip_setdraddr() and uip_setnetmask() should be used instead.
*
* \hideinitializer
*/
#define UIP_FIXEDADDR 0
/**
* Ping IP address asignment.
*
* uIP uses a "ping" packets for setting its own IP address if this
* option is set. If so, uIP will start with an empty IP address and
* the destination IP address of the first incoming "ping" (ICMP echo)
* packet will be used for setting the hosts IP address.
*
* \note This works only if UIP_FIXEDADDR is 0.
*
* \hideinitializer
*/
#ifdef UIP_CONF_PINGADDRCONF
#define UIP_PINGADDRCONF UIP_CONF_PINGADDRCONF
#else /* UIP_CONF_PINGADDRCONF */
#define UIP_PINGADDRCONF 0
#endif /* UIP_CONF_PINGADDRCONF */
/**
* Specifies if the uIP ARP module should be compiled with a fixed
* Ethernet MAC address or not.
*
* If this configuration option is 0, the macro uip_setethaddr() can
* be used to specify the Ethernet address at run-time.
*
* \hideinitializer
*/
#define UIP_FIXEDETHADDR 0
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name IP configuration options
* @{
*
*/
/**
* The IP TTL (time to live) of IP packets sent by uIP.
*
* This should normally not be changed.
*/
#define UIP_TTL 64
/**
* Turn on support for IP packet reassembly.
*
* uIP supports reassembly of fragmented IP packets. This features
* requires an additonal amount of RAM to hold the reassembly buffer
* and the reassembly code size is approximately 700 bytes. The
* reassembly buffer is of the same size as the uip_buf buffer
* (configured by UIP_BUFSIZE).
*
* \note IP packet reassembly is not heavily tested.
*
* \hideinitializer
*/
#define UIP_REASSEMBLY 0
/**
* The maximum time an IP fragment should wait in the reassembly
* buffer before it is dropped.
*
*/
#define UIP_REASS_MAXAGE 40
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name UDP configuration options
* @{
*/
/**
* Toggles wether UDP support should be compiled in or not.
*
* \hideinitializer
*/
#ifdef UIP_CONF_UDP
#define UIP_UDP UIP_CONF_UDP
#else /* UIP_CONF_UDP */
#define UIP_UDP 0
#endif /* UIP_CONF_UDP */
/**
* Toggles if UDP checksums should be used or not.
*
* \note Support for UDP checksums is currently not included in uIP,
* so this option has no function.
*
* \hideinitializer
*/
#ifdef UIP_CONF_UDP_CHECKSUMS
#define UIP_UDP_CHECKSUMS UIP_CONF_UDP_CHECKSUMS
#else
#define UIP_UDP_CHECKSUMS 0
#endif
/**
* The maximum amount of concurrent UDP connections.
*
* \hideinitializer
*/
#ifdef UIP_CONF_UDP_CONNS
#define UIP_UDP_CONNS UIP_CONF_UDP_CONNS
#else /* UIP_CONF_UDP_CONNS */
#define UIP_UDP_CONNS 10
#endif /* UIP_CONF_UDP_CONNS */
/**
* The name of the function that should be called when UDP datagrams arrive.
*
* \hideinitializer
*/
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name TCP configuration options
* @{
*/
/**
* Determines if support for opening connections from uIP should be
* compiled in.
*
* If the applications that are running on top of uIP for this project
* do not need to open outgoing TCP connections, this configration
* option can be turned off to reduce the code size of uIP.
*
* \hideinitializer
*/
#define UIP_ACTIVE_OPEN 1
/**
* The maximum number of simultaneously open TCP connections.
*
* Since the TCP connections are statically allocated, turning this
* configuration knob down results in less RAM used. Each TCP
* connection requires approximatly 30 bytes of memory.
*
* \hideinitializer
*/
#ifndef UIP_CONF_MAX_CONNECTIONS
#define UIP_CONNS 10
#else /* UIP_CONF_MAX_CONNECTIONS */
#define UIP_CONNS UIP_CONF_MAX_CONNECTIONS
#endif /* UIP_CONF_MAX_CONNECTIONS */
/**
* The maximum number of simultaneously listening TCP ports.
*
* Each listening TCP port requires 2 bytes of memory.
*
* \hideinitializer
*/
#ifndef UIP_CONF_MAX_LISTENPORTS
#define UIP_LISTENPORTS 20
#else /* UIP_CONF_MAX_LISTENPORTS */
#define UIP_LISTENPORTS UIP_CONF_MAX_LISTENPORTS
#endif /* UIP_CONF_MAX_LISTENPORTS */
/**
* Determines if support for TCP urgent data notification should be
* compiled in.
*
* Urgent data (out-of-band data) is a rarely used TCP feature that
* very seldom would be required.
*
* \hideinitializer
*/
#define UIP_URGDATA 0
/**
* The initial retransmission timeout counted in timer pulses.
*
* This should not be changed.
*/
#define UIP_RTO 3
/**
* The maximum number of times a segment should be retransmitted
* before the connection should be aborted.
*
* This should not be changed.
*/
#define UIP_MAXRTX 8
/**
* The maximum number of times a SYN segment should be retransmitted
* before a connection request should be deemed to have been
* unsuccessful.
*
* This should not need to be changed.
*/
#define UIP_MAXSYNRTX 5
/**
* The TCP maximum segment size.
*
* This is should not be to set to more than
* UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN.
*/
#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
/**
* The size of the advertised receiver's window.
*
* Should be set low (i.e., to the size of the uip_buf buffer) is the
* application is slow to process incoming data, or high (32768 bytes)
* if the application processes data quickly.
*
* \hideinitializer
*/
#ifndef UIP_CONF_RECEIVE_WINDOW
#define UIP_RECEIVE_WINDOW UIP_TCP_MSS
#else
#define UIP_RECEIVE_WINDOW UIP_CONF_RECEIVE_WINDOW
#endif
/**
* How long a connection should stay in the TIME_WAIT state.
*
* This configiration option has no real implication, and it should be
* left untouched.
*/
#define UIP_TIME_WAIT_TIMEOUT 120
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name ARP configuration options
* @{
*/
/**
* The size of the ARP table.
*
* This option should be set to a larger value if this uIP node will
* have many connections from the local network.
*
* \hideinitializer
*/
#ifdef UIP_CONF_ARPTAB_SIZE
#define UIP_ARPTAB_SIZE UIP_CONF_ARPTAB_SIZE
#else
#define UIP_ARPTAB_SIZE 8
#endif
/**
* 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
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name General configuration options
* @{
*/
/**
* The size of the uIP packet buffer.
*
* The uIP packet buffer should not be smaller than 60 bytes, and does
* not need to be larger than 1500 bytes. Lower size results in lower
* TCP throughput, larger size results in higher TCP throughput.
*
* \hideinitializer
*/
#ifndef UIP_CONF_BUFFER_SIZE
#define UIP_BUFSIZE 400
#else /* UIP_CONF_BUFFER_SIZE */
#define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE
#endif /* UIP_CONF_BUFFER_SIZE */
/**
* Determines if statistics support should be compiled in.
*
* The statistics is useful for debugging and to show the user.
*
* \hideinitializer
*/
#ifndef UIP_CONF_STATISTICS
#define UIP_STATISTICS 0
#else /* UIP_CONF_STATISTICS */
#define UIP_STATISTICS UIP_CONF_STATISTICS
#endif /* UIP_CONF_STATISTICS */
/**
* Determines if logging of certain events should be compiled in.
*
* This is useful mostly for debugging. The function uip_log()
* must be implemented to suit the architecture of the project, if
* logging is turned on.
*
* \hideinitializer
*/
#ifndef UIP_CONF_LOGGING
#define UIP_LOGGING 0
#else /* UIP_CONF_LOGGING */
#define UIP_LOGGING UIP_CONF_LOGGING
#endif /* UIP_CONF_LOGGING */
/**
* Broadcast support.
*
* This flag configures IP broadcast support. This is useful only
* together with UDP.
*
* \hideinitializer
*
*/
#ifndef UIP_CONF_BROADCAST
#define UIP_BROADCAST 0
#else /* UIP_CONF_BROADCAST */
#define UIP_BROADCAST UIP_CONF_BROADCAST
#endif /* UIP_CONF_BROADCAST */
/**
* Print out a uIP log message.
*
* This function must be implemented by the module that uses uIP, and
* is called by uIP whenever a log message is generated.
*/
void uip_log(char *msg);
/**
* 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.
*
* \hideinitializer
*/
#ifdef UIP_CONF_LLH_LEN
#define UIP_LLH_LEN UIP_CONF_LLH_LEN
#else /* UIP_CONF_LLH_LEN */
#define UIP_LLH_LEN 14
#endif /* UIP_CONF_LLH_LEN */
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name CPU architecture configuration
* @{
*
* The CPU architecture configuration is where the endianess of the
* CPU on which uIP is to be run is specified. Most CPUs today are
* little endian, and the most notable exception are the Motorolas
* which are big endian. The BYTE_ORDER macro should be changed to
* reflect the CPU architecture on which uIP is to be run.
*/
/**
* The byte order of the CPU architecture on which uIP is to be run.
*
* This option can be either BIG_ENDIAN (Motorola byte order) or
* LITTLE_ENDIAN (Intel byte order).
*
* \hideinitializer
*/
#if 0
#ifdef UIP_CONF_BYTE_ORDER
#define UIP_BYTE_ORDER UIP_CONF_BYTE_ORDER
#else /* UIP_CONF_BYTE_ORDER */
#define UIP_BYTE_ORDER UIP_LITTLE_ENDIAN
#endif /* UIP_CONF_BYTE_ORDER */
#endif
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name Appication specific configurations
* @{
*
* An uIP application is implemented using a single application
* function that is called by uIP whenever a TCP/IP event occurs. The
* name of this function must be registered with uIP at compile time
* using the UIP_APPCALL definition.
*
* uIP applications can store the application state within the
* uip_conn structure by specifying the type of the application
* structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t.
*
* The file containing the definitions must be included in the
* uipopt.h file.
*
* The following example illustrates how this can look.
\code
void httpd_appcall(void);
#define UIP_APPCALL httpd_appcall
struct httpd_state {
u8_t state;
u16_t count;
char *dataptr;
char *script;
};
typedef struct httpd_state uip_tcp_appstate_t
\endcode
*/
/**
* \var #define UIP_APPCALL
*
* The name of the application function that uIP should call in
* response to TCP/IP events.
*
*/
/**
* \var typedef uip_tcp_appstate_t
*
* The type of the application state that is to be stored in the
* uip_conn structure. This usually is typedef:ed to a struct holding
* application state information.
*/
/**
* \var typedef uip_udp_appstate_t
*
* The type of the application state that is to be stored in the
* uip_conn structure. This usually is typedef:ed to a struct holding
* application state information.
*/
/** @} */
/** @} */
#endif /* __UIPOPT_H__ */

44
android/uip/unix/Makefile Normal file
View File

@ -0,0 +1,44 @@
# 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. 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.13 2006/06/11 21:55:03 adam Exp $
#
all: uip
CC = gcc
AR = ar
APPS = webserver
CFLAGS = -Wall -g -I../uip -I. -fpack-struct -Os
-include ../uip/Makefile.include
uip: $(addprefix $(OBJECTDIR)/, main.o tapdev.o clock-arch.o) apps.a uip.a
clean:
rm -fr *.o *~ *core uip $(OBJECTDIR) *.a

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2006, 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.
*
* This file is part of the uIP TCP/IP stack
*
* $Id: clock-arch.c,v 1.2 2006/06/12 08:00:31 adam Exp $
*/
/**
* \file
* Implementation of architecture-specific clock functionality
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "clock-arch.h"
#include <sys/time.h>
/*---------------------------------------------------------------------------*/
clock_time_t
clock_time(void)
{
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
/*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2006, 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.
*
* This file is part of the uIP TCP/IP stack
*
* $Id: clock-arch.h,v 1.2 2006/06/12 08:00:31 adam Exp $
*/
#ifndef __CLOCK_ARCH_H__
#define __CLOCK_ARCH_H__
typedef int clock_time_t;
#define CLOCK_CONF_SECOND 1000
#endif /* __CLOCK_ARCH_H__ */

218
android/uip/unix/main.c Normal file
View File

@ -0,0 +1,218 @@
/*
* 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.16 2006/06/11 21:55:03 adam Exp $
*
*/
#include "uip.h"
#include "uip_arp.h"
#include "tapdev.h"
#include "timer.h"
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
#ifndef NULL
#define NULL (void *)0
#endif /* NULL */
/*---------------------------------------------------------------------------*/
int
main(void)
{
int i;
uip_ipaddr_t ipaddr;
struct timer periodic_timer, arp_timer;
timer_set(&periodic_timer, CLOCK_SECOND / 2);
timer_set(&arp_timer, CLOCK_SECOND * 10);
tapdev_init();
uip_init();
uip_ipaddr(ipaddr, 192,168,0,2);
uip_sethostaddr(ipaddr);
uip_ipaddr(ipaddr, 192,168,0,1);
uip_setdraddr(ipaddr);
uip_ipaddr(ipaddr, 255,255,255,0);
uip_setnetmask(ipaddr);
httpd_init();
/* telnetd_init();*/
/* hello_world_init();*/
/* {
u8_t mac[6] = {1,2,3,4,5,6};
dhcpc_init(&mac, 6);
}*/
/*uip_ipaddr(ipaddr, 127,0,0,1);
smtp_configure("localhost", ipaddr);
SMTP_SEND("adam@sics.se", NULL, "uip-testing@example.com",
"Testing SMTP from uIP",
"Test message sent by uIP\r\n");*/
/*
webclient_init();
resolv_init();
uip_ipaddr(ipaddr, 195,54,122,204);
resolv_conf(ipaddr);
resolv_query("www.sics.se");*/
while(1) {
uip_len = tapdev_read();
if(uip_len > 0) {
if(BUF->type == htons(UIP_ETHTYPE_IP)) {
uip_arp_ipin();
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();
}
}
} else if(timer_expired(&periodic_timer)) {
timer_reset(&periodic_timer);
for(i = 0; i < UIP_CONNS; i++) {
uip_periodic(i);
/* 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();
}
}
#if UIP_UDP
for(i = 0; i < UIP_UDP_CONNS; i++) {
uip_udp_periodic(i);
/* 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();
}
}
#endif /* UIP_UDP */
/* Call the ARP timer function every 10 seconds. */
if(timer_expired(&arp_timer)) {
timer_reset(&arp_timer);
uip_arp_timer();
}
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
void
uip_log(char *m)
{
printf("uIP log message: %s\n", m);
}
void
resolv_found(char *name, u16_t *ipaddr)
{
u16_t *ipaddr2;
if(ipaddr == NULL) {
printf("Host '%s' not found.\n", name);
} else {
printf("Found name '%s' = %d.%d.%d.%d\n", name,
htons(ipaddr[0]) >> 8,
htons(ipaddr[0]) & 0xff,
htons(ipaddr[1]) >> 8,
htons(ipaddr[1]) & 0xff);
/* webclient_get("www.sics.se", 80, "/~adam/uip");*/
}
}
#ifdef __DHCPC_H__
void
dhcpc_configured(const struct dhcpc_state *s)
{
uip_sethostaddr(s->ipaddr);
uip_setnetmask(s->netmask);
uip_setdraddr(s->default_router);
resolv_conf(s->dnsaddr);
}
#endif /* __DHCPC_H__ */
void
smtp_done(unsigned char code)
{
printf("SMTP done with code %d\n", code);
}
void
webclient_closed(void)
{
printf("Webclient: connection closed\n");
}
void
webclient_aborted(void)
{
printf("Webclient: connection aborted\n");
}
void
webclient_timedout(void)
{
printf("Webclient: connection timed out\n");
}
void
webclient_connected(void)
{
printf("Webclient: connected, waiting for data...\n");
}
void
webclient_datahandler(char *data, u16_t len)
{
printf("Webclient: got %d bytes of data.\n", len);
}
/*---------------------------------------------------------------------------*/

152
android/uip/unix/tapdev.c Normal file
View File

@ -0,0 +1,152 @@
/*
* 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.8 2006/06/07 08:39:58 adam Exp $
*/
#define UIP_DRIPADDR0 192
#define UIP_DRIPADDR1 168
#define UIP_DRIPADDR2 0
#define UIP_DRIPADDR3 1
#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;
/*---------------------------------------------------------------------------*/
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(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);
}
/*---------------------------------------------------------------------------*/
unsigned int
tapdev_read(void)
{
fd_set fdset;
struct timeval tv, now;
int ret;
tv.tv_sec = 0;
tv.tv_usec = 1000;
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("tap_dev: tapdev_read: read");
}
/* 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;
/* printf("tapdev_send: sending %d bytes\n", size);*/
/* check_checksum(uip_buf, size);*/
/* drop++;
if(drop % 8 == 7) {
printf("Dropped a packet!\n");
return;
}*/
ret = write(fd, uip_buf, uip_len);
if(ret == -1) {
perror("tap_dev: tapdev_send: writev");
exit(1);
}
}
/*---------------------------------------------------------------------------*/

45
android/uip/unix/tapdev.h Normal file
View File

@ -0,0 +1,45 @@
/*
* 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: tapdev.h,v 1.1 2002/01/10 06:22:56 adam Exp $
*
*/
#ifndef __TAPDEV_H__
#define __TAPDEV_H__
void tapdev_init(void);
unsigned int tapdev_read(void);
void tapdev_send(void);
#endif /* __TAPDEV_H__ */

157
android/uip/unix/uip-conf.h Normal file
View File

@ -0,0 +1,157 @@
/**
* \addtogroup uipopt
* @{
*/
/**
* \name Project-specific configuration options
* @{
*
* uIP has a number of configuration options that can be overridden
* for each project. These are kept in a project-specific uip-conf.h
* file and all configuration names have the prefix UIP_CONF.
*/
/*
* Copyright (c) 2006, 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.
*
* This file is part of the uIP TCP/IP stack
*
* $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $
*/
/**
* \file
* An example uIP configuration file
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __UIP_CONF_H__
#define __UIP_CONF_H__
#include <inttypes.h>
/**
* 8 bit datatype
*
* This typedef defines the 8-bit type used throughout uIP.
*
* \hideinitializer
*/
typedef uint8_t u8_t;
/**
* 16 bit datatype
*
* This typedef defines the 16-bit type used throughout uIP.
*
* \hideinitializer
*/
typedef uint16_t u16_t;
/**
* Statistics datatype
*
* This typedef defines the dataype used for keeping statistics in
* uIP.
*
* \hideinitializer
*/
typedef unsigned short uip_stats_t;
/**
* Maximum number of TCP connections.
*
* \hideinitializer
*/
#define UIP_CONF_MAX_CONNECTIONS 40
/**
* Maximum number of listening TCP ports.
*
* \hideinitializer
*/
#define UIP_CONF_MAX_LISTENPORTS 40
/**
* uIP buffer size.
*
* \hideinitializer
*/
#define UIP_CONF_BUFFER_SIZE 420
/**
* CPU byte order.
*
* \hideinitializer
*/
#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN
/**
* Logging on or off
*
* \hideinitializer
*/
#define UIP_CONF_LOGGING 1
/**
* UDP support on or off
*
* \hideinitializer
*/
#define UIP_CONF_UDP 0
/**
* UDP checksums on or off
*
* \hideinitializer
*/
#define UIP_CONF_UDP_CHECKSUMS 1
/**
* uIP statistics on or off
*
* \hideinitializer
*/
#define UIP_CONF_STATISTICS 1
/* Here we include the header file for the application(s) we use in
our project. */
/*#include "smtp.h"*/
/*#include "hello-world.h"*/
/*#include "telnetd.h"*/
#include "webserver.h"
/*#include "dhcpc.h"*/
/*#include "resolv.h"*/
/*#include "webclient.h"*/
#endif /* __UIP_CONF_H__ */
/** @} */
/** @} */

View File

@ -18,6 +18,11 @@
#include "n2n.h" #include "n2n.h"
#ifdef __ANDROID_NDK__
#include "android/edge_android.h"
#include <tun2tap/tun2tap.h>
#endif /* __ANDROID_NDK__ */
#if defined(DEBUG) #if defined(DEBUG)
#define SOCKET_TIMEOUT_INTERVAL_SECS 5 #define SOCKET_TIMEOUT_INTERVAL_SECS 5
#define REGISTER_SUPER_INTERVAL_DFL 20 /* sec */ #define REGISTER_SUPER_INTERVAL_DFL 20 /* sec */
@ -32,6 +37,10 @@
#define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */ #define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */
#define TRANSOP_TICK_INTERVAL (10) /* sec */ #define TRANSOP_TICK_INTERVAL (10) /* sec */
#ifdef __ANDROID_NDK__
#define ARP_PERIOD_INTERVAL (10) /* sec */
#endif
/** Positions in the transop array where various transforms are stored. /** Positions in the transop array where various transforms are stored.
* *
* Used by transop_enum_to_index(). See also the transform enumerations in * Used by transop_enum_to_index(). See also the transform enumerations in
@ -1147,7 +1156,19 @@ static void readFromTAPSocket(n2n_edge_t * eee) {
macstr_t mac_buf; macstr_t mac_buf;
ssize_t len; ssize_t len;
len = tuntap_read(&(eee->device), eth_pkt, N2N_PKT_BUF_SIZE); #ifdef __ANDROID_NDK__
if (uip_arp_len != 0) {
len = uip_arp_len;
memcpy(eth_pkt, uip_arp_buf, MIN(uip_arp_len, N2N_PKT_BUF_SIZE));
traceEvent(TRACE_DEBUG, "ARP reply packet to send");
}
else
{
#endif /* #ifdef __ANDROID_NDK__ */
len = tuntap_read( &(eee->device), eth_pkt, N2N_PKT_BUF_SIZE );
#ifdef __ANDROID_NDK__
}
#endif /* #ifdef __ANDROID_NDK__ */
if((len <= 0) || (len > N2N_PKT_BUF_SIZE)) if((len <= 0) || (len > N2N_PKT_BUF_SIZE))
{ {
@ -1398,6 +1419,9 @@ int run_edge_loop(n2n_edge_t * eee, int *keep_running) {
size_t numPurged; size_t numPurged;
time_t lastIfaceCheck=0; time_t lastIfaceCheck=0;
time_t lastTransop=0; time_t lastTransop=0;
#ifdef __ANDROID_NDK__
time_t lastArpPeriod=0;
#endif
#ifdef WIN32 #ifdef WIN32
startTunReadThread(eee); startTunReadThread(eee);
@ -1412,7 +1436,7 @@ int run_edge_loop(n2n_edge_t * eee, int *keep_running) {
* readFromIPSocket() or readFromTAPSocket() * readFromIPSocket() or readFromTAPSocket()
*/ */
while(keep_running) { while(*keep_running) {
int rc, max_sock = 0; int rc, max_sock = 0;
fd_set socket_mask; fd_set socket_mask;
struct timeval wait_time; struct timeval wait_time;
@ -1451,6 +1475,13 @@ int run_edge_loop(n2n_edge_t * eee, int *keep_running) {
readFromIPSocket(eee); readFromIPSocket(eee);
} }
#ifdef __ANDROID_NDK__
if (uip_arp_len != 0) {
readFromTAPSocket(eee);
uip_arp_len = 0;
}
#endif /* #ifdef __ANDROID_NDK__ */
if(FD_ISSET(eee->udp_mgmt_sock, &socket_mask)) { if(FD_ISSET(eee->udp_mgmt_sock, &socket_mask)) {
/* Read a cooked socket from the internet socket. Writes on the TAP /* Read a cooked socket from the internet socket. Writes on the TAP
* socket. */ * socket. */
@ -1486,6 +1517,12 @@ int run_edge_loop(n2n_edge_t * eee, int *keep_running) {
tuntap_get_address(&(eee->device)); tuntap_get_address(&(eee->device));
lastIfaceCheck = nowTime; lastIfaceCheck = nowTime;
} }
#ifdef __ANDROID_NDK__
if ((nowTime - lastArpPeriod) > ARP_PERIOD_INTERVAL) {
uip_arp_timer();
}
#endif /* #ifdef __ANDROID_NDK__ */
} /* while */ } /* while */
send_deregister(eee, &(eee->supernode)); send_deregister(eee, &(eee->supernode));
@ -1579,6 +1616,26 @@ void edge_term(n2n_edge_t * eee) {
/* ************************************** */ /* ************************************** */
const char *random_device_mac(void)
{
const char key[] = "0123456789abcdef";
static char mac[18];
int i;
srand(getpid());
for (i = 0; i < sizeof(mac) - 1; ++i) {
if ((i + 1) % 3 == 0) {
mac[i] = ':';
continue;
}
mac[i] = key[random() % sizeof(key)];
}
mac[sizeof(mac) - 1] = '\0';
return mac;
}
/* ************************************** */
int quick_edge_init(char *device_name, char *community_name, int quick_edge_init(char *device_name, char *community_name,
char *encrypt_key, char *device_mac, char *encrypt_key, char *device_mac,
char *local_ip_address, char *local_ip_address,

24
n2n.c
View File

@ -118,8 +118,32 @@ void traceEvent(int eventTraceLevel, char* file, int line, char * format, ...) {
syslog(LOG_INFO, "%s", out_buf); syslog(LOG_INFO, "%s", out_buf);
} else { } else {
snprintf(out_buf, sizeof(out_buf), "%s [%11s:%4d] %s%s", theDate, file, line, extra_msg, buf); snprintf(out_buf, sizeof(out_buf), "%s [%11s:%4d] %s%s", theDate, file, line, extra_msg, buf);
#ifdef __ANDROID_NDK__
switch (eventTraceLevel) {
case 0: // ERROR
eventTraceLevel = ANDROID_LOG_ERROR;
break;
case 1: // WARNING
eventTraceLevel = ANDROID_LOG_WARN;
break;
case 2: // NORMAL
eventTraceLevel = ANDROID_LOG_INFO;
break;
case 3: // INFO
eventTraceLevel = ANDROID_LOG_DEBUG;
break;
case 4: // DEBUG
eventTraceLevel = ANDROID_LOG_VERBOSE;
break;
default: // NORMAL
eventTraceLevel = ANDROID_LOG_INFO;
break;
}
__android_log_write(eventTraceLevel, "n2n", buf);
#else
printf("%s\n", out_buf); printf("%s\n", out_buf);
fflush(stdout); fflush(stdout);
#endif /* #ifdef __ANDROID_NDK__ */
} }
#else #else
/* this is the WIN32 code */ /* this is the WIN32 code */

10
n2n.h
View File

@ -87,6 +87,12 @@ struct ether_hdr
typedef struct ether_hdr ether_hdr_t; typedef struct ether_hdr ether_hdr_t;
#ifdef __ANDROID_NDK__
#undef N2N_HAVE_DAEMON
#undef N2N_HAVE_SETUID
#undef N2N_CAN_NAME_IFACE
#endif /* #ifdef __ANDROID_NDK__ */
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <netinet/udp.h> #include <netinet/udp.h>
@ -220,6 +226,9 @@ struct n2n_edge {
/* ************************************** */ /* ************************************** */
#ifdef __ANDROID_NDK__
#include <android/log.h>
#endif /* #ifdef __ANDROID_NDK__ */
#ifndef TRACE_ERROR #ifndef TRACE_ERROR
#define TRACE_ERROR 0, __FILE__, __LINE__ #define TRACE_ERROR 0, __FILE__, __LINE__
#define TRACE_WARNING 1, __FILE__, __LINE__ #define TRACE_WARNING 1, __FILE__, __LINE__
@ -327,6 +336,7 @@ int edge_init_twofish(n2n_edge_t * eee, uint8_t *encrypt_pwd,
uint32_t encrypt_pwd_len); uint32_t encrypt_pwd_len);
int run_edge_loop(n2n_edge_t * eee, int *keep_running); int run_edge_loop(n2n_edge_t * eee, int *keep_running);
void edge_term(n2n_edge_t * eee); void edge_term(n2n_edge_t * eee);
const char *random_device_mac(void);
int quick_edge_init(char *device_name, char *community_name, int quick_edge_init(char *device_name, char *community_name,
char *encrypt_key, char *device_mac, char *encrypt_key, char *device_mac,
char *local_ip_address, char *local_ip_address,

Some files were not shown because too many files have changed in this diff Show More