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);
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;
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 *
162 u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags);
169 seg->flags = optflags;
172 seg->len =
p->tot_len - optlen;
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;
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)
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;
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;
451 oversize_used = oversize <
len ? oversize :
len;
452 pos += oversize_used;
453 oversize -= oversize_used;
454 space -= oversize_used;
467 if ((
pos <
len) && (
space > 0) && (last_unsent->len > 0)) {
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;
527#if TCP_CHECKSUM_ON_COPY
529 u8_t chksum_swapped = 0;
532 if (apiflags & TCP_WRITE_FLAG_COPY) {
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
580 if ((queuelen >
TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
589#if TCP_OVERSIZE_DBGCHECK
590 seg->oversize_left = oversize;
592#if TCP_CHECKSUM_ON_COPY
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) {
630 p->tot_len += oversize_used;
631 if (
p->next ==
NULL) {
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",
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;
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) +
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;
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
#define LWIP_MEM_ALIGN_SIZE(size)
#define snmp_inc_tcpoutsegs()
#define snmp_inc_tcpoutrsts()
#define snmp_inc_tcpretranssegs()
GLuint GLsizei GLsizei * length
GLenum GLuint GLint GLint layer
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
static u32_t chksum(void *dataptr, u16_t len)
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)
#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)
int const JOCTET unsigned int datalen
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)
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)
struct pbuf * tcp_create_segment(ip_addr_t *src_ip, ip_addr_t *dst_ip, u16_t src_port, u16_t dst_port, void *data, size_t data_len, u32_t seqno, u32_t ackno, u8_t headerflags)
void tcp_send_fin(struct sock *sk)