⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uip.c

📁 uIP1.0完整源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
#define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*//** * \defgroup uip The uIP TCP/IP stack * @{ * * uIP is an implementation of the TCP/IP protocol stack intended for * small 8-bit and 16-bit microcontrollers. * * uIP provides the necessary protocols for Internet communication, * with a very small code footprint and RAM requirements - the uIP * code size is on the order of a few kilobytes and RAM usage is on * the order of a few hundred bytes. *//** * \file * The uIP TCP/IP stack code. * \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.c,v 1.65 2006/06/11 21:46:39 adam Exp $ * *//* * uIP is a small implementation of the IP, UDP and TCP protocols (as * well as some basic ICMP stuff). The implementation couples the IP, * UDP, TCP and the application layers very tightly. To keep the size * of the compiled code down, this code frequently uses the goto * statement. While it would be possible to break the uip_process() * function into many smaller functions, this would increase the code * size because of the overhead of parameter passing and the fact that * the optimier would not be as efficient. * * The principle is that we have a small buffer, called the uip_buf, * in which the device driver puts an incoming packet. The TCP/IP * stack parses the headers in the packet, and calls the * application. If the remote host has sent data to the application, * this data is present in the uip_buf and the application read the * data from there. It is up to the application to put this data into * a byte stream if needed. The application will not be fed with data * that is out of sequence. * * If the application whishes to send data to the peer, it should put * its data into the uip_buf. The uip_appdata pointer points to the * first available byte. The TCP/IP stack will calculate the * checksums, and fill in the necessary header fields and finally send * the packet back to the peer.*/#include "uip.h"#include "uipopt.h"#include "uip_arch.h"#if UIP_CONF_IPV6#include "uip-neighbor.h"#endif /* UIP_CONF_IPV6 */#include <string.h>/*---------------------------------------------------------------------------*//* Variable definitions. *//* The IP address of this host. If it is defined to be fixed (by   setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set   here. Otherwise, the address */#if UIP_FIXEDADDR > 0const uip_ipaddr_t uip_hostaddr =  {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),   HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};const uip_ipaddr_t uip_draddr =  {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),   HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};const uip_ipaddr_t uip_netmask =  {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),   HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};#elseuip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;#endif /* UIP_FIXEDADDR */static const uip_ipaddr_t all_ones_addr =#if UIP_CONF_IPV6  {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff};#else /* UIP_CONF_IPV6 */  {0xffff,0xffff};#endif /* UIP_CONF_IPV6 */static const uip_ipaddr_t all_zeroes_addr =#if UIP_CONF_IPV6  {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};#else /* UIP_CONF_IPV6 */  {0x0000,0x0000};#endif /* UIP_CONF_IPV6 */#if UIP_FIXEDETHADDRconst struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,					  UIP_ETHADDR1,					  UIP_ETHADDR2,					  UIP_ETHADDR3,					  UIP_ETHADDR4,					  UIP_ETHADDR5}};#elsestruct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}};#endif#ifndef UIP_CONF_EXTERNAL_BUFFERu8_t uip_buf[UIP_BUFSIZE + 2];   /* The packet buffer that contains				    incoming packets. */#endif /* UIP_CONF_EXTERNAL_BUFFER */void *uip_appdata;               /* The uip_appdata pointer points to				    application data. */void *uip_sappdata;              /* The uip_appdata pointer points to				    the application data which is to				    be sent. */#if UIP_URGDATA > 0void *uip_urgdata;               /* The uip_urgdata pointer points to   				    urgent data (out-of-band data), if   				    present. */u16_t uip_urglen, uip_surglen;#endif /* UIP_URGDATA > 0 */u16_t uip_len, uip_slen;                             /* The uip_len is either 8 or 16 bits,				depending on the maximum packet				size. */u8_t uip_flags;     /* The uip_flags variable is used for				communication between the TCP/IP stack				and the application program. */struct uip_conn *uip_conn;   /* uip_conn always points to the current				connection. */struct uip_conn uip_conns[UIP_CONNS];                             /* The uip_conns array holds all TCP				connections. */u16_t uip_listenports[UIP_LISTENPORTS];                             /* The uip_listenports list all currently				listning ports. */#if UIP_UDPstruct uip_udp_conn *uip_udp_conn;struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];#endif /* UIP_UDP */static u16_t ipid;           /* Ths ipid variable is an increasing				number that is used for the IP ID				field. */void uip_setipid(u16_t id) { ipid = id; }static u8_t iss[4];          /* The iss variable is used for the TCP				initial sequence number. */#if UIP_ACTIVE_OPENstatic u16_t lastport;       /* Keeps track of the last port used for				a new connection. */#endif /* UIP_ACTIVE_OPEN *//* Temporary variables. */u8_t uip_acc32[4];static u8_t c, opt;static u16_t tmp16;/* Structures and definitions. */#define TCP_FIN 0x01#define TCP_SYN 0x02#define TCP_RST 0x04#define TCP_PSH 0x08#define TCP_ACK 0x10#define TCP_URG 0x20#define TCP_CTL 0x3f#define TCP_OPT_END     0   /* End of TCP options list */#define TCP_OPT_NOOP    1   /* "No-operation" TCP option */#define TCP_OPT_MSS     2   /* Maximum segment size TCP option */#define TCP_OPT_MSS_LEN 4   /* Length of TCP MSS option. */#define ICMP_ECHO_REPLY 0#define ICMP_ECHO       8#define ICMP6_ECHO_REPLY             129#define ICMP6_ECHO                   128#define ICMP6_NEIGHBOR_SOLICITATION  135#define ICMP6_NEIGHBOR_ADVERTISEMENT 136#define ICMP6_FLAG_S (1 << 6)#define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1#define ICMP6_OPTION_TARGET_LINK_ADDRESS 2/* Macros. */#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])#if UIP_STATISTICS == 1struct uip_stats uip_stat;#define UIP_STAT(s) s#else#define UIP_STAT(s)#endif /* UIP_STATISTICS == 1 */#if UIP_LOGGING == 1#include <stdio.h>void uip_log(char *msg);#define UIP_LOG(m) uip_log(m)#else#define UIP_LOG(m)#endif /* UIP_LOGGING == 1 */#if ! UIP_ARCH_ADD32voiduip_add32(u8_t *op32, u16_t op16){  uip_acc32[3] = op32[3] + (op16 & 0xff);  uip_acc32[2] = op32[2] + (op16 >> 8);  uip_acc32[1] = op32[1];  uip_acc32[0] = op32[0];    if(uip_acc32[2] < (op16 >> 8)) {    ++uip_acc32[1];    if(uip_acc32[1] == 0) {      ++uip_acc32[0];    }  }      if(uip_acc32[3] < (op16 & 0xff)) {    ++uip_acc32[2];    if(uip_acc32[2] == 0) {      ++uip_acc32[1];      if(uip_acc32[1] == 0) {	++uip_acc32[0];      }    }  }}#endif /* UIP_ARCH_ADD32 */#if ! UIP_ARCH_CHKSUM/*---------------------------------------------------------------------------*/static u16_tchksum(u16_t sum, const u8_t *data, u16_t len){  u16_t t;  const u8_t *dataptr;  const u8_t *last_byte;  dataptr = data;  last_byte = data + len - 1;    while(dataptr < last_byte) {	/* At least two more bytes */    t = (dataptr[0] << 8) + dataptr[1];    sum += t;    if(sum < t) {      sum++;		/* carry */    }    dataptr += 2;  }    if(dataptr == last_byte) {    t = (dataptr[0] << 8) + 0;    sum += t;    if(sum < t) {      sum++;		/* carry */    }  }  /* Return sum in host byte order. */  return sum;}/*---------------------------------------------------------------------------*/u16_tuip_chksum(u16_t *data, u16_t len){  return htons(chksum(0, (u8_t *)data, len));}/*---------------------------------------------------------------------------*/#ifndef UIP_ARCH_IPCHKSUMu16_tuip_ipchksum(void){  u16_t sum;  sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);  DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum);  return (sum == 0) ? 0xffff : htons(sum);}#endif/*---------------------------------------------------------------------------*/static u16_tupper_layer_chksum(u8_t proto){  u16_t upper_layer_len;  u16_t sum;  #if UIP_CONF_IPV6  upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]);#else /* UIP_CONF_IPV6 */  upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;#endif /* UIP_CONF_IPV6 */    /* First sum pseudoheader. */    /* IP protocol and length fields. This addition cannot carry. */  sum = upper_layer_len + proto;  /* Sum IP source and destination addresses. */  sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));  /* Sum TCP header and data. */  sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],	       upper_layer_len);      return (sum == 0) ? 0xffff : htons(sum);}/*---------------------------------------------------------------------------*/#if UIP_CONF_IPV6u16_tuip_icmp6chksum(void){  return upper_layer_chksum(UIP_PROTO_ICMP6);  }#endif /* UIP_CONF_IPV6 *//*---------------------------------------------------------------------------*/u16_tuip_tcpchksum(void){  return upper_layer_chksum(UIP_PROTO_TCP);}/*---------------------------------------------------------------------------*/#if UIP_UDP_CHECKSUMSu16_tuip_udpchksum(void){  return upper_layer_chksum(UIP_PROTO_UDP);}#endif /* UIP_UDP_CHECKSUMS */#endif /* UIP_ARCH_CHKSUM *//*---------------------------------------------------------------------------*/voiduip_init(void){  for(c = 0; c < UIP_LISTENPORTS; ++c) {    uip_listenports[c] = 0;  }  for(c = 0; c < UIP_CONNS; ++c) {    uip_conns[c].tcpstateflags = UIP_CLOSED;  }#if UIP_ACTIVE_OPEN  lastport = 1024;#endif /* UIP_ACTIVE_OPEN */#if UIP_UDP  for(c = 0; c < UIP_UDP_CONNS; ++c) {    uip_udp_conns[c].lport = 0;  }#endif /* UIP_UDP */    /* IPv4 initialization. */#if UIP_FIXEDADDR == 0  /*  uip_hostaddr[0] = uip_hostaddr[1] = 0;*/#endif /* UIP_FIXEDADDR */}/*---------------------------------------------------------------------------*/#if UIP_ACTIVE_OPENstruct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t rport){  register struct uip_conn *conn, *cconn;    /* Find an unused local port. */ again:  ++lastport;  if(lastport >= 32000) {    lastport = 4096;  }  /* Check if this port is already in use, and if so try to find     another one. */  for(c = 0; c < UIP_CONNS; ++c) {    conn = &uip_conns[c];    if(conn->tcpstateflags != UIP_CLOSED &&       conn->lport == htons(lastport)) {      goto again;    }  }  conn = 0;  for(c = 0; c < UIP_CONNS; ++c) {    cconn = &uip_conns[c];    if(cconn->tcpstateflags == UIP_CLOSED) {      conn = cconn;      break;    }    if(cconn->tcpstateflags == UIP_TIME_WAIT) {      if(conn == 0 ||	 cconn->timer > conn->timer) {	conn = cconn;      }    }  }  if(conn == 0) {    return 0;  }    conn->tcpstateflags = UIP_SYN_SENT;  conn->snd_nxt[0] = iss[0];  conn->snd_nxt[1] = iss[1];  conn->snd_nxt[2] = iss[2];  conn->snd_nxt[3] = iss[3];  conn->initialmss = conn->mss = UIP_TCP_MSS;    conn->len = 1;   /* TCP length of the SYN is one. */  conn->nrtx = 0;  conn->timer = 1; /* Send the SYN next time around. */  conn->rto = UIP_RTO;  conn->sa = 0;  conn->sv = 16;   /* Initial value of the RTT variance. */  conn->lport = htons(lastport);  conn->rport = rport;  uip_ipaddr_copy(&conn->ripaddr, ripaddr);    return conn;}#endif /* UIP_ACTIVE_OPEN *//*---------------------------------------------------------------------------*/#if UIP_UDPstruct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport){  register struct uip_udp_conn *conn;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -