45 #define DEBUG_PRINTF(...)
98 const uip_ipaddr_t uip_hostaddr =
99 { UIP_IPADDR0, UIP_IPADDR1, UIP_IPADDR2, UIP_IPADDR3 };
100 const uip_ipaddr_t uip_draddr =
101 { UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3 };
102 const uip_ipaddr_t uip_netmask =
103 { UIP_NETMASK0, UIP_NETMASK1, UIP_NETMASK2, UIP_NETMASK3 };
105 uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
108 const uip_ipaddr_t uip_broadcast_addr =
110 { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
111 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
113 { { 0xff, 0xff, 0xff, 0xff } };
115 const uip_ipaddr_t uip_all_zeroes_addr = { { 0x0, } };
140 uint16_t uip_urglen, uip_surglen;
165 static uint16_t ipid;
171 static uint8_t iss[4];
174 #if UIP_ACTIVE_OPEN || UIP_UDP
175 static uint16_t lastport;
181 static uint8_t c, opt;
182 static uint16_t tmp16;
193 #define TCP_OPT_END 0
194 #define TCP_OPT_NOOP 1
195 #define TCP_OPT_MSS 2
197 #define TCP_OPT_MSS_LEN 4
199 #define ICMP_ECHO_REPLY 0
202 #define ICMP_DEST_UNREACHABLE 3
203 #define ICMP_PORT_UNREACHABLE 3
205 #define ICMP6_ECHO_REPLY 129
206 #define ICMP6_ECHO 128
207 #define ICMP6_NEIGHBOR_SOLICITATION 135
208 #define ICMP6_NEIGHBOR_ADVERTISEMENT 136
210 #define ICMP6_FLAG_S (1 << 6)
212 #define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1
213 #define ICMP6_OPTION_TARGET_LINK_ADDRESS 2
217 #define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
218 #define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
219 #define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
220 #define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
223 #if UIP_STATISTICS == 1
225 #define UIP_STAT(s) s
233 #define UIP_LOG(m) uip_log(m)
244 uip_acc32[1] = op32[1];
245 uip_acc32[0] = op32[0];
247 if(uip_acc32[2] < (op16 >> 8)) {
249 if(uip_acc32[1] == 0) {
255 if(uip_acc32[3] < (op16 & 0xff)) {
257 if(uip_acc32[2] == 0) {
259 if(uip_acc32[1] == 0) {
268 #if ! UIP_ARCH_CHKSUM
271 chksum(uint16_t sum,
const uint8_t *data, uint16_t len)
274 const uint8_t *dataptr;
275 const uint8_t *last_byte;
278 last_byte = data + len - 1;
280 while(dataptr < last_byte) {
281 t = (dataptr[0] << 8) + dataptr[1];
289 if(dataptr == last_byte) {
290 t = (dataptr[0] << 8) + 0;
304 return uip_htons(chksum(0, (uint8_t *)data, len));
307 #ifndef UIP_ARCH_IPCHKSUM
313 sum = chksum(0, &uip_buf[
UIP_LLH_LEN], UIP_IPH_LEN);
314 DEBUG_PRINTF(
"uip_ipchksum: sum 0x%04x\n", sum);
315 return (sum == 0) ? 0xffff :
uip_htons(sum);
320 upper_layer_chksum(uint8_t proto)
322 uint16_t upper_layer_len;
326 upper_layer_len = (((uint16_t)(BUF->len[0]) << 8) + BUF->len[1]);
328 upper_layer_len = (((uint16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
334 sum = upper_layer_len + proto;
336 sum = chksum(sum, (uint8_t *)&BUF->srcipaddr, 2 *
sizeof(uip_ipaddr_t));
339 sum = chksum(sum, &uip_buf[UIP_IPH_LEN +
UIP_LLH_LEN],
342 return (sum == 0) ? 0xffff :
uip_htons(sum);
349 return upper_layer_chksum(UIP_PROTO_ICMP6);
357 return upper_layer_chksum(UIP_PROTO_TCP);
360 #if UIP_UDP_CHECKSUMS
364 return upper_layer_chksum(UIP_PROTO_UDP);
373 uip_listenports[c] = 0;
376 uip_conns[c].tcpstateflags = UIP_CLOSED;
378 #if UIP_ACTIVE_OPEN || UIP_UDP
384 uip_udp_conns[c].
lport = 0;
390 #if UIP_FIXEDADDR == 0
400 register struct uip_conn *conn, *cconn;
406 if(lastport >= 32000) {
413 conn = &uip_conns[c];
422 cconn = &uip_conns[c];
463 struct uip_udp_conn *
464 uip_udp_new(
const uip_ipaddr_t *ripaddr, uint16_t rport)
466 register struct uip_udp_conn *conn;
472 if(lastport >= 32000) {
485 if(uip_udp_conns[c].
lport == 0) {
486 conn = &uip_udp_conns[c];
497 if(ripaddr ==
NULL) {
498 memset(&conn->
ripaddr, 0,
sizeof(uip_ipaddr_t));
512 if(uip_listenports[c] == port) {
513 uip_listenports[c] = 0;
523 if(uip_listenports[c] == 0) {
524 uip_listenports[c] = port;
532 #if UIP_REASSEMBLY && !UIP_CONF_IPV6
533 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
534 static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE];
535 static uint8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
536 static const uint8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
537 0x0f, 0x07, 0x03, 0x01};
538 static uint16_t uip_reasslen;
539 static uint8_t uip_reassflags;
540 #define UIP_REASS_FLAG_LASTFRAG 0x01
541 static uint8_t uip_reasstmr;
548 uint16_t offset, len;
554 if(uip_reasstmr == 0) {
555 memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN);
559 memset(uip_reassbitmap, 0,
sizeof(uip_reassbitmap));
565 if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
566 BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
567 BUF->destipaddr[0] == FBUF->destipaddr[0] &&
568 BUF->destipaddr[1] == FBUF->destipaddr[1] &&
569 BUF->ipid[0] == FBUF->ipid[0] &&
570 BUF->ipid[1] == FBUF->ipid[1]) {
572 len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
573 offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
577 if(offset > UIP_REASS_BUFSIZE ||
578 offset + len > UIP_REASS_BUFSIZE) {
585 memcpy(&uip_reassbuf[UIP_IPH_LEN + offset],
586 (
char *)BUF + (
int)((BUF->vhl & 0x0f) * 4),
590 if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
594 uip_reassbitmap[offset / (8 * 8)] |=
595 bitmap_bits[(offset / 8 ) & 7] &
596 ~bitmap_bits[((offset + len) / 8 ) & 7];
601 uip_reassbitmap[offset / (8 * 8)] |=
602 bitmap_bits[(offset / 8 ) & 7];
603 for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
604 uip_reassbitmap[i] = 0xff;
606 uip_reassbitmap[(offset + len) / (8 * 8)] |=
607 ~bitmap_bits[((offset + len) / 8 ) & 7];
616 if((BUF->ipoffset[0] & IP_MF) == 0) {
617 uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
618 uip_reasslen = offset + len;
624 if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
627 for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
628 if(uip_reassbitmap[i] != 0xff) {
634 if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
635 (uint8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
643 memcpy(BUF, FBUF, uip_reasslen);
647 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
648 BUF->len[0] = uip_reasslen >> 8;
649 BUF->len[1] = uip_reasslen & 0xff;
663 uip_add_rcv_nxt(uint16_t n)
666 uip_conn->
rcv_nxt[0] = uip_acc32[0];
667 uip_conn->
rcv_nxt[1] = uip_acc32[1];
668 uip_conn->
rcv_nxt[2] = uip_acc32[2];
669 uip_conn->
rcv_nxt[3] = uip_acc32[3];
675 register struct uip_conn *uip_connr =
uip_conn;
678 if(flag == UIP_UDP_SEND_CONN) {
687 if(flag == UIP_POLL_REQUEST) {
688 if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
689 !uip_outstanding(uip_connr)) {
690 uip_flags = UIP_POLL;
693 #if UIP_ACTIVE_OPEN && UIP_TCP
694 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
703 }
else if(flag == UIP_TIMER) {
705 if(uip_reasstmr != 0) {
729 ++(uip_connr->
timer);
738 if(uip_outstanding(uip_connr)) {
739 if(uip_connr->
timer-- == 0) {
749 uip_flags = UIP_TIMEDOUT;
753 BUF->flags = TCP_RST | TCP_ACK;
754 goto tcp_send_nodata;
774 goto tcp_send_synack;
783 case UIP_ESTABLISHED:
788 uip_flags = UIP_REXMIT;
796 goto tcp_send_finack;
800 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
803 uip_flags = UIP_POLL;
812 if(flag == UIP_UDP_TIMER) {
813 if(uip_udp_conn->
lport != 0) {
817 uip_flags = UIP_POLL;
833 if((BUF->vtc & 0xf0) != 0x60) {
836 UIP_LOG(
"ipv6: invalid version.");
841 if(BUF->vhl != 0x45) {
844 UIP_LOG(
"ip: invalid version or header length.");
856 if((BUF->len[0] << 8) + BUF->len[1] <=
uip_len) {
857 uip_len = (BUF->len[0] << 8) + BUF->len[1];
870 UIP_LOG(
"ip: packet shorter than reported in IP header.");
876 if((BUF->ipoffset[0] & 0x3f) != 0 ||
877 BUF->ipoffset[1] != 0) {
886 UIP_LOG(
"ip: fragment dropped.");
892 if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) {
896 #if UIP_PINGADDRCONF && !UIP_CONF_IPV6
897 if(BUF->proto == UIP_PROTO_ICMP) {
898 UIP_LOG(
"ip: possible ping config packet received.");
901 UIP_LOG(
"ip: packet dropped since no address assigned.");
910 DEBUG_PRINTF(
"UDP IP checksum 0x%04x\n",
uip_ipchksum());
911 if(BUF->proto == UIP_PROTO_UDP &&
912 (uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr) ||
913 (BUF->destipaddr.u8[0] & 224) == 224)) {
928 if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr)) {
938 if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr) &&
939 BUF->destipaddr.u16[0] !=
UIP_HTONS(0xff02)) {
951 UIP_LOG(
"ip: bad checksum.");
957 if(BUF->proto == UIP_PROTO_TCP) {
965 if(BUF->proto == UIP_PROTO_UDP) {
972 if(BUF->proto != UIP_PROTO_ICMP) {
976 UIP_LOG(
"ip: neither tcp nor icmp.");
988 if(ICMPBUF->type != ICMP_ECHO) {
991 UIP_LOG(
"icmp: not icmp echo.");
999 if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) {
1000 uip_hostaddr = BUF->destipaddr;
1004 ICMPBUF->type = ICMP_ECHO_REPLY;
1006 if(ICMPBUF->icmpchksum >=
UIP_HTONS(0xffff - (ICMP_ECHO << 8))) {
1007 ICMPBUF->icmpchksum +=
UIP_HTONS(ICMP_ECHO << 8) + 1;
1009 ICMPBUF->icmpchksum +=
UIP_HTONS(ICMP_ECHO << 8);
1024 DEBUG_PRINTF(
"icmp6_input: length %d\n",
uip_len);
1026 if(BUF->proto != UIP_PROTO_ICMP6) {
1030 UIP_LOG(
"ip: neither tcp nor icmp6.");
1038 if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
1039 if(uip_ipaddr_cmp(&ICMPBUF->icmp6data, &uip_hostaddr)) {
1041 if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {
1043 uip_neighbor_add(&ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
1048 ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
1049 ICMPBUF->flags = ICMP6_FLAG_S;
1051 ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
1055 ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
1056 ICMPBUF->options[1] = 1;
1057 memcpy(&(ICMPBUF->options[2]), &uip_lladdr,
sizeof(uip_lladdr));
1058 ICMPBUF->icmpchksum = 0;
1065 }
else if(ICMPBUF->type == ICMP6_ECHO) {
1074 ICMPBUF->icmpchksum = 0;
1080 DEBUG_PRINTF(
"Unknown icmp6 message type %d\n", ICMPBUF->type);
1083 UIP_LOG(
"icmp: unknown ICMP message.");
1098 #if UIP_UDP_CHECKSUMS
1104 UIP_LOG(
"udp: bad checksum.");
1112 if(UDPBUF->destport == 0) {
1113 UIP_LOG(
"udp: zero port.");
1118 for(uip_udp_conn = &uip_udp_conns[0];
1128 if(uip_udp_conn->
lport != 0 &&
1129 UDPBUF->destport == uip_udp_conn->
lport &&
1130 (uip_udp_conn->
rport == 0 ||
1131 UDPBUF->srcport == uip_udp_conn->
rport) &&
1132 (uip_ipaddr_cmp(&uip_udp_conn->
ripaddr, &uip_all_zeroes_addr) ||
1133 uip_ipaddr_cmp(&uip_udp_conn->
ripaddr, &uip_broadcast_addr) ||
1134 uip_ipaddr_cmp(&BUF->srcipaddr, &uip_udp_conn->
ripaddr))) {
1138 UIP_LOG(
"udp: no matching connection found");
1140 #if UIP_CONF_ICMP_DEST_UNREACH && !UIP_CONF_IPV6
1142 memcpy(&(ICMPBUF->payload[0]), ICMPBUF, UIP_IPH_LEN + 8);
1145 ICMPBUF->type = ICMP_DEST_UNREACHABLE;
1146 ICMPBUF->icode = ICMP_PORT_UNREACHABLE;
1149 ICMPBUF->icmpchksum = 0;
1150 ICMPBUF->icmpchksum = ~
uip_chksum((uint16_t *)&(ICMPBUF->type), 36);
1162 ICMPBUF->len[0] = 0;
1163 ICMPBUF->len[1] = (uint8_t)
uip_len;
1165 ICMPBUF->proto = UIP_PROTO_ICMP;
1175 uip_flags = UIP_NEWDATA;
1184 uip_len = uip_slen + UIP_IPUDPH_LEN;
1189 BUF->len[0] = ((
uip_len - UIP_IPH_LEN) >> 8);
1190 BUF->len[1] = ((
uip_len - UIP_IPH_LEN) & 0xff);
1193 BUF->len[1] = (
uip_len & 0xff);
1196 BUF->ttl = uip_udp_conn->
ttl;
1197 BUF->proto = UIP_PROTO_UDP;
1199 UDPBUF->udplen =
UIP_HTONS(uip_slen + UIP_UDPH_LEN);
1200 UDPBUF->udpchksum = 0;
1202 BUF->srcport = uip_udp_conn->
lport;
1203 BUF->destport = uip_udp_conn->
rport;
1210 #if UIP_UDP_CHECKSUMS
1213 if(UDPBUF->udpchksum == 0) {
1214 UDPBUF->udpchksum = 0xffff;
1233 UIP_LOG(
"tcp: bad checksum.");
1238 if(BUF->destport == 0 || BUF->srcport == 0) {
1239 UIP_LOG(
"tcp: zero port.");
1245 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
1248 BUF->destport == uip_connr->
lport &&
1249 BUF->srcport == uip_connr->
rport &&
1250 uip_ipaddr_cmp(&BUF->srcipaddr, &uip_connr->
ripaddr)) {
1259 if((BUF->flags & TCP_CTL) != TCP_SYN) {
1263 tmp16 = BUF->destport;
1266 if(tmp16 == uip_listenports[c]) {
1276 if(BUF->flags & TCP_RST) {
1282 BUF->flags = TCP_RST | TCP_ACK;
1284 BUF->tcpoffset = 5 << 4;
1288 BUF->seqno[3] = BUF->ackno[3];
1292 BUF->seqno[2] = BUF->ackno[2];
1296 BUF->seqno[1] = BUF->ackno[1];
1300 BUF->seqno[0] = BUF->ackno[0];
1306 if(++BUF->ackno[3] == 0) {
1307 if(++BUF->ackno[2] == 0) {
1308 if(++BUF->ackno[1] == 0) {
1315 tmp16 = BUF->srcport;
1316 BUF->srcport = BUF->destport;
1317 BUF->destport = tmp16;
1324 goto tcp_send_noconn;
1339 uip_connr = &uip_conns[c];
1343 if(uip_connr == 0 ||
1345 uip_connr = &uip_conns[c];
1350 if(uip_connr == 0) {
1355 UIP_LOG(
"tcp: found no unused connections.");
1358 uip_conn = uip_connr;
1364 uip_connr->
nrtx = 0;
1365 uip_connr->
lport = BUF->destport;
1366 uip_connr->
rport = BUF->srcport;
1370 uip_connr->
snd_nxt[0] = iss[0];
1371 uip_connr->
snd_nxt[1] = iss[1];
1372 uip_connr->
snd_nxt[2] = iss[2];
1373 uip_connr->
snd_nxt[3] = iss[3];
1377 uip_connr->
rcv_nxt[3] = BUF->seqno[3];
1378 uip_connr->
rcv_nxt[2] = BUF->seqno[2];
1379 uip_connr->
rcv_nxt[1] = BUF->seqno[1];
1380 uip_connr->
rcv_nxt[0] = BUF->seqno[0];
1384 if((BUF->tcpoffset & 0xf0) > 0x50) {
1385 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
1387 if(opt == TCP_OPT_END) {
1390 }
else if(opt == TCP_OPT_NOOP) {
1393 }
else if(opt == TCP_OPT_MSS &&
1394 uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
1396 tmp16 = ((uint16_t)uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 2 + c] << 8) |
1397 (uint16_t)uip_buf[UIP_IPTCPH_LEN +
UIP_LLH_LEN + 3 + c];
1406 if(uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 1 + c] == 0) {
1411 c += uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 1 + c];
1419 BUF->flags = TCP_ACK;
1422 BUF->flags |= TCP_SYN;
1425 BUF->flags = TCP_SYN | TCP_ACK;
1430 BUF->optdata[0] = TCP_OPT_MSS;
1431 BUF->optdata[1] = TCP_OPT_MSS_LEN;
1434 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
1435 BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
1440 uip_conn = uip_connr;
1446 if(BUF->flags & TCP_RST) {
1448 UIP_LOG(
"tcp: got reset, aborting connection.");
1449 uip_flags = UIP_ABORT;
1455 c = (BUF->tcpoffset >> 4) << 2;
1466 if(!((((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
1467 ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
1468 (((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
1469 ((BUF->flags & TCP_CTL) == TCP_SYN)))) {
1470 if((
uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
1471 (BUF->seqno[0] != uip_connr->
rcv_nxt[0] ||
1472 BUF->seqno[1] != uip_connr->
rcv_nxt[1] ||
1473 BUF->seqno[2] != uip_connr->
rcv_nxt[2] ||
1474 BUF->seqno[3] != uip_connr->
rcv_nxt[3])) {
1483 if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
1486 if(BUF->ackno[0] == uip_acc32[0] &&
1487 BUF->ackno[1] == uip_acc32[1] &&
1488 BUF->ackno[2] == uip_acc32[2] &&
1489 BUF->ackno[3] == uip_acc32[3]) {
1491 uip_connr->
snd_nxt[0] = uip_acc32[0];
1492 uip_connr->
snd_nxt[1] = uip_acc32[1];
1493 uip_connr->
snd_nxt[2] = uip_acc32[2];
1494 uip_connr->
snd_nxt[3] = uip_acc32[3];
1497 if(uip_connr->
nrtx == 0) {
1499 m = uip_connr->
rto - uip_connr->
timer;
1501 m = m - (uip_connr->
sa >> 3);
1506 m = m - (uip_connr->
sv >> 2);
1508 uip_connr->
rto = (uip_connr->
sa >> 3) + uip_connr->
sv;
1512 uip_flags = UIP_ACKDATA;
1533 if(uip_flags & UIP_ACKDATA) {
1535 uip_flags = UIP_CONNECTED;
1538 uip_flags |= UIP_NEWDATA;
1546 if((BUF->flags & TCP_CTL) == TCP_SYN) {
1547 goto tcp_send_synack;
1556 if((uip_flags & UIP_ACKDATA) &&
1557 (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
1560 if((BUF->tcpoffset & 0xf0) > 0x50) {
1561 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
1563 if(opt == TCP_OPT_END) {
1566 }
else if(opt == TCP_OPT_NOOP) {
1569 }
else if(opt == TCP_OPT_MSS &&
1570 uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
1572 tmp16 = (uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 2 + c] << 8) |
1582 if(uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 1 + c] == 0) {
1587 c += uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 1 + c];
1592 uip_connr->
rcv_nxt[0] = BUF->seqno[0];
1593 uip_connr->
rcv_nxt[1] = BUF->seqno[1];
1594 uip_connr->
rcv_nxt[2] = BUF->seqno[2];
1595 uip_connr->
rcv_nxt[3] = BUF->seqno[3];
1597 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
1605 uip_flags = UIP_ABORT;
1612 case UIP_ESTABLISHED:
1624 if(BUF->flags & TCP_FIN && !(uip_connr->
tcpstateflags & UIP_STOPPED)) {
1625 if(uip_outstanding(uip_connr)) {
1629 uip_flags |= UIP_CLOSE;
1631 uip_flags |= UIP_NEWDATA;
1636 uip_connr->
nrtx = 0;
1638 BUF->flags = TCP_FIN | TCP_ACK;
1639 goto tcp_send_nodata;
1644 if((BUF->flags & TCP_URG) != 0) {
1646 uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
1651 uip_add_rcv_nxt(uip_urglen);
1659 uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
1669 uip_flags |= UIP_NEWDATA;
1685 tmp16 = ((uint16_t)BUF->wnd[0] << 8) + (uint16_t)BUF->wnd[1];
1690 uip_connr->
mss = tmp16;
1708 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
1714 if(uip_flags & UIP_ABORT) {
1717 BUF->flags = TCP_RST | TCP_ACK;
1718 goto tcp_send_nodata;
1721 if(uip_flags & UIP_CLOSE) {
1725 uip_connr->
nrtx = 0;
1726 BUF->flags = TCP_FIN | TCP_ACK;
1727 goto tcp_send_nodata;
1735 if((uip_flags & UIP_ACKDATA) != 0) {
1742 if(uip_connr->
len == 0) {
1747 if(uip_slen > uip_connr->
mss) {
1748 uip_slen = uip_connr->
mss;
1753 uip_connr->
len = uip_slen;
1759 uip_slen = uip_connr->
len;
1762 uip_connr->
nrtx = 0;
1768 if(uip_slen > 0 && uip_connr->
len > 0) {
1772 BUF->flags = TCP_ACK | TCP_PSH;
1774 goto tcp_send_noopts;
1778 if(uip_flags & UIP_NEWDATA) {
1780 BUF->flags = TCP_ACK;
1781 goto tcp_send_noopts;
1788 if(uip_flags & UIP_ACKDATA) {
1790 uip_flags = UIP_CLOSE;
1795 case UIP_FIN_WAIT_1:
1802 if(BUF->flags & TCP_FIN) {
1803 if(uip_flags & UIP_ACKDATA) {
1805 uip_connr->
timer = 0;
1811 uip_flags = UIP_CLOSE;
1814 }
else if(uip_flags & UIP_ACKDATA) {
1824 case UIP_FIN_WAIT_2:
1828 if(BUF->flags & TCP_FIN) {
1830 uip_connr->
timer = 0;
1832 uip_flags = UIP_CLOSE;
1845 if(uip_flags & UIP_ACKDATA) {
1847 uip_connr->
timer = 0;
1855 BUF->flags = TCP_ACK;
1861 BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
1868 BUF->ackno[0] = uip_connr->
rcv_nxt[0];
1869 BUF->ackno[1] = uip_connr->
rcv_nxt[1];
1870 BUF->ackno[2] = uip_connr->
rcv_nxt[2];
1871 BUF->ackno[3] = uip_connr->
rcv_nxt[3];
1873 BUF->seqno[0] = uip_connr->
snd_nxt[0];
1874 BUF->seqno[1] = uip_connr->
snd_nxt[1];
1875 BUF->seqno[2] = uip_connr->
snd_nxt[2];
1876 BUF->seqno[3] = uip_connr->
snd_nxt[3];
1878 BUF->proto = UIP_PROTO_TCP;
1880 BUF->srcport = uip_connr->
lport;
1881 BUF->destport = uip_connr->
rport;
1889 BUF->wnd[0] = BUF->wnd[1] = 0;
1900 BUF->len[0] = ((
uip_len - UIP_IPH_LEN) >> 8);
1901 BUF->len[1] = ((
uip_len - UIP_IPH_LEN) & 0xff);
1904 BUF->len[1] = (
uip_len & 0xff);
1907 BUF->urgp[0] = BUF->urgp[1] = 0;
1922 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
1924 BUF->ipid[0] = ipid >> 8;
1925 BUF->ipid[1] = ipid & 0xff;
1929 DEBUG_PRINTF(
"uip ip_send_nolen: chkecum 0x%04x\n",
uip_ipchksum());
1935 DEBUG_PRINTF(
"Sending packet with length %d (%d)\n",
uip_len,
1936 (BUF->len[0] << 8) | BUF->len[1]);
1956 uip_htonl(uint32_t val)
1958 return UIP_HTONL(val);
1962 uip_send(
const void *data,
int len)
1965 #define MIN(a,b) ((a) < (b)? (a): (b))
1967 (
int)((
char *)uip_sappdata - (
char *)&uip_buf[
UIP_LLH_LEN + UIP_TCPIP_HLEN]));
1970 if(data != uip_sappdata) {
1971 memcpy(uip_sappdata, (data), uip_slen);
#define UIP_CONNS
The maximum number of simultaneously open TCP connections.
uint16_t uip_udpchksum(void)
Calculate the UDP checksum of the packet in uip_buf and uip_appdata.
struct uip_udp_conn * uip_udp_conn
The current UDP connection.
uint8_t uip_acc32[4]
4-byte array used for the 32-bit sequence number calculations.
uint16_t uip_ipchksum(void)
Calculate the IP header checksum of the packet header in uip_buf.
uip_len
The length of the packet in the uip_buf buffer.
uint8_t sv
Retransmission time-out calculation state variable.
void uip_setipid(uint16_t id)
uIP initialization function.
CCIF uip_lladdr_t uip_lladdr
Host L2 address.
The structure holding the TCP/IP statistics that are gathered if UIP_STATISTICS is set to 1...
uint16_t rport
The remote port number in network byte order.
Representation of a uIP TCP connection.
Header file for the uIP TCP/IP stack.
CCIF void uip_send(const void *data, int len)
Send data on the current connection.
#define UIP_MAXSYNRTX
The maximum number of times a SYN segment should be retransmitted before a connection request should ...
uint8_t nrtx
The number of retransmissions for the last segment sent.
uint16_t uip_chksum(uint16_t *buf, uint16_t len)
Calculate the Internet checksum over a buffer.
#define UIP_RTO
The initial retransmission timeout counted in timer pulses.
CCIF uip_buf_t uip_aligned_buf
Packet buffer for incoming and outgoing packets.
uint16_t mss
Current maximum segment size for the connection.
uint16_t lport
The local TCP port, in network byte order.
#define ICMP6_ECHO_REPLY
Echo reply.
#define NULL
The null pointer.
uint8_t timer
The retransmission timer.
uint16_t len
Length of the data that was previously sent.
#define UIP_MAXRTX
The maximum number of times a segment should be retransmitted before the connection should be aborted...
void uip_log(char *msg)
Print out a uIP log message.
Header file for database of link-local neighbors, used by IPv6 code and to be used by future ...
void uip_listen(uint16_t port)
Start listening to the specified port.
uint16_t lport
The local port number in network byte order.
#define UIP_BUFSIZE
The size of the uIP packet buffer.
struct uip_conn * uip_connect(uip_ipaddr_t *ripaddr, uint16_t port)
Connect to a remote host using TCP.
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
webserver_log_file & uip_conn
Pointer to the current TCP connection.
#define UIP_TIME_WAIT_TIMEOUT
How long a connection should stay in the TIME_WAIT state.
#define UIP_STAT(s)
The uIP TCP/IP statistics.
uip_ipaddr_t ripaddr
The IP address of the remote peer.
uint16_t uip_tcpchksum(void)
Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
void uip_unlisten(uint16_t port)
Stop listening to the specified port.
#define UIP_LLH_LEN
The link level header length.
uint16_t rport
The local remote TCP port, in network byte order.
Macros and definitions for the ARP module.
#define UIP_LISTENPORTS
The maximum number of simultaneously listening TCP ports.
uint16_t uip_icmp6chksum(void)
Calculate the ICMP checksum of the packet in uip_buf.
uint8_t rcv_nxt[4]
The sequence number that we expect to receive next.
Configuration options for uIP.
uint8_t rto
Retransmission time-out.
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
uint16_t initialmss
Initial maximum segment size for the connection.
CCIF uint16_t uip_htons(uint16_t val)
Convert a 16-bit quantity from host byte order to network byte order.
void uip_init(void)
uIP initialization function.
void uip_add32(uint8_t *op32, uint16_t op16)
Carry out a 32-bit addition.
uint8_t tcpstateflags
TCP state and flags.
uint8_t sa
Retransmission time-out calculation state variable.
#define UIP_REASS_MAXAGE
The maximum time an IP fragment should wait in the reassembly buffer before it is dropped...
uint8_t snd_nxt[4]
The sequence number that was last sent by us.
void uip_process(uint8_t flag)
process the options within a hop by hop or destination option header
#define UIP_UDP_CONNS
The maximum amount of concurrent UDP connections.
#define UIP_TTL
The IP TTL (time to live) of IP packets sent by uIP.
struct uip_udp_conn * uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport)
Set up a new UDP connection.
uip_ipaddr_t ripaddr
The IP address of the remote host.
Representation of a uIP UDP connection.
#define UIP_APPCALL
The name of the application function that uIP should call in response to TCP/IP events.
#define UIP_RECEIVE_WINDOW
The size of the advertised receiver's window.
#define UIP_TCP_MSS
The TCP maximum segment size.
Declarations of architecture specific functions.
uip_appdata
Pointer to the application data in the packet buffer.
uint8_t ttl
Default time-to-live.