49#include "lwip/ip_addr.h"
54#if LWIP_TCP_TIMESTAMPS
62#if TCP_CHECKSUM_ON_COPY
63#define TCP_DATA_COPY(dst, src, len, seg) do { \
64 tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \
65 len, &seg->chksum, &seg->chksum_swapped); \
66 seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0)
67#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) \
68 tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped);
70#define TCP_DATA_COPY(dst, src, len, seg) MEMCPY(dst, src, len)
71#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len)
76#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK
77#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 0
81static void tcp_output_segment(
struct tcp_seg *seg,
struct tcp_pcb *pcb);
94tcp_output_alloc_header(
struct tcp_pcb *pcb,
u16_t optlen,
u16_t datalen,
100 LWIP_ASSERT(
"check that first pbuf can hold struct tcp_hdr",
101 (p->
len >= TCP_HLEN + optlen));
107 TCPH_HDRLEN_FLAGS_SET(
tcphdr, (5 + optlen / 4), TCP_ACK);
113 pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
125tcp_send_fin(
struct tcp_pcb *pcb)
128 if (pcb->unsent !=
NULL) {
129 struct tcp_seg *last_unsent;
130 for (last_unsent = pcb->unsent; last_unsent->next !=
NULL;
131 last_unsent = last_unsent->next);
133 if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) {
135 TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN);
136 pcb->flags |= TF_FIN;
141 return tcp_enqueue_flags(pcb, TCP_FIN);
158static struct tcp_seg *
159tcp_create_segment(
struct tcp_pcb *pcb,
struct pbuf *p,
u8_t flags,
u32_t seqno,
u8_t optflags)
162 u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags);
169 seg->flags = optflags;
173#if TCP_OVERSIZE_DBGCHECK
174 seg->oversize_left = 0;
176#if TCP_CHECKSUM_ON_COPY
178 seg->chksum_swapped = 0;
180 LWIP_ASSERT(
"invalid optflags passed: TF_SEG_DATA_CHECKSUMMED",
181 (optflags & TF_SEG_DATA_CHECKSUMMED) == 0);
191 seg->tcphdr = (
struct tcp_hdr *)seg->p->payload;
192 seg->tcphdr->src =
htons(pcb->local_port);
193 seg->tcphdr->dest =
htons(pcb->remote_port);
194 seg->tcphdr->seqno =
htonl(seqno);
196 TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), flags);
198 seg->tcphdr->urgp = 0;
220 u16_t *oversize,
struct tcp_pcb *pcb,
u8_t apiflags,
226#if LWIP_NETIF_TX_SINGLE_PBUF
234 if (
length < max_length) {
246 if ((apiflags & TCP_WRITE_FLAG_MORE) ||
247 (!(pcb->flags & TF_NODELAY) &&
249 pcb->unsent !=
NULL ||
250 pcb->unacked !=
NULL))) {
266#define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM)
269#if TCP_CHECKSUM_ON_COPY
273 u8_t *seg_chksum_swapped)
277 helper = chksum + *seg_chksum;
279 if ((
len & 1) != 0) {
280 *seg_chksum_swapped = 1 - *seg_chksum_swapped;
283 *seg_chksum = chksum;
294tcp_write_checks(
struct tcp_pcb *pcb,
u16_t len)
297 if ((pcb->state != ESTABLISHED) &&
298 (pcb->state != CLOSE_WAIT) &&
299 (pcb->state != SYN_SENT) &&
300 (pcb->state != SYN_RCVD)) {
303 }
else if (
len == 0) {
308 if (
len > pcb->snd_buf) {
311 pcb->flags |= TF_NAGLEMEMERR;
320 if ((pcb->snd_queuelen >=
TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
324 pcb->flags |= TF_NAGLEMEMERR;
327 if (pcb->snd_queuelen != 0) {
328 LWIP_ASSERT(
"tcp_write: pbufs on queue => at least one queue non-empty",
329 pcb->unacked !=
NULL || pcb->unsent !=
NULL);
331 LWIP_ASSERT(
"tcp_write: no pbufs on queue => both queues empty",
332 pcb->unacked ==
NULL && pcb->unsent ==
NULL);
354tcp_write(
struct tcp_pcb *pcb,
const void *arg,
u16_t len,
u8_t apiflags)
357 struct tcp_seg *last_unsent =
NULL, *seg =
NULL, *prev_seg =
NULL, *queue =
NULL;
364 u16_t oversize_used = 0;
366#if TCP_CHECKSUM_ON_COPY
367 u16_t concat_chksum = 0;
368 u8_t concat_chksum_swapped = 0;
369 u16_t concat_chksummed = 0;
375#if LWIP_NETIF_TX_SINGLE_PBUF
377 apiflags |= TCP_WRITE_FLAG_COPY;
381 (
void *)pcb, arg, len, (
u16_t)apiflags));
382 LWIP_ERROR(
"tcp_write: arg == NULL (programmer violates API)",
385 err = tcp_write_checks(pcb, len);
389 queuelen = pcb->snd_queuelen;
391#if LWIP_TCP_TIMESTAMPS
392 if ((pcb->flags & TF_TIMESTAMP)) {
393 optflags = TF_SEG_OPTS_TS;
394 optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
422 if (pcb->unsent !=
NULL) {
427 for (last_unsent = pcb->unsent; last_unsent->next !=
NULL;
428 last_unsent = last_unsent->next);
431 unsent_optlen = LWIP_TCP_OPT_LENGTH(last_unsent->flags);
432 space = mss_local - (last_unsent->len + unsent_optlen);
442#if TCP_OVERSIZE_DBGCHECK
444 LWIP_ASSERT(
"unsent_oversize mismatch (pcb vs. last_unsent)",
445 pcb->unsent_oversize == last_unsent->oversize_left);
447 oversize = pcb->unsent_oversize;
449 LWIP_ASSERT(
"inconsistent oversize vs. space", oversize_used <= space);
451 oversize_used = oversize < len ? oversize : len;
452 pos += oversize_used;
453 oversize -= oversize_used;
454 space -= oversize_used;
457 LWIP_ASSERT(
"inconsistend oversize vs. len", (oversize == 0) || (pos == len));
467 if ((pos < len) && (space > 0) && (last_unsent->len > 0)) {
468 u16_t seglen = space < len - pos ? space : len - pos;
474 if (apiflags & TCP_WRITE_FLAG_COPY) {
476 if ((concat_p = tcp_pbuf_prealloc(
PBUF_RAW, seglen, space, &oversize, pcb, apiflags, 1)) ==
NULL) {
478 (
"tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n",
482#if TCP_OVERSIZE_DBGCHECK
483 last_unsent->oversize_left += oversize;
485 TCP_DATA_COPY2(concat_p->
payload, (
u8_t*)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped);
486#if TCP_CHECKSUM_ON_COPY
487 concat_chksummed += seglen;
493 (
"tcp_write: could not allocate memory for zero-copy pbuf\n"));
496#if TCP_CHECKSUM_ON_COPY
499 &concat_chksum, &concat_chksum_swapped);
500 concat_chksummed += seglen;
511 LWIP_ASSERT(
"unsent_oversize mismatch (pcb->unsent is NULL)",
512 pcb->unsent_oversize == 0);
525 u16_t max_len = mss_local - optlen;
526 u16_t seglen = left > max_len ? max_len : left;
527#if TCP_CHECKSUM_ON_COPY
529 u8_t chksum_swapped = 0;
532 if (apiflags & TCP_WRITE_FLAG_COPY) {
535 if ((p = tcp_pbuf_prealloc(
PBUF_TRANSPORT, seglen + optlen, mss_local, &oversize, pcb, apiflags, queue ==
NULL)) ==
NULL) {
539 LWIP_ASSERT(
"tcp_write: check that first pbuf can hold the complete seglen",
541 TCP_DATA_COPY2((
char *)p->
payload + optlen, (
u8_t*)arg + pos, seglen, &chksum, &chksum_swapped);
556#if TCP_CHECKSUM_ON_COPY
558 chksum = ~inet_chksum((
u8_t*)arg + pos, seglen);
580 if ((queuelen >
TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
586 if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) ==
NULL) {
589#if TCP_OVERSIZE_DBGCHECK
590 seg->oversize_left = oversize;
592#if TCP_CHECKSUM_ON_COPY
593 seg->chksum = chksum;
594 seg->chksum_swapped = chksum_swapped;
595 seg->flags |= TF_SEG_DATA_CHECKSUMMED;
604 prev_seg->next = seg;
610 ntohl(seg->tcphdr->seqno),
611 ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg)));
626 if (oversize_used > 0) {
629 for (p = last_unsent->p; p; p = p->
next) {
632 TCP_DATA_COPY((
char *)p->
payload + p->
len, arg, oversize_used, last_unsent);
633 p->
len += oversize_used;
636 last_unsent->len += oversize_used;
637#if TCP_OVERSIZE_DBGCHECK
638 LWIP_ASSERT(
"last_unsent->oversize_left >= oversize_used",
639 last_unsent->oversize_left >= oversize_used);
640 last_unsent->oversize_left -= oversize_used;
643 pcb->unsent_oversize = oversize;
649 if (concat_p !=
NULL) {
650 LWIP_ASSERT(
"tcp_write: cannot concatenate when pcb->unsent is empty",
651 (last_unsent !=
NULL));
653 last_unsent->len += concat_p->
tot_len;
654#if TCP_CHECKSUM_ON_COPY
655 if (concat_chksummed) {
656 tcp_seg_add_chksum(concat_chksum, concat_chksummed, &last_unsent->chksum,
657 &last_unsent->chksum_swapped);
658 last_unsent->flags |= TF_SEG_DATA_CHECKSUMMED;
667 if (last_unsent ==
NULL) {
670 last_unsent->next = queue;
678 pcb->snd_queuelen = queuelen;
682 if (pcb->snd_queuelen != 0) {
684 pcb->unacked !=
NULL || pcb->unsent !=
NULL);
688 if (seg !=
NULL && seg->tcphdr !=
NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) {
689 TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
694 pcb->flags |= TF_NAGLEMEMERR;
697 if (concat_p !=
NULL) {
701 tcp_segs_free(queue);
703 if (pcb->snd_queuelen != 0) {
705 pcb->unsent !=
NULL);
722tcp_enqueue_flags(
struct tcp_pcb *pcb,
u8_t flags)
731 LWIP_ASSERT(
"tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)",
732 (flags & (TCP_SYN | TCP_FIN)) != 0);
735 if ((pcb->snd_queuelen >=
TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
739 pcb->flags |= TF_NAGLEMEMERR;
743 if (flags & TCP_SYN) {
744 optflags = TF_SEG_OPTS_MSS;
746#if LWIP_TCP_TIMESTAMPS
747 if ((pcb->flags & TF_TIMESTAMP)) {
748 optflags |= TF_SEG_OPTS_TS;
751 optlen = LWIP_TCP_OPT_LENGTH(optflags);
757 if (pcb->snd_buf == 0) {
765 pcb->flags |= TF_NAGLEMEMERR;
769 LWIP_ASSERT(
"tcp_enqueue_flags: check that first pbuf can hold optlen",
773 if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) ==
NULL) {
774 pcb->flags |= TF_NAGLEMEMERR;
779 LWIP_ASSERT(
"tcp_enqueue_flags: invalid segment length", seg->len == 0);
783 ntohl(seg->tcphdr->seqno),
784 ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
788 if (pcb->unsent ==
NULL) {
791 struct tcp_seg *useg;
792 for (useg = pcb->unsent; useg->next !=
NULL; useg = useg->next);
797 pcb->unsent_oversize = 0;
801 if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
806 if (flags & TCP_FIN) {
807 pcb->flags |= TF_FIN;
813 if (pcb->snd_queuelen != 0) {
814 LWIP_ASSERT(
"tcp_enqueue_flags: invalid queue length",
815 pcb->unacked !=
NULL || pcb->unsent !=
NULL);
821#if LWIP_TCP_TIMESTAMPS
828tcp_build_timestamp_option(
struct tcp_pcb *pcb,
u32_t *opts)
833 opts[2] =
htonl(pcb->ts_recent);
842tcp_send_empty_ack(
struct tcp_pcb *pcb)
848#if LWIP_TCP_TIMESTAMPS
849 if (pcb->flags & TF_TIMESTAMP) {
850 optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
854 p = tcp_output_alloc_header(pcb, optlen, 0,
htonl(pcb->snd_nxt));
861 (
"tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
863 pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
866#if LWIP_TCP_TIMESTAMPS
867 pcb->ts_lastacksent = pcb->rcv_nxt;
869 if (pcb->flags & TF_TIMESTAMP) {
870 tcp_build_timestamp_option(pcb, (
u32_t *)(
tcphdr + 1));
878#if LWIP_NETIF_HWADDRHINT
879 ip_output_hinted(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
882 ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
898tcp_output(
struct tcp_pcb *pcb)
900 struct tcp_seg *seg, *useg;
907 LWIP_ASSERT(
"don't call tcp_output for listen-pcbs",
908 pcb->state != LISTEN);
914 if (tcp_input_pcb == pcb) {
918 wnd =
LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
928 if (pcb->flags & TF_ACK_NOW &&
930 ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
931 return tcp_send_empty_ack(pcb);
937 for (; useg->next !=
NULL; useg = useg->next);
943 (
void*)pcb->unsent));
950 ", seg == NULL, ack %"U32_F"\n",
951 pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack));
956 pcb->snd_wnd, pcb->cwnd, wnd,
957 ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
958 ntohl(seg->tcphdr->seqno), pcb->lastack));
962 while (seg !=
NULL &&
963 ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
965 (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0);
973 if((tcp_do_output_nagle(pcb) == 0) &&
974 ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){
979 pcb->snd_wnd, pcb->cwnd, wnd,
980 ntohl(seg->tcphdr->seqno) + seg->len -
982 ntohl(seg->tcphdr->seqno), pcb->lastack, i));
986 pcb->unsent = seg->next;
988 if (pcb->state != SYN_SENT) {
989 TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
990 pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
993 tcp_output_segment(seg, pcb);
994 snd_nxt =
ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
995 if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
996 pcb->snd_nxt = snd_nxt;
999 if (TCP_TCPLEN(seg) > 0) {
1002 if (pcb->unacked ==
NULL) {
1010 if (TCP_SEQ_LT(
ntohl(seg->tcphdr->seqno),
ntohl(useg->tcphdr->seqno))) {
1012 struct tcp_seg **cur_seg = &(pcb->unacked);
1014 TCP_SEQ_LT(
ntohl((*cur_seg)->tcphdr->seqno),
ntohl(seg->tcphdr->seqno))) {
1015 cur_seg = &((*cur_seg)->next );
1017 seg->next = (*cur_seg);
1032 if (pcb->unsent ==
NULL) {
1034 pcb->unsent_oversize = 0;
1038 pcb->flags &= ~TF_NAGLEMEMERR;
1049tcp_output_segment(
struct tcp_seg *seg,
struct tcp_pcb *pcb)
1060 seg->tcphdr->ackno =
htonl(pcb->rcv_nxt);
1063 seg->tcphdr->wnd =
htons(pcb->rcv_ann_wnd);
1065 pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
1069 opts = (
u32_t *)(
void *)(seg->tcphdr + 1);
1070 if (seg->flags & TF_SEG_OPTS_MSS) {
1072#if TCP_CALCULATE_EFF_SEND_MSS
1073 mss = tcp_eff_send_mss(
TCP_MSS, &pcb->remote_ip);
1077 *opts = TCP_BUILD_MSS_OPTION(mss);
1080#if LWIP_TCP_TIMESTAMPS
1081 pcb->ts_lastacksent = pcb->rcv_nxt;
1083 if (seg->flags & TF_SEG_OPTS_TS) {
1084 tcp_build_timestamp_option(pcb, opts);
1091 if (pcb->rtime == -1) {
1105 if (pcb->rttest == 0) {
1106 pcb->rttest = tcp_ticks;
1107 pcb->rtseq =
ntohl(seg->tcphdr->seqno);
1112 htonl(seg->tcphdr->seqno),
htonl(seg->tcphdr->seqno) +
1115 len = (
u16_t)((
u8_t *)seg->tcphdr - (
u8_t *)seg->p->payload);
1118 seg->p->tot_len -= len;
1120 seg->p->payload = seg->tcphdr;
1122 seg->tcphdr->chksum = 0;
1124#if TCP_CHECKSUM_ON_COPY
1127#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
1132 if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) {
1134 seg->p->tot_len == (TCPH_HDRLEN(seg->tcphdr) * 4));
1140 IP_PROTO_TCP, seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4);
1142 if (seg->chksum_swapped) {
1144 seg->chksum_swapped = 0;
1146 acc += (
u16_t)~(seg->chksum);
1148#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
1149 if (chksum_slow != seg->tcphdr->chksum) {
1151 (
"tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n",
1152 seg->tcphdr->chksum, chksum_slow));
1153 seg->tcphdr->chksum = chksum_slow;
1165#if LWIP_NETIF_HWADDRHINT
1166 ip_output_hinted(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
1169 ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
1206 LWIP_ASSERT(
"check that first pbuf can hold struct tcp_hdr",
1207 (p->
len >=
sizeof(
struct tcp_hdr)));
1214 TCPH_HDRLEN_FLAGS_SET(
tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK);
1239tcp_rexmit_rto(
struct tcp_pcb *pcb)
1241 struct tcp_seg *seg;
1243 if (pcb->unacked ==
NULL) {
1248 for (seg = pcb->unacked; seg->next !=
NULL; seg = seg->next);
1250 seg->next = pcb->unsent;
1252 pcb->unsent = pcb->unacked;
1254 pcb->unacked =
NULL;
1275tcp_rexmit(
struct tcp_pcb *pcb)
1277 struct tcp_seg *seg;
1278 struct tcp_seg **cur_seg;
1280 if (pcb->unacked ==
NULL) {
1287 pcb->unacked = seg->next;
1289 cur_seg = &(pcb->unsent);
1291 TCP_SEQ_LT(
ntohl((*cur_seg)->tcphdr->seqno),
ntohl(seg->tcphdr->seqno))) {
1292 cur_seg = &((*cur_seg)->next );
1294 seg->next = *cur_seg;
1297 if (seg->next ==
NULL) {
1299 pcb->unsent_oversize = 0;
1321tcp_rexmit_fast(
struct tcp_pcb *pcb)
1323 if (pcb->unacked !=
NULL && !(pcb->flags & TF_INFR)) {
1327 "), fast retransmit %"U32_F"\n",
1328 (
u16_t)pcb->dupacks, pcb->lastack,
1329 ntohl(pcb->unacked->tcphdr->seqno)));
1334 if (pcb->cwnd > pcb->snd_wnd) {
1335 pcb->ssthresh = pcb->snd_wnd / 2;
1337 pcb->ssthresh = pcb->cwnd / 2;
1341 if (pcb->ssthresh < 2*pcb->mss) {
1343 (
"tcp_receive: The minimum value for ssthresh %"U16_F
1344 " should be min 2 mss %"U16_F"...\n",
1345 pcb->ssthresh, 2*pcb->mss));
1346 pcb->ssthresh = 2*pcb->mss;
1349 pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
1350 pcb->flags |= TF_INFR;
1364tcp_keepalive(
struct tcp_pcb *pcb)
1374 tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
1376 p = tcp_output_alloc_header(pcb, 0, 0,
htonl(pcb->snd_nxt - 1));
1379 (
"tcp_keepalive: could not allocate memory for pbuf\n"));
1391#if LWIP_NETIF_HWADDRHINT
1392 ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0,
IP_PROTO_TCP,
1401 pcb->snd_nxt - 1, pcb->rcv_nxt));
1414tcp_zero_window_probe(
struct tcp_pcb *pcb)
1418 struct tcp_seg *seg;
1423 (
"tcp_zero_window_probe: sending ZERO WINDOW probe to %"
1429 (
"tcp_zero_window_probe: tcp_ticks %"U32_F
1430 " pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
1431 tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
1442 is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0);
1444 len = is_fin ? 0 : 1;
1446 p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno);
1455 TCPH_FLAGS_SET(
tcphdr, TCP_ACK | TCP_FIN);
1458 char *d = ((
char *)p->
payload + TCP_HLEN);
1472#if LWIP_NETIF_HWADDRHINT
1473 ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0,
IP_PROTO_TCP,
1482 " ackno %"U32_F".\n",
1483 pcb->snd_nxt - 1, pcb->rcv_nxt));
#define LWIP_UNUSED_ARG(x)
#define LWIP_DEBUGF(debug, message)
#define LWIP_DBG_LEVEL_WARNING
#define LWIP_ERROR(message, expression, handler)
#define LWIP_ASSERT(message, assertion)
#define LWIP_DBG_LEVEL_SEVERE
u16_t inet_chksum_pseudo(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t proto, u16_t proto_len)
u16_t inet_chksum(void *dataptr, u16_t len)
u16_t inet_chksum_pseudo_partial(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t proto, u16_t proto_len, u16_t chksum_len)
#define SWAP_BYTES_IN_WORD(w)
err_t ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto)
struct netif * ip_route(ip_addr_t *dest)
#define ip_addr_isany(addr1)
#define ip4_addr1_16(ipaddr)
#define ip4_addr2_16(ipaddr)
#define ip_addr_copy(dest, src)
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
#define ip4_addr3_16(ipaddr)
#define ip4_addr4_16(ipaddr)
#define LWIP_MEM_ALIGN_SIZE(size)
void * memp_malloc(memp_t type)
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
void pbuf_cat(struct pbuf *h, struct pbuf *t)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u8_t pbuf_clen(struct pbuf *p)
u16_t pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
u8_t pbuf_free(struct pbuf *p)
#define snmp_inc_tcpoutsegs()
#define snmp_inc_tcpoutrsts()
#define snmp_inc_tcpretranssegs()