pbuf.c 49 KB

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