pbuf.c 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351
  1. /**
  2. * @file
  3. * Packet buffer management
  4. *
  5. * Packets are built from the pbuf data structure. It supports dynamic
  6. * memory allocation for packet contents or can reference externally
  7. * managed packet contents both in RAM and ROM. Quick allocation for
  8. * incoming packets is provided through pools with fixed sized pbufs.
  9. *
  10. * A packet may span over multiple pbufs, chained as a singly linked
  11. * list. This is called a "pbuf chain".
  12. *
  13. * Multiple packets may be queued, also using this singly linked list.
  14. * This is called a "packet queue".
  15. *
  16. * So, a packet queue consists of one or more pbuf chains, each of
  17. * which consist of one or more pbufs. CURRENTLY, PACKET QUEUES ARE
  18. * NOT SUPPORTED!!! Use helper structs to queue multiple packets.
  19. *
  20. * The differences between a pbuf chain and a packet queue are very
  21. * precise but subtle.
  22. *
  23. * The last pbuf of a packet has a ->tot_len field that equals the
  24. * ->len field. It can be found by traversing the list. If the last
  25. * pbuf of a packet has a ->next field other than NULL, more packets
  26. * are on the queue.
  27. *
  28. * Therefore, looping through a pbuf of a single packet, has an
  29. * loop end condition (tot_len == p->len), NOT (next == NULL).
  30. */
  31. /*
  32. * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
  33. * All rights reserved.
  34. *
  35. * Redistribution and use in source and binary forms, with or without modification,
  36. * are permitted provided that the following conditions are met:
  37. *
  38. * 1. Redistributions of source code must retain the above copyright notice,
  39. * this list of conditions and the following disclaimer.
  40. * 2. Redistributions in binary form must reproduce the above copyright notice,
  41. * this list of conditions and the following disclaimer in the documentation
  42. * and/or other materials provided with the distribution.
  43. * 3. The name of the author may not be used to endorse or promote products
  44. * derived from this software without specific prior written permission.
  45. *
  46. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  47. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  48. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  49. * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  50. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  51. * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  52. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  53. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  54. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  55. * OF SUCH DAMAGE.
  56. *
  57. * This file is part of the lwIP TCP/IP stack.
  58. *
  59. * Author: Adam Dunkels <adam@sics.se>
  60. *
  61. */
  62. #include "lwip/opt.h"
  63. #include "lwip/stats.h"
  64. #include "lwip/def.h"
  65. #include "lwip/mem.h"
  66. #include "lwip/memp.h"
  67. #include "lwip/pbuf.h"
  68. #include "lwip/sys.h"
  69. #if LWIP_TCP && TCP_QUEUE_OOSEQ
  70. #include "lwip/priv/tcp_priv.h"
  71. #endif
  72. #if LWIP_CHECKSUM_ON_COPY
  73. #include "lwip/inet_chksum.h"
  74. #endif
  75. #include <string.h>
  76. #define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf))
  77. /* Since the pool is created in memp, PBUF_POOL_BUFSIZE will be automatically
  78. aligned there. Therefore, PBUF_POOL_BUFSIZE_ALIGNED can be used here. */
  79. #define PBUF_POOL_BUFSIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE)
  80. #if !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ
  81. #define PBUF_POOL_IS_EMPTY()
  82. #else /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */
  83. #if !NO_SYS
  84. #ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL
  85. #include "lwip/tcpip.h"
  86. #define PBUF_POOL_FREE_OOSEQ_QUEUE_CALL() do { \
  87. if (tcpip_callback_with_block(pbuf_free_ooseq_callback, NULL, 0) != ERR_OK) { \
  88. SYS_ARCH_PROTECT(old_level); \
  89. pbuf_free_ooseq_pending = 0; \
  90. SYS_ARCH_UNPROTECT(old_level); \
  91. } } while(0)
  92. #endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */
  93. #endif /* !NO_SYS */
  94. volatile u8_t pbuf_free_ooseq_pending;
  95. #define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty()
  96. /**
  97. * Attempt to reclaim some memory from queued out-of-sequence TCP segments
  98. * if we run out of pool pbufs. It's better to give priority to new packets
  99. * if we're running out.
  100. *
  101. * This must be done in the correct thread context therefore this function
  102. * can only be used with NO_SYS=0 and through tcpip_callback.
  103. */
  104. #if !NO_SYS
  105. static
  106. #endif /* !NO_SYS */
  107. void
  108. pbuf_free_ooseq(void)
  109. {
  110. struct tcp_pcb* pcb;
  111. SYS_ARCH_SET(pbuf_free_ooseq_pending, 0);
  112. for (pcb = tcp_active_pcbs; NULL != pcb; pcb = pcb->next) {
  113. if (NULL != pcb->ooseq) {
  114. /** Free the ooseq pbufs of one PCB only */
  115. LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free_ooseq: freeing out-of-sequence pbufs\n"));
  116. tcp_segs_free(pcb->ooseq);
  117. pcb->ooseq = NULL;
  118. return;
  119. }
  120. }
  121. }
  122. #if !NO_SYS
  123. /**
  124. * Just a callback function for tcpip_callback() that calls pbuf_free_ooseq().
  125. */
  126. static void
  127. pbuf_free_ooseq_callback(void *arg)
  128. {
  129. LWIP_UNUSED_ARG(arg);
  130. pbuf_free_ooseq();
  131. }
  132. #endif /* !NO_SYS */
  133. /** Queue a call to pbuf_free_ooseq if not already queued. */
  134. static void
  135. pbuf_pool_is_empty(void)
  136. {
  137. #ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL
  138. SYS_ARCH_SET(pbuf_free_ooseq_pending, 1);
  139. #else /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */
  140. u8_t queued;
  141. SYS_ARCH_DECL_PROTECT(old_level);
  142. SYS_ARCH_PROTECT(old_level);
  143. queued = pbuf_free_ooseq_pending;
  144. pbuf_free_ooseq_pending = 1;
  145. SYS_ARCH_UNPROTECT(old_level);
  146. if (!queued) {
  147. /* queue a call to pbuf_free_ooseq if not already queued */
  148. PBUF_POOL_FREE_OOSEQ_QUEUE_CALL();
  149. }
  150. #endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */
  151. }
  152. #endif /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */
  153. /**
  154. * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type).
  155. *
  156. * The actual memory allocated for the pbuf is determined by the
  157. * layer at which the pbuf is allocated and the requested size
  158. * (from the size parameter).
  159. *
  160. * @param layer flag to define header size
  161. * @param length size of the pbuf's payload
  162. * @param type this parameter decides how and where the pbuf
  163. * should be allocated as follows:
  164. *
  165. * - PBUF_RAM: buffer memory for pbuf is allocated as one large
  166. * chunk. This includes protocol headers as well.
  167. * - PBUF_ROM: no buffer memory is allocated for the pbuf, even for
  168. * protocol headers. Additional headers must be prepended
  169. * by allocating another pbuf and chain in to the front of
  170. * the ROM pbuf. It is assumed that the memory used is really
  171. * similar to ROM in that it is immutable and will not be
  172. * changed. Memory which is dynamic should generally not
  173. * be attached to PBUF_ROM pbufs. Use PBUF_REF instead.
  174. * - PBUF_REF: no buffer memory is allocated for the pbuf, even for
  175. * protocol headers. It is assumed that the pbuf is only
  176. * being used in a single thread. If the pbuf gets queued,
  177. * then pbuf_take should be called to copy the buffer.
  178. * - PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from
  179. * the pbuf pool that is allocated during pbuf_init().
  180. *
  181. * @return the allocated pbuf. If multiple pbufs where allocated, this
  182. * is the first pbuf of a pbuf chain.
  183. */
  184. struct pbuf *
  185. pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
  186. {
  187. struct pbuf *p, *q, *r;
  188. u16_t offset = 0;
  189. s32_t rem_len; /* remaining length */
  190. LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length));
  191. /* determine header offset */
  192. switch (layer) {
  193. case PBUF_TRANSPORT:
  194. /* add room for transport (often TCP) layer header */
  195. offset = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN;
  196. break;
  197. case PBUF_IP:
  198. /* add room for IP layer header */
  199. offset = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN;
  200. break;
  201. case PBUF_LINK:
  202. /* add room for link layer header */
  203. offset = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN;
  204. break;
  205. case PBUF_RAW_TX:
  206. /* add room for encapsulating link layer headers (e.g. 802.11) */
  207. offset = PBUF_LINK_ENCAPSULATION_HLEN;
  208. break;
  209. case PBUF_RAW:
  210. offset = 0;
  211. break;
  212. default:
  213. LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0);
  214. return NULL;
  215. }
  216. switch (type) {
  217. case PBUF_POOL:
  218. /* allocate head of pbuf chain into p */
  219. p = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL);
  220. LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc: allocated pbuf %p\n", (void *)p));
  221. if (p == NULL) {
  222. PBUF_POOL_IS_EMPTY();
  223. return NULL;
  224. }
  225. p->type = type;
  226. p->next = NULL;
  227. /* make the payload pointer point 'offset' bytes into pbuf data memory */
  228. p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + (SIZEOF_STRUCT_PBUF + offset)));
  229. LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned",
  230. ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
  231. /* the total length of the pbuf chain is the requested size */
  232. p->tot_len = length;
  233. /* set the length of the first pbuf in the chain */
  234. p->len = LWIP_MIN(length, PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset));
  235. LWIP_ASSERT("check p->payload + p->len does not overflow pbuf",
  236. ((u8_t*)p->payload + p->len <=
  237. (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED));
  238. LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT",
  239. (PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)) > 0 );
  240. /* set reference count (needed here in case we fail) */
  241. p->ref = 1;
  242. /* now allocate the tail of the pbuf chain */
  243. /* remember first pbuf for linkage in next iteration */
  244. r = p;
  245. /* remaining length to be allocated */
  246. rem_len = length - p->len;
  247. /* any remaining pbufs to be allocated? */
  248. while (rem_len > 0) {
  249. q = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL);
  250. if (q == NULL) {
  251. PBUF_POOL_IS_EMPTY();
  252. /* free chain so far allocated */
  253. pbuf_free(p);
  254. /* bail out unsuccessfully */
  255. return NULL;
  256. }
  257. q->type = type;
  258. q->flags = 0;
  259. q->next = NULL;
  260. /* make previous pbuf point to this pbuf */
  261. r->next = q;
  262. /* set total length of this pbuf and next in chain */
  263. LWIP_ASSERT("rem_len < max_u16_t", rem_len < 0xffff);
  264. q->tot_len = (u16_t)rem_len;
  265. /* this pbuf length is pool size, unless smaller sized tail */
  266. q->len = LWIP_MIN((u16_t)rem_len, PBUF_POOL_BUFSIZE_ALIGNED);
  267. q->payload = (void *)((u8_t *)q + SIZEOF_STRUCT_PBUF);
  268. LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned",
  269. ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0);
  270. LWIP_ASSERT("check p->payload + p->len does not overflow pbuf",
  271. ((u8_t*)p->payload + p->len <=
  272. (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED));
  273. q->ref = 1;
  274. /* calculate remaining length to be allocated */
  275. rem_len -= q->len;
  276. /* remember this pbuf for linkage in next iteration */
  277. r = q;
  278. }
  279. /* end of chain */
  280. /*r->next = NULL;*/
  281. break;
  282. case PBUF_RAM:
  283. /* If pbuf is to be allocated in RAM, allocate memory for it. */
  284. p = (struct pbuf*)mem_malloc(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF + offset) + LWIP_MEM_ALIGN_SIZE(length));
  285. if (p == NULL) {
  286. return NULL;
  287. }
  288. /* Set up internal structure of the pbuf. */
  289. p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset));
  290. p->len = p->tot_len = length;
  291. p->next = NULL;
  292. p->type = type;
  293. LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
  294. ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
  295. break;
  296. /* pbuf references existing (non-volatile static constant) ROM payload? */
  297. case PBUF_ROM:
  298. /* pbuf references existing (externally allocated) RAM payload? */
  299. case PBUF_REF:
  300. /* only allocate memory for the pbuf structure */
  301. p = (struct pbuf *)memp_malloc(MEMP_PBUF);
  302. if (p == NULL) {
  303. LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
  304. ("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n",
  305. (type == PBUF_ROM) ? "ROM" : "REF"));
  306. return NULL;
  307. }
  308. /* caller must set this field properly, afterwards */
  309. p->payload = NULL;
  310. p->len = p->tot_len = length;
  311. p->next = NULL;
  312. p->type = type;
  313. break;
  314. default:
  315. LWIP_ASSERT("pbuf_alloc: erroneous type", 0);
  316. return NULL;
  317. }
  318. /* set reference count */
  319. p->ref = 1;
  320. /* set flags */
  321. p->flags = 0;
  322. #if ESP_LWIP
  323. p->l2_owner = NULL;
  324. p->l2_buf = NULL;
  325. #endif
  326. LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p));
  327. return p;
  328. }
  329. #if LWIP_SUPPORT_CUSTOM_PBUF
  330. /** Initialize a custom pbuf (already allocated).
  331. *
  332. * @param layer flag to define header size
  333. * @param length size of the pbuf's payload
  334. * @param type type of the pbuf (only used to treat the pbuf accordingly, as
  335. * this function allocates no memory)
  336. * @param p pointer to the custom pbuf to initialize (already allocated)
  337. * @param payload_mem pointer to the buffer that is used for payload and headers,
  338. * must be at least big enough to hold 'length' plus the header size,
  339. * may be NULL if set later.
  340. * ATTENTION: The caller is responsible for correct alignment of this buffer!!
  341. * @param payload_mem_len the size of the 'payload_mem' buffer, must be at least
  342. * big enough to hold 'length' plus the header size
  343. */
  344. struct pbuf*
  345. pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_custom *p,
  346. void *payload_mem, u16_t payload_mem_len)
  347. {
  348. u16_t offset;
  349. LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloced_custom(length=%"U16_F")\n", length));
  350. /* determine header offset */
  351. switch (l) {
  352. case PBUF_TRANSPORT:
  353. /* add room for transport (often TCP) layer header */
  354. offset = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN;
  355. break;
  356. case PBUF_IP:
  357. /* add room for IP layer header */
  358. offset = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN;
  359. break;
  360. case PBUF_LINK:
  361. /* add room for link layer header */
  362. offset = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN;
  363. break;
  364. case PBUF_RAW_TX:
  365. /* add room for encapsulating link layer headers (e.g. 802.11) */
  366. offset = PBUF_LINK_ENCAPSULATION_HLEN;
  367. break;
  368. case PBUF_RAW:
  369. offset = 0;
  370. break;
  371. default:
  372. LWIP_ASSERT("pbuf_alloced_custom: bad pbuf layer", 0);
  373. return NULL;
  374. }
  375. if (LWIP_MEM_ALIGN_SIZE(offset) + length > payload_mem_len) {
  376. LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_WARNING, ("pbuf_alloced_custom(length=%"U16_F") buffer too short\n", length));
  377. return NULL;
  378. }
  379. p->pbuf.next = NULL;
  380. if (payload_mem != NULL) {
  381. p->pbuf.payload = (u8_t *)payload_mem + LWIP_MEM_ALIGN_SIZE(offset);
  382. } else {
  383. p->pbuf.payload = NULL;
  384. }
  385. p->pbuf.flags = PBUF_FLAG_IS_CUSTOM;
  386. p->pbuf.len = p->pbuf.tot_len = length;
  387. p->pbuf.type = type;
  388. p->pbuf.ref = 1;
  389. return &p->pbuf;
  390. }
  391. #endif /* LWIP_SUPPORT_CUSTOM_PBUF */
  392. /**
  393. * Shrink a pbuf chain to a desired length.
  394. *
  395. * @param p pbuf to shrink.
  396. * @param new_len desired new length of pbuf chain
  397. *
  398. * Depending on the desired length, the first few pbufs in a chain might
  399. * be skipped and left unchanged. The new last pbuf in the chain will be
  400. * resized, and any remaining pbufs will be freed.
  401. *
  402. * @note If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted.
  403. * @note May not be called on a packet queue.
  404. *
  405. * @note Despite its name, pbuf_realloc cannot grow the size of a pbuf (chain).
  406. */
  407. void
  408. pbuf_realloc(struct pbuf *p, u16_t new_len)
  409. {
  410. struct pbuf *q;
  411. u16_t rem_len; /* remaining length */
  412. s32_t grow;
  413. LWIP_ASSERT("pbuf_realloc: p != NULL", p != NULL);
  414. LWIP_ASSERT("pbuf_realloc: sane p->type", p->type == PBUF_POOL ||
  415. p->type == PBUF_ROM ||
  416. p->type == PBUF_RAM ||
  417. p->type == PBUF_REF);
  418. /* desired length larger than current length? */
  419. if (new_len >= p->tot_len) {
  420. /* enlarging not yet supported */
  421. return;
  422. }
  423. /* the pbuf chain grows by (new_len - p->tot_len) bytes
  424. * (which may be negative in case of shrinking) */
  425. grow = new_len - p->tot_len;
  426. /* first, step over any pbufs that should remain in the chain */
  427. rem_len = new_len;
  428. q = p;
  429. /* should this pbuf be kept? */
  430. while (rem_len > q->len) {
  431. /* decrease remaining length by pbuf length */
  432. rem_len -= q->len;
  433. /* decrease total length indicator */
  434. LWIP_ASSERT("grow < max_u16_t", grow < 0xffff);
  435. q->tot_len += (u16_t)grow;
  436. /* proceed to next pbuf in chain */
  437. q = q->next;
  438. LWIP_ASSERT("pbuf_realloc: q != NULL", q != NULL);
  439. }
  440. /* we have now reached the new last pbuf (in q) */
  441. /* rem_len == desired length for pbuf q */
  442. /* shrink allocated memory for PBUF_RAM */
  443. /* (other types merely adjust their length fields */
  444. if ((q->type == PBUF_RAM) && (rem_len != q->len)
  445. #if LWIP_SUPPORT_CUSTOM_PBUF
  446. && ((q->flags & PBUF_FLAG_IS_CUSTOM) == 0)
  447. #endif /* LWIP_SUPPORT_CUSTOM_PBUF */
  448. ) {
  449. /* reallocate and adjust the length of the pbuf that will be split */
  450. q = (struct pbuf *)mem_trim(q, (u16_t)((u8_t *)q->payload - (u8_t *)q) + rem_len);
  451. LWIP_ASSERT("mem_trim returned q == NULL", q != NULL);
  452. }
  453. /* adjust length fields for new last pbuf */
  454. q->len = rem_len;
  455. q->tot_len = q->len;
  456. /* any remaining pbufs in chain? */
  457. if (q->next != NULL) {
  458. /* free remaining pbufs in chain */
  459. pbuf_free(q->next);
  460. }
  461. /* q is last packet in chain */
  462. q->next = NULL;
  463. }
  464. /**
  465. * Adjusts the payload pointer to hide or reveal headers in the payload.
  466. * @see pbuf_header.
  467. *
  468. * @param p pbuf to change the header size.
  469. * @param header_size_increment Number of bytes to increment header size.
  470. * @param force Allow 'header_size_increment > 0' for PBUF_REF/PBUF_ROM types
  471. *
  472. * @return non-zero on failure, zero on success.
  473. *
  474. */
  475. static u8_t
  476. pbuf_header_impl(struct pbuf *p, s16_t header_size_increment, u8_t force)
  477. {
  478. u16_t type;
  479. void *payload;
  480. u16_t increment_magnitude;
  481. LWIP_ASSERT("p != NULL", p != NULL);
  482. if ((header_size_increment == 0) || (p == NULL)) {
  483. return 0;
  484. }
  485. if (header_size_increment < 0) {
  486. increment_magnitude = -header_size_increment;
  487. /* Check that we aren't going to move off the end of the pbuf */
  488. LWIP_ERROR("increment_magnitude <= p->len", (increment_magnitude <= p->len), return 1;);
  489. } else {
  490. increment_magnitude = header_size_increment;
  491. #if 0
  492. /* Can't assert these as some callers speculatively call
  493. pbuf_header() to see if it's OK. Will return 1 below instead. */
  494. /* Check that we've got the correct type of pbuf to work with */
  495. LWIP_ASSERT("p->type == PBUF_RAM || p->type == PBUF_POOL",
  496. p->type == PBUF_RAM || p->type == PBUF_POOL);
  497. /* Check that we aren't going to move off the beginning of the pbuf */
  498. LWIP_ASSERT("p->payload - increment_magnitude >= p + SIZEOF_STRUCT_PBUF",
  499. (u8_t *)p->payload - increment_magnitude >= (u8_t *)p + SIZEOF_STRUCT_PBUF);
  500. #endif
  501. }
  502. type = p->type;
  503. /* remember current payload pointer */
  504. payload = p->payload;
  505. /* pbuf types containing payloads? */
  506. if (type == PBUF_RAM || type == PBUF_POOL) {
  507. /* set new payload pointer */
  508. p->payload = (u8_t *)p->payload - header_size_increment;
  509. /* boundary check fails? */
  510. if ((u8_t *)p->payload < (u8_t *)p + SIZEOF_STRUCT_PBUF) {
  511. LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
  512. ("pbuf_header: failed as %p < %p (not enough space for new header size)\n",
  513. (void *)p->payload, (void *)(p + 1)));
  514. /* restore old payload pointer */
  515. p->payload = payload;
  516. /* bail out unsuccessfully */
  517. return 1;
  518. }
  519. /* pbuf types referring to external payloads? */
  520. } else if (type == PBUF_REF || type == PBUF_ROM) {
  521. /* hide a header in the payload? */
  522. if ((header_size_increment < 0) && (increment_magnitude <= p->len)) {
  523. /* increase payload pointer */
  524. p->payload = (u8_t *)p->payload - header_size_increment;
  525. } else if ((header_size_increment > 0) && force) {
  526. p->payload = (u8_t *)p->payload - header_size_increment;
  527. } else {
  528. /* cannot expand payload to front (yet!)
  529. * bail out unsuccessfully */
  530. return 1;
  531. }
  532. } else {
  533. /* Unknown type */
  534. LWIP_ASSERT("bad pbuf type", 0);
  535. return 1;
  536. }
  537. /* modify pbuf length fields */
  538. p->len += header_size_increment;
  539. p->tot_len += header_size_increment;
  540. LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_header: old %p new %p (%"S16_F")\n",
  541. (void *)payload, (void *)p->payload, header_size_increment));
  542. return 0;
  543. }
  544. /**
  545. * Adjusts the payload pointer to hide or reveal headers in the payload.
  546. *
  547. * Adjusts the ->payload pointer so that space for a header
  548. * (dis)appears in the pbuf payload.
  549. *
  550. * The ->payload, ->tot_len and ->len fields are adjusted.
  551. *
  552. * @param p pbuf to change the header size.
  553. * @param header_size_increment Number of bytes to increment header size which
  554. * increases the size of the pbuf. New space is on the front.
  555. * (Using a negative value decreases the header size.)
  556. * If hdr_size_inc is 0, this function does nothing and returns successful.
  557. *
  558. * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so
  559. * the call will fail. A check is made that the increase in header size does
  560. * not move the payload pointer in front of the start of the buffer.
  561. * @return non-zero on failure, zero on success.
  562. *
  563. */
  564. u8_t
  565. pbuf_header(struct pbuf *p, s16_t header_size_increment)
  566. {
  567. return pbuf_header_impl(p, header_size_increment, 0);
  568. }
  569. /**
  570. * Same as pbuf_header but does not check if 'header_size > 0' is allowed.
  571. * This is used internally only, to allow PBUF_REF for RX.
  572. */
  573. u8_t
  574. pbuf_header_force(struct pbuf *p, s16_t header_size_increment)
  575. {
  576. return pbuf_header_impl(p, header_size_increment, 1);
  577. }
  578. /**
  579. * Dereference a pbuf chain or queue and deallocate any no-longer-used
  580. * pbufs at the head of this chain or queue.
  581. *
  582. * Decrements the pbuf reference count. If it reaches zero, the pbuf is
  583. * deallocated.
  584. *
  585. * For a pbuf chain, this is repeated for each pbuf in the chain,
  586. * up to the first pbuf which has a non-zero reference count after
  587. * decrementing. So, when all reference counts are one, the whole
  588. * chain is free'd.
  589. *
  590. * @param p The pbuf (chain) to be dereferenced.
  591. *
  592. * @return the number of pbufs that were de-allocated
  593. * from the head of the chain.
  594. *
  595. * @note MUST NOT be called on a packet queue (Not verified to work yet).
  596. * @note the reference counter of a pbuf equals the number of pointers
  597. * that refer to the pbuf (or into the pbuf).
  598. *
  599. * @internal examples:
  600. *
  601. * Assuming existing chains a->b->c with the following reference
  602. * counts, calling pbuf_free(a) results in:
  603. *
  604. * 1->2->3 becomes ...1->3
  605. * 3->3->3 becomes 2->3->3
  606. * 1->1->2 becomes ......1
  607. * 2->1->1 becomes 1->1->1
  608. * 1->1->1 becomes .......
  609. *
  610. */
  611. u8_t
  612. pbuf_free(struct pbuf *p)
  613. {
  614. u16_t type;
  615. struct pbuf *q;
  616. u8_t count;
  617. if (p == NULL) {
  618. LWIP_ASSERT("p != NULL", p != NULL);
  619. /* if assertions are disabled, proceed with debug output */
  620. LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
  621. ("pbuf_free(p == NULL) was called.\n"));
  622. return 0;
  623. }
  624. LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p));
  625. PERF_START;
  626. LWIP_ASSERT("pbuf_free: sane type",
  627. p->type == PBUF_RAM || p->type == PBUF_ROM ||
  628. p->type == PBUF_REF || p->type == PBUF_POOL);
  629. count = 0;
  630. /* de-allocate all consecutive pbufs from the head of the chain that
  631. * obtain a zero reference count after decrementing*/
  632. while (p != NULL) {
  633. u16_t ref;
  634. SYS_ARCH_DECL_PROTECT(old_level);
  635. /* Since decrementing ref cannot be guaranteed to be a single machine operation
  636. * we must protect it. We put the new ref into a local variable to prevent
  637. * further protection. */
  638. SYS_ARCH_PROTECT(old_level);
  639. /* all pbufs in a chain are referenced at least once */
  640. LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0);
  641. /* decrease reference count (number of pointers to pbuf) */
  642. ref = --(p->ref);
  643. SYS_ARCH_UNPROTECT(old_level);
  644. /* this pbuf is no longer referenced to? */
  645. if (ref == 0) {
  646. /* remember next pbuf in chain for next iteration */
  647. q = p->next;
  648. LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: deallocating %p\n", (void *)p));
  649. type = p->type;
  650. #if LWIP_SUPPORT_CUSTOM_PBUF
  651. /* is this a custom pbuf? */
  652. if ((p->flags & PBUF_FLAG_IS_CUSTOM) != 0) {
  653. struct pbuf_custom *pc = (struct pbuf_custom*)p;
  654. LWIP_ASSERT("pc->custom_free_function != NULL", pc->custom_free_function != NULL);
  655. pc->custom_free_function(p);
  656. } else
  657. #endif /* LWIP_SUPPORT_CUSTOM_PBUF */
  658. {
  659. /* is this a pbuf from the pool? */
  660. if (type == PBUF_POOL) {
  661. memp_free(MEMP_PBUF_POOL, p);
  662. /* is this a ROM or RAM referencing pbuf? */
  663. } else if (type == PBUF_ROM || type == PBUF_REF) {
  664. #if ESP_LWIP
  665. if (p->l2_owner != NULL
  666. && p->l2_buf != NULL
  667. && p->l2_owner->l2_buffer_free_notify != NULL) {
  668. p->l2_owner->l2_buffer_free_notify(p->l2_buf);
  669. }
  670. #endif
  671. memp_free(MEMP_PBUF, p);
  672. /* type == PBUF_RAM */
  673. } else {
  674. mem_free(p);
  675. }
  676. }
  677. count++;
  678. /* proceed to next pbuf */
  679. p = q;
  680. /* p->ref > 0, this pbuf is still referenced to */
  681. /* (and so the remaining pbufs in chain as well) */
  682. } else {
  683. LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, ref));
  684. /* stop walking through the chain */
  685. p = NULL;
  686. }
  687. }
  688. PERF_STOP("pbuf_free");
  689. /* return number of de-allocated pbufs */
  690. return count;
  691. }
  692. /**
  693. * Count number of pbufs in a chain
  694. *
  695. * @param p first pbuf of chain
  696. * @return the number of pbufs in a chain
  697. */
  698. u8_t
  699. pbuf_clen(struct pbuf *p)
  700. {
  701. u8_t len;
  702. len = 0;
  703. while (p != NULL) {
  704. ++len;
  705. p = p->next;
  706. }
  707. return len;
  708. }
  709. /**
  710. * Increment the reference count of the pbuf.
  711. *
  712. * @param p pbuf to increase reference counter of
  713. *
  714. */
  715. void
  716. pbuf_ref(struct pbuf *p)
  717. {
  718. SYS_ARCH_DECL_PROTECT(old_level);
  719. /* pbuf given? */
  720. if (p != NULL) {
  721. SYS_ARCH_PROTECT(old_level);
  722. ++(p->ref);
  723. SYS_ARCH_UNPROTECT(old_level);
  724. }
  725. }
  726. /**
  727. * Concatenate two pbufs (each may be a pbuf chain) and take over
  728. * the caller's reference of the tail pbuf.
  729. *
  730. * @note The caller MAY NOT reference the tail pbuf afterwards.
  731. * Use pbuf_chain() for that purpose.
  732. *
  733. * @see pbuf_chain()
  734. */
  735. void
  736. pbuf_cat(struct pbuf *h, struct pbuf *t)
  737. {
  738. struct pbuf *p;
  739. LWIP_ERROR("(h != NULL) && (t != NULL) (programmer violates API)",
  740. ((h != NULL) && (t != NULL)), return;);
  741. /* proceed to last pbuf of chain */
  742. for (p = h; p->next != NULL; p = p->next) {
  743. /* add total length of second chain to all totals of first chain */
  744. p->tot_len += t->tot_len;
  745. }
  746. /* { p is last pbuf of first h chain, p->next == NULL } */
  747. LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len);
  748. LWIP_ASSERT("p->next == NULL", p->next == NULL);
  749. /* add total length of second chain to last pbuf total of first chain */
  750. p->tot_len += t->tot_len;
  751. /* chain last pbuf of head (p) with first of tail (t) */
  752. p->next = t;
  753. /* p->next now references t, but the caller will drop its reference to t,
  754. * so netto there is no change to the reference count of t.
  755. */
  756. }
  757. /**
  758. * Chain two pbufs (or pbuf chains) together.
  759. *
  760. * The caller MUST call pbuf_free(t) once it has stopped
  761. * using it. Use pbuf_cat() instead if you no longer use t.
  762. *
  763. * @param h head pbuf (chain)
  764. * @param t tail pbuf (chain)
  765. * @note The pbufs MUST belong to the same packet.
  766. * @note MAY NOT be called on a packet queue.
  767. *
  768. * The ->tot_len fields of all pbufs of the head chain are adjusted.
  769. * The ->next field of the last pbuf of the head chain is adjusted.
  770. * The ->ref field of the first pbuf of the tail chain is adjusted.
  771. *
  772. */
  773. void
  774. pbuf_chain(struct pbuf *h, struct pbuf *t)
  775. {
  776. pbuf_cat(h, t);
  777. /* t is now referenced by h */
  778. pbuf_ref(t);
  779. LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t));
  780. }
  781. /**
  782. * Dechains the first pbuf from its succeeding pbufs in the chain.
  783. *
  784. * Makes p->tot_len field equal to p->len.
  785. * @param p pbuf to dechain
  786. * @return remainder of the pbuf chain, or NULL if it was de-allocated.
  787. * @note May not be called on a packet queue.
  788. */
  789. struct pbuf *
  790. pbuf_dechain(struct pbuf *p)
  791. {
  792. struct pbuf *q;
  793. u8_t tail_gone = 1;
  794. /* tail */
  795. q = p->next;
  796. /* pbuf has successor in chain? */
  797. if (q != NULL) {
  798. /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */
  799. LWIP_ASSERT("p->tot_len == p->len + q->tot_len", q->tot_len == p->tot_len - p->len);
  800. /* enforce invariant if assertion is disabled */
  801. q->tot_len = p->tot_len - p->len;
  802. /* decouple pbuf from remainder */
  803. p->next = NULL;
  804. /* total length of pbuf p is its own length only */
  805. p->tot_len = p->len;
  806. /* q is no longer referenced by p, free it */
  807. LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_dechain: unreferencing %p\n", (void *)q));
  808. tail_gone = pbuf_free(q);
  809. if (tail_gone > 0) {
  810. LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE,
  811. ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q));
  812. }
  813. /* return remaining tail or NULL if deallocated */
  814. }
  815. /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */
  816. LWIP_ASSERT("p->tot_len == p->len", p->tot_len == p->len);
  817. return ((tail_gone > 0) ? NULL : q);
  818. }
  819. /**
  820. *
  821. * Create PBUF_RAM copies of pbufs.
  822. *
  823. * Used to queue packets on behalf of the lwIP stack, such as
  824. * ARP based queueing.
  825. *
  826. * @note You MUST explicitly use p = pbuf_take(p);
  827. *
  828. * @note Only one packet is copied, no packet queue!
  829. *
  830. * @param p_to pbuf destination of the copy
  831. * @param p_from pbuf source of the copy
  832. *
  833. * @return ERR_OK if pbuf was copied
  834. * ERR_ARG if one of the pbufs is NULL or p_to is not big
  835. * enough to hold p_from
  836. */
  837. err_t
  838. pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
  839. {
  840. u16_t offset_to=0, offset_from=0, len;
  841. LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n",
  842. (void*)p_to, (void*)p_from));
  843. /* is the target big enough to hold the source? */
  844. LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) &&
  845. (p_from != NULL) && (p_to->tot_len >= p_from->tot_len)), return ERR_ARG;);
  846. /* iterate through pbuf chain */
  847. do
  848. {
  849. /* copy one part of the original chain */
  850. if ((p_to->len - offset_to) >= (p_from->len - offset_from)) {
  851. /* complete current p_from fits into current p_to */
  852. len = p_from->len - offset_from;
  853. } else {
  854. /* current p_from does not fit into current p_to */
  855. len = p_to->len - offset_to;
  856. }
  857. MEMCPY((u8_t*)p_to->payload + offset_to, (u8_t*)p_from->payload + offset_from, len);
  858. offset_to += len;
  859. offset_from += len;
  860. LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len);
  861. LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len);
  862. if (offset_from >= p_from->len) {
  863. /* on to next p_from (if any) */
  864. offset_from = 0;
  865. p_from = p_from->next;
  866. }
  867. if (offset_to == p_to->len) {
  868. /* on to next p_to (if any) */
  869. offset_to = 0;
  870. p_to = p_to->next;
  871. LWIP_ERROR("p_to != NULL", (p_to != NULL) || (p_from == NULL) , return ERR_ARG;);
  872. }
  873. if ((p_from != NULL) && (p_from->len == p_from->tot_len)) {
  874. /* don't copy more than one packet! */
  875. LWIP_ERROR("pbuf_copy() does not allow packet queues!",
  876. (p_from->next == NULL), return ERR_VAL;);
  877. }
  878. if ((p_to != NULL) && (p_to->len == p_to->tot_len)) {
  879. /* don't copy more than one packet! */
  880. LWIP_ERROR("pbuf_copy() does not allow packet queues!",
  881. (p_to->next == NULL), return ERR_VAL;);
  882. }
  883. } while (p_from);
  884. LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n"));
  885. return ERR_OK;
  886. }
  887. /**
  888. * Copy (part of) the contents of a packet buffer
  889. * to an application supplied buffer.
  890. *
  891. * @param buf the pbuf from which to copy data
  892. * @param dataptr the application supplied buffer
  893. * @param len length of data to copy (dataptr must be big enough). No more
  894. * than buf->tot_len will be copied, irrespective of len
  895. * @param offset offset into the packet buffer from where to begin copying len bytes
  896. * @return the number of bytes copied, or 0 on failure
  897. */
  898. u16_t
  899. pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
  900. {
  901. struct pbuf *p;
  902. u16_t left;
  903. u16_t buf_copy_len;
  904. u16_t copied_total = 0;
  905. LWIP_ERROR("pbuf_copy_partial: invalid buf", (buf != NULL), return 0;);
  906. LWIP_ERROR("pbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;);
  907. left = 0;
  908. if ((buf == NULL) || (dataptr == NULL)) {
  909. return 0;
  910. }
  911. /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */
  912. for (p = buf; len != 0 && p != NULL; p = p->next) {
  913. if ((offset != 0) && (offset >= p->len)) {
  914. /* don't copy from this buffer -> on to the next */
  915. offset -= p->len;
  916. } else {
  917. /* copy from this buffer. maybe only partially. */
  918. buf_copy_len = p->len - offset;
  919. if (buf_copy_len > len)
  920. buf_copy_len = len;
  921. /* copy the necessary parts of the buffer */
  922. MEMCPY(&((char*)dataptr)[left], &((char*)p->payload)[offset], buf_copy_len);
  923. copied_total += buf_copy_len;
  924. left += buf_copy_len;
  925. len -= buf_copy_len;
  926. offset = 0;
  927. }
  928. }
  929. return copied_total;
  930. }
  931. #if LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
  932. /**
  933. * This method modifies a 'pbuf chain', so that its total length is
  934. * smaller than 64K. The remainder of the original pbuf chain is stored
  935. * in *rest.
  936. * This function never creates new pbufs, but splits an existing chain
  937. * in two parts. The tot_len of the modified packet queue will likely be
  938. * smaller than 64K.
  939. * 'packet queues' are not supported by this function.
  940. *
  941. * @param p the pbuf queue to be split
  942. * @param rest pointer to store the remainder (after the first 64K)
  943. */
  944. void pbuf_split_64k(struct pbuf *p, struct pbuf **rest)
  945. {
  946. *rest = NULL;
  947. if ((p != NULL) && (p->next != NULL)) {
  948. u16_t tot_len_front = p->len;
  949. struct pbuf *i = p;
  950. struct pbuf *r = p->next;
  951. /* continue until the total length (summed up as u16_t) overflows */
  952. while ((r != NULL) && ((u16_t)(tot_len_front + r->len) > tot_len_front)) {
  953. tot_len_front += r->len;
  954. i = r;
  955. r = r->next;
  956. }
  957. /* i now points to last packet of the first segment. Set next
  958. pointer to NULL */
  959. i->next = NULL;
  960. if (r != NULL) {
  961. /* Update the tot_len field in the first part */
  962. for (i = p; i != NULL; i = i->next) {
  963. i->tot_len -= r->tot_len;
  964. LWIP_ASSERT("tot_len/len mismatch in last pbuf",
  965. (i->next != NULL) || (i->tot_len == i->len));
  966. }
  967. if (p->flags & PBUF_FLAG_TCP_FIN) {
  968. r->flags |= PBUF_FLAG_TCP_FIN;
  969. }
  970. /* tot_len field in rest does not need modifications */
  971. /* reference counters do not need modifications */
  972. *rest = r;
  973. }
  974. }
  975. }
  976. #endif /* LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
  977. /**
  978. * Skip a number of bytes at the start of a pbuf
  979. *
  980. * @param in input pbuf
  981. * @param in_offset offset to skip
  982. * @param out_offset resulting offset in the returned pbuf
  983. * @return the pbuf in the queue where the offset is
  984. */
  985. struct pbuf*
  986. pbuf_skip(struct pbuf* in, u16_t in_offset, u16_t* out_offset)
  987. {
  988. u16_t offset_left = in_offset;
  989. struct pbuf* q = in;
  990. /* get the correct pbuf */
  991. while ((q != NULL) && (q->len <= offset_left)) {
  992. offset_left -= q->len;
  993. q = q->next;
  994. }
  995. if (out_offset != NULL) {
  996. *out_offset = offset_left;
  997. }
  998. return q;
  999. }
  1000. /**
  1001. * Copy application supplied data into a pbuf.
  1002. * This function can only be used to copy the equivalent of buf->tot_len data.
  1003. *
  1004. * @param buf pbuf to fill with data
  1005. * @param dataptr application supplied data buffer
  1006. * @param len length of the application supplied data buffer
  1007. *
  1008. * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough
  1009. */
  1010. err_t
  1011. pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len)
  1012. {
  1013. struct pbuf *p;
  1014. u16_t buf_copy_len;
  1015. u16_t total_copy_len = len;
  1016. u16_t copied_total = 0;
  1017. LWIP_ERROR("pbuf_take: invalid buf", (buf != NULL), return ERR_ARG;);
  1018. LWIP_ERROR("pbuf_take: invalid dataptr", (dataptr != NULL), return ERR_ARG;);
  1019. LWIP_ERROR("pbuf_take: buf not large enough", (buf->tot_len >= len), return ERR_MEM;);
  1020. if ((buf == NULL) || (dataptr == NULL) || (buf->tot_len < len)) {
  1021. return ERR_ARG;
  1022. }
  1023. /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */
  1024. for (p = buf; total_copy_len != 0; p = p->next) {
  1025. LWIP_ASSERT("pbuf_take: invalid pbuf", p != NULL);
  1026. buf_copy_len = total_copy_len;
  1027. if (buf_copy_len > p->len) {
  1028. /* this pbuf cannot hold all remaining data */
  1029. buf_copy_len = p->len;
  1030. }
  1031. /* copy the necessary parts of the buffer */
  1032. MEMCPY(p->payload, &((const char*)dataptr)[copied_total], buf_copy_len);
  1033. total_copy_len -= buf_copy_len;
  1034. copied_total += buf_copy_len;
  1035. }
  1036. LWIP_ASSERT("did not copy all data", total_copy_len == 0 && copied_total == len);
  1037. return ERR_OK;
  1038. }
  1039. /**
  1040. * Same as pbuf_take() but puts data at an offset
  1041. *
  1042. * @param buf pbuf to fill with data
  1043. * @param dataptr application supplied data buffer
  1044. * @param len length of the application supplied data buffer
  1045. *
  1046. * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough
  1047. */
  1048. err_t
  1049. pbuf_take_at(struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset)
  1050. {
  1051. u16_t target_offset;
  1052. struct pbuf* q = pbuf_skip(buf, offset, &target_offset);
  1053. /* return requested data if pbuf is OK */
  1054. if ((q != NULL) && (q->tot_len >= target_offset + len)) {
  1055. u16_t remaining_len = len;
  1056. const u8_t* src_ptr = (const u8_t*)dataptr;
  1057. /* copy the part that goes into the first pbuf */
  1058. u16_t first_copy_len = LWIP_MIN(q->len - target_offset, len);
  1059. MEMCPY(((u8_t*)q->payload) + target_offset, dataptr, first_copy_len);
  1060. remaining_len -= first_copy_len;
  1061. src_ptr += first_copy_len;
  1062. if (remaining_len > 0) {
  1063. return pbuf_take(q->next, src_ptr, remaining_len);
  1064. }
  1065. return ERR_OK;
  1066. }
  1067. return ERR_MEM;
  1068. }
  1069. /**
  1070. * Creates a single pbuf out of a queue of pbufs.
  1071. *
  1072. * @remark: Either the source pbuf 'p' is freed by this function or the original
  1073. * pbuf 'p' is returned, therefore the caller has to check the result!
  1074. *
  1075. * @param p the source pbuf
  1076. * @param layer pbuf_layer of the new pbuf
  1077. *
  1078. * @return a new, single pbuf (p->next is NULL)
  1079. * or the old pbuf if allocation fails
  1080. */
  1081. struct pbuf*
  1082. pbuf_coalesce(struct pbuf *p, pbuf_layer layer)
  1083. {
  1084. struct pbuf *q;
  1085. err_t err;
  1086. if (p->next == NULL) {
  1087. return p;
  1088. }
  1089. q = pbuf_alloc(layer, p->tot_len, PBUF_RAM);
  1090. if (q == NULL) {
  1091. /* @todo: what do we do now? */
  1092. return p;
  1093. }
  1094. err = pbuf_copy(q, p);
  1095. LWIP_ASSERT("pbuf_copy failed", err == ERR_OK);
  1096. pbuf_free(p);
  1097. return q;
  1098. }
  1099. #if LWIP_CHECKSUM_ON_COPY
  1100. /**
  1101. * Copies data into a single pbuf (*not* into a pbuf queue!) and updates
  1102. * the checksum while copying
  1103. *
  1104. * @param p the pbuf to copy data into
  1105. * @param start_offset offset of p->payload where to copy the data to
  1106. * @param dataptr data to copy into the pbuf
  1107. * @param len length of data to copy into the pbuf
  1108. * @param chksum pointer to the checksum which is updated
  1109. * @return ERR_OK if successful, another error if the data does not fit
  1110. * within the (first) pbuf (no pbuf queues!)
  1111. */
  1112. err_t
  1113. pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr,
  1114. u16_t len, u16_t *chksum)
  1115. {
  1116. u32_t acc;
  1117. u16_t copy_chksum;
  1118. char *dst_ptr;
  1119. LWIP_ASSERT("p != NULL", p != NULL);
  1120. LWIP_ASSERT("dataptr != NULL", dataptr != NULL);
  1121. LWIP_ASSERT("chksum != NULL", chksum != NULL);
  1122. LWIP_ASSERT("len != 0", len != 0);
  1123. if ((start_offset >= p->len) || (start_offset + len > p->len)) {
  1124. return ERR_ARG;
  1125. }
  1126. dst_ptr = ((char*)p->payload) + start_offset;
  1127. copy_chksum = LWIP_CHKSUM_COPY(dst_ptr, dataptr, len);
  1128. if ((start_offset & 1) != 0) {
  1129. copy_chksum = SWAP_BYTES_IN_WORD(copy_chksum);
  1130. }
  1131. acc = *chksum;
  1132. acc += copy_chksum;
  1133. *chksum = FOLD_U32T(acc);
  1134. return ERR_OK;
  1135. }
  1136. #endif /* LWIP_CHECKSUM_ON_COPY */
  1137. /** Get one byte from the specified position in a pbuf
  1138. * WARNING: returns zero for offset >= p->tot_len
  1139. *
  1140. * @param p pbuf to parse
  1141. * @param offset offset into p of the byte to return
  1142. * @return byte at an offset into p OR ZERO IF 'offset' >= p->tot_len
  1143. */
  1144. u8_t
  1145. pbuf_get_at(struct pbuf* p, u16_t offset)
  1146. {
  1147. u16_t q_idx;
  1148. struct pbuf* q = pbuf_skip(p, offset, &q_idx);
  1149. /* return requested data if pbuf is OK */
  1150. if ((q != NULL) && (q->len > q_idx)) {
  1151. return ((u8_t*)q->payload)[q_idx];
  1152. }
  1153. return 0;
  1154. }
  1155. /** Put one byte to the specified position in a pbuf
  1156. * WARNING: silently ignores offset >= p->tot_len
  1157. *
  1158. * @param p pbuf to fill
  1159. * @param offset offset into p of the byte to write
  1160. * @param data byte to write at an offset into p
  1161. */
  1162. void
  1163. pbuf_put_at(struct pbuf* p, u16_t offset, u8_t data)
  1164. {
  1165. u16_t q_idx;
  1166. struct pbuf* q = pbuf_skip(p, offset, &q_idx);
  1167. /* write requested data if pbuf is OK */
  1168. if ((q != NULL) && (q->len > q_idx)) {
  1169. ((u8_t*)q->payload)[q_idx] = data;
  1170. }
  1171. }
  1172. /** Compare pbuf contents at specified offset with memory s2, both of length n
  1173. *
  1174. * @param p pbuf to compare
  1175. * @param offset offset into p at which to start comparing
  1176. * @param s2 buffer to compare
  1177. * @param n length of buffer to compare
  1178. * @return zero if equal, nonzero otherwise
  1179. * (0xffff if p is too short, diffoffset+1 otherwise)
  1180. */
  1181. u16_t
  1182. pbuf_memcmp(struct pbuf* p, u16_t offset, const void* s2, u16_t n)
  1183. {
  1184. u16_t start = offset;
  1185. struct pbuf* q = p;
  1186. /* get the correct pbuf */
  1187. while ((q != NULL) && (q->len <= start)) {
  1188. start -= q->len;
  1189. q = q->next;
  1190. }
  1191. /* return requested data if pbuf is OK */
  1192. if ((q != NULL) && (q->len > start)) {
  1193. u16_t i;
  1194. for (i = 0; i < n; i++) {
  1195. u8_t a = pbuf_get_at(q, start + i);
  1196. u8_t b = ((const u8_t*)s2)[i];
  1197. if (a != b) {
  1198. return i+1;
  1199. }
  1200. }
  1201. return 0;
  1202. }
  1203. return 0xffff;
  1204. }
  1205. /** Find occurrence of mem (with length mem_len) in pbuf p, starting at offset
  1206. * start_offset.
  1207. *
  1208. * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as
  1209. * return value 'not found'
  1210. * @param mem search for the contents of this buffer
  1211. * @param mem_len length of 'mem'
  1212. * @param start_offset offset into p at which to start searching
  1213. * @return 0xFFFF if substr was not found in p or the index where it was found
  1214. */
  1215. u16_t
  1216. pbuf_memfind(struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset)
  1217. {
  1218. u16_t i;
  1219. u16_t max = p->tot_len - mem_len;
  1220. if (p->tot_len >= mem_len + start_offset) {
  1221. for (i = start_offset; i <= max; i++) {
  1222. u16_t plus = pbuf_memcmp(p, i, mem, mem_len);
  1223. if (plus == 0) {
  1224. return i;
  1225. }
  1226. }
  1227. }
  1228. return 0xFFFF;
  1229. }
  1230. /** Find occurrence of substr with length substr_len in pbuf p, start at offset
  1231. * start_offset
  1232. * WARNING: in contrast to strstr(), this one does not stop at the first \0 in
  1233. * the pbuf/source string!
  1234. *
  1235. * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as
  1236. * return value 'not found'
  1237. * @param substr string to search for in p, maximum length is 0xFFFE
  1238. * @return 0xFFFF if substr was not found in p or the index where it was found
  1239. */
  1240. u16_t
  1241. pbuf_strstr(struct pbuf* p, const char* substr)
  1242. {
  1243. size_t substr_len;
  1244. if ((substr == NULL) || (substr[0] == 0) || (p->tot_len == 0xFFFF)) {
  1245. return 0xFFFF;
  1246. }
  1247. substr_len = strlen(substr);
  1248. if (substr_len >= 0xFFFF) {
  1249. return 0xFFFF;
  1250. }
  1251. return pbuf_memfind(p, substr, (u16_t)substr_len, 0);
  1252. }