ReactOS 0.4.16-dev-334-g4d9f67c
Packet buffers (PBUF)
Collaboration diagram for Packet buffers (PBUF):

Macros

#define PBUF_NEEDS_COPY(p)   ((p)->type_internal & PBUF_TYPE_FLAG_DATA_VOLATILE)
 

Enumerations

enum  pbuf_layer {
  PBUF_TRANSPORT = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN , PBUF_IP = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN , PBUF_LINK = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN , PBUF_RAW_TX = PBUF_LINK_ENCAPSULATION_HLEN ,
  PBUF_RAW = 0
}
 
enum  pbuf_type { PBUF_RAM = (PBUF_ALLOC_FLAG_DATA_CONTIGUOUS | PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP) , PBUF_ROM = PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF , PBUF_REF = (PBUF_TYPE_FLAG_DATA_VOLATILE | PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF) , PBUF_POOL = (PBUF_ALLOC_FLAG_RX | PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL) }
 

Functions

struct pbufpbuf_alloc (pbuf_layer layer, u16_t length, pbuf_type type)
 
struct pbufpbuf_alloc_reference (void *payload, u16_t length, pbuf_type type)
 
void pbuf_realloc (struct pbuf *p, u16_t new_len)
 
u8_t pbuf_free (struct pbuf *p)
 
void pbuf_ref (struct pbuf *p)
 
void pbuf_cat (struct pbuf *h, struct pbuf *t)
 
void pbuf_chain (struct pbuf *h, struct pbuf *t)
 
err_t pbuf_copy (struct pbuf *p_to, const struct pbuf *p_from)
 
err_t pbuf_copy_partial_pbuf (struct pbuf *p_to, const struct pbuf *p_from, u16_t copy_len, u16_t offset)
 
u16_t pbuf_copy_partial (const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
 
voidpbuf_get_contiguous (const struct pbuf *p, void *buffer, size_t bufsize, u16_t len, u16_t offset)
 
struct pbufpbuf_skip (struct pbuf *in, u16_t in_offset, u16_t *out_offset)
 
err_t pbuf_take (struct pbuf *buf, const void *dataptr, u16_t len)
 
err_t pbuf_take_at (struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset)
 
struct pbufpbuf_coalesce (struct pbuf *p, pbuf_layer layer)
 
struct pbufpbuf_clone (pbuf_layer layer, pbuf_type type, struct pbuf *p)
 
u8_t pbuf_get_at (const struct pbuf *p, u16_t offset)
 
int pbuf_try_get_at (const struct pbuf *p, u16_t offset)
 
void pbuf_put_at (struct pbuf *p, u16_t offset, u8_t data)
 
u16_t pbuf_memcmp (const struct pbuf *p, u16_t offset, const void *s2, u16_t n)
 
u16_t pbuf_memfind (const struct pbuf *p, const void *mem, u16_t mem_len, u16_t start_offset)
 

Detailed Description

Packets are built from the pbuf data structure. It supports dynamic memory allocation for packet contents or can reference externally managed packet contents both in RAM and ROM. Quick allocation for incoming packets is provided through pools with fixed sized pbufs.

A packet may span over multiple pbufs, chained as a singly linked list. This is called a "pbuf chain".

Multiple packets may be queued, also using this singly linked list. This is called a "packet queue".

So, a packet queue consists of one or more pbuf chains, each of which consist of one or more pbufs. CURRENTLY, PACKET QUEUES ARE NOT SUPPORTED!!! Use helper structs to queue multiple packets.

The differences between a pbuf chain and a packet queue are very precise but subtle.

The last pbuf of a packet has a ->tot_len field that equals the ->len field. It can be found by traversing the list. If the last pbuf of a packet has a ->next field other than NULL, more packets are on the queue.

Therefore, looping through a pbuf of a single packet, has an loop end condition (tot_len == p->len), NOT (next == NULL).

Example of custom pbuf usage: Zero-copy RX

Macro Definition Documentation

◆ PBUF_NEEDS_COPY

#define PBUF_NEEDS_COPY (   p)    ((p)->type_internal & PBUF_TYPE_FLAG_DATA_VOLATILE)

PBUF_NEEDS_COPY(p): return a boolean value indicating whether the given pbuf needs to be copied in order to be kept around beyond the current call stack without risking being corrupted. The default setting provides safety: it will make a copy iof any pbuf chain that does not consist entirely of PBUF_ROM type pbufs. For setups with zero-copy support, it may be redefined to evaluate to true in all cases, for example. However, doing so also has an effect on the application side: any buffers that are not copied must also not be reused by the application after passing them to lwIP. For example, when setting PBUF_NEEDS_COPY to (0), after using udp_send() with a PBUF_RAM pbuf, the application must free the pbuf immediately, rather than reusing it for other purposes. For more background information on this, see tasks #6735 and #7896, and bugs #11400 and #49914.

Definition at line 72 of file pbuf.h.

Enumeration Type Documentation

◆ pbuf_layer

Enumeration of pbuf layers

Enumerator
PBUF_TRANSPORT 

Includes spare room for transport layer header, e.g. UDP header. Use this if you intend to pass the pbuf to functions like udp_send().

PBUF_IP 

Includes spare room for IP header. Use this if you intend to pass the pbuf to functions like raw_send().

PBUF_LINK 

Includes spare room for link layer header (ethernet header). Use this if you intend to pass the pbuf to functions like ethernet_output().

See also
PBUF_LINK_HLEN
PBUF_RAW_TX 

Includes spare room for additional encapsulation header before ethernet headers (e.g. 802.11). Use this if you intend to pass the pbuf to functions like netif->linkoutput().

See also
PBUF_LINK_ENCAPSULATION_HLEN
PBUF_RAW 

Use this for input packets in a netif driver when calling netif->input() in the most common case - ethernet-layer netif driver.

Definition at line 89 of file pbuf.h.

89 {
111 PBUF_RAW = 0
112} pbuf_layer;
#define PBUF_LINK_HLEN
Definition: opt.h:1581
#define PBUF_LINK_ENCAPSULATION_HLEN
Definition: opt.h:1590
pbuf_layer
Definition: pbuf.h:89
@ PBUF_RAW_TX
Definition: pbuf.h:108
@ PBUF_RAW
Definition: pbuf.h:111
@ PBUF_TRANSPORT
Definition: pbuf.h:93
@ PBUF_LINK
Definition: pbuf.h:102
@ PBUF_IP
Definition: pbuf.h:97
#define PBUF_IP_HLEN
Definition: pbuf.h:82
#define PBUF_TRANSPORT_HLEN
Definition: pbuf.h:78

◆ pbuf_type

Enumeration of pbuf types

Enumerator
PBUF_RAM 

pbuf data is stored in RAM, used for TX mostly, struct pbuf and its payload are allocated in one piece of contiguous memory (so the first payload byte can be calculated from struct pbuf). pbuf_alloc() allocates PBUF_RAM pbufs as unchained pbufs (although that might change in future versions). This should be used for all OUTGOING packets (TX).

PBUF_ROM 

pbuf data is stored in ROM, i.e. struct pbuf and its payload are located in totally different memory areas. Since it points to ROM, payload does not have to be copied when queued for transmission.

PBUF_REF 

pbuf comes from the pbuf pool. Much like PBUF_ROM but payload might change so it has to be duplicated when queued before transmitting, depending on who has a 'ref' to it.

PBUF_POOL 

pbuf payload refers to RAM. This one comes from a pool and should be used for RX. Payload can be chained (scatter-gather RX) but like PBUF_RAM, struct pbuf and its payload are allocated in one piece of contiguous memory (so the first payload byte can be calculated from struct pbuf). Don't use this for TX, if the pool becomes empty e.g. because of TCP queuing, you are unable to receive TCP acks!

Definition at line 145 of file pbuf.h.

145 {
168} pbuf_type;
pbuf_type
Definition: pbuf.h:145
@ PBUF_ROM
Definition: pbuf.h:156
@ PBUF_RAM
Definition: pbuf.h:152
@ PBUF_REF
Definition: pbuf.h:160
@ PBUF_POOL
Definition: pbuf.h:167
#define PBUF_TYPE_FLAG_DATA_VOLATILE
Definition: pbuf.h:122
#define PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL
Definition: pbuf.h:135
#define PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF
Definition: pbuf.h:134
#define PBUF_ALLOC_FLAG_DATA_CONTIGUOUS
Definition: pbuf.h:131
#define PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS
Definition: pbuf.h:119
#define PBUF_ALLOC_FLAG_RX
Definition: pbuf.h:129
#define PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP
Definition: pbuf.h:133

Function Documentation

◆ pbuf_alloc()

struct pbuf * pbuf_alloc ( pbuf_layer  layer,
u16_t  length,
pbuf_type  type 
)

Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type).

The actual memory allocated for the pbuf is determined by the layer at which the pbuf is allocated and the requested size (from the size parameter).

Parameters
layerheader size
lengthsize of the pbuf's payload
typethis parameter decides how and where the pbuf should be allocated as follows:
  • PBUF_RAM: buffer memory for pbuf is allocated as one large chunk. This includes protocol headers as well.
  • PBUF_ROM: no buffer memory is allocated for the pbuf, even for protocol headers. Additional headers must be prepended by allocating another pbuf and chain in to the front of the ROM pbuf. It is assumed that the memory used is really similar to ROM in that it is immutable and will not be changed. Memory which is dynamic should generally not be attached to PBUF_ROM pbufs. Use PBUF_REF instead.
  • PBUF_REF: no buffer memory is allocated for the pbuf, even for protocol headers. It is assumed that the pbuf is only being used in a single thread. If the pbuf gets queued, then pbuf_take should be called to copy the buffer.
  • PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from the pbuf pool that is allocated during pbuf_init().
Returns
the allocated pbuf. If multiple pbufs where allocated, this is the first pbuf of a pbuf chain.

Definition at line 224 of file pbuf.c.

225{
226 struct pbuf *p;
228 LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length));
229
230 switch (type) {
231 case PBUF_REF: /* fall through */
232 case PBUF_ROM:
234 break;
235 case PBUF_POOL: {
236 struct pbuf *q, *last;
237 u16_t rem_len; /* remaining length */
238 p = NULL;
239 last = NULL;
240 rem_len = length;
241 do {
242 u16_t qlen;
243 q = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL);
244 if (q == NULL) {
246 /* free chain so far allocated */
247 if (p) {
248 pbuf_free(p);
249 }
250 /* bail out unsuccessfully */
251 return NULL;
252 }
255 rem_len, qlen, type, 0);
256 LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned",
257 ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0);
258 LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT",
260 if (p == NULL) {
261 /* allocated head of pbuf chain (into p) */
262 p = q;
263 } else {
264 /* make previous pbuf point to this pbuf */
265 last->next = q;
266 }
267 last = q;
268 rem_len = (u16_t)(rem_len - qlen);
269 offset = 0;
270 } while (rem_len > 0);
271 break;
272 }
273 case PBUF_RAM: {
275 mem_size_t alloc_len = (mem_size_t)(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF) + payload_len);
276
277 /* bug #50040: Check for integer overflow when calculating alloc_len */
278 if ((payload_len < LWIP_MEM_ALIGN_SIZE(length)) ||
279 (alloc_len < LWIP_MEM_ALIGN_SIZE(length))) {
280 return NULL;
281 }
282
283 /* If pbuf is to be allocated in RAM, allocate memory for it. */
284 p = (struct pbuf *)mem_malloc(alloc_len);
285 if (p == NULL) {
286 return NULL;
287 }
289 length, length, type, 0);
290 LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
291 ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
292 break;
293 }
294 default:
295 LWIP_ASSERT("pbuf_alloc: erroneous type", 0);
296 return NULL;
297 }
298 LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p));
299 return p;
300}
#define MEM_ALIGNMENT
Definition: d3d9_helpers.c:15
#define LWIP_MIN(x, y)
Definition: def.h:66
#define NULL
Definition: types.h:112
#define U16_F
Definition: cc.h:19
void * mem_malloc(mem_size_t size_in)
Definition: mem.c:831
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:158
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:116
u16_t mem_size_t
Definition: mem.h:67
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLuint GLint GLint layer
Definition: glext.h:7007
GLintptr offset
Definition: glext.h:5920
uint8_t u8_t
Definition: arch.h:125
uint16_t u16_t
Definition: arch.h:127
#define LWIP_MEM_ALIGN(addr)
Definition: arch.h:294
#define LWIP_MEM_ALIGN_SIZE(size)
Definition: arch.h:279
uintptr_t mem_ptr_t
Definition: arch.h:135
#define LWIP_DBG_TRACE
Definition: debug.h:83
#define PBUF_DEBUG
Definition: opt.h:3343
struct pbuf * pbuf_alloc_reference(void *payload, u16_t length, pbuf_type type)
Definition: pbuf.c:327
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:727
void * memp_malloc(memp_t type)
Definition: memp.c:337
static UINT UINT last
Definition: font.c:45
#define PBUF_POOL_BUFSIZE_ALIGNED
Definition: pbuf.c:92
static void pbuf_init_alloced_pbuf(struct pbuf *p, void *payload, u16_t tot_len, u16_t len, pbuf_type type, u8_t flags)
Definition: pbuf.c:179
#define SIZEOF_STRUCT_PBUF
Definition: pbuf.c:89
#define PBUF_POOL_IS_EMPTY()
Definition: pbuf.c:98
Definition: pbuf.h:186

Referenced by create_arp_response(), create_ip4_input_fragment(), eth_mac_irq(), input_pkt(), LibIPInsertPacket(), pbuf_clone(), send_pkt(), slipif_rxbyte(), START_TEST(), tcp_create_segment_wnd(), test_tcp_netif_output(), and test_udp_create_test_packet().

◆ pbuf_alloc_reference()

struct pbuf * pbuf_alloc_reference ( void payload,
u16_t  length,
pbuf_type  type 
)

Allocates a pbuf for referenced data. Referenced data can be volatile (PBUF_REF) or long-lived (PBUF_ROM).

The actual memory allocated for the pbuf is determined by the layer at which the pbuf is allocated and the requested size (from the size parameter).

Parameters
payloadreferenced payload
lengthsize of the pbuf's payload
typethis parameter decides how and where the pbuf should be allocated as follows:
  • PBUF_ROM: It is assumed that the memory used is really similar to ROM in that it is immutable and will not be changed. Memory which is dynamic should generally not be attached to PBUF_ROM pbufs. Use PBUF_REF instead.
  • PBUF_REF: It is assumed that the pbuf is only being used in a single thread. If the pbuf gets queued, then pbuf_take should be called to copy the buffer.
Returns
the allocated pbuf.

Definition at line 327 of file pbuf.c.

328{
329 struct pbuf *p;
330 LWIP_ASSERT("invalid pbuf_type", (type == PBUF_REF) || (type == PBUF_ROM));
331 /* only allocate memory for the pbuf structure */
332 p = (struct pbuf *)memp_malloc(MEMP_PBUF);
333 if (p == NULL) {
335 ("pbuf_alloc_reference: Could not allocate MEMP_PBUF for PBUF_%s.\n",
336 (type == PBUF_ROM) ? "ROM" : "REF"));
337 return NULL;
338 }
340 return p;
341}
#define LWIP_DBG_LEVEL_SERIOUS
Definition: debug.h:57
void * payload
Definition: pbuf.h:191

Referenced by pbuf_alloc().

◆ pbuf_cat()

void pbuf_cat ( struct pbuf h,
struct pbuf t 
)

Concatenate two pbufs (each may be a pbuf chain) and take over the caller's reference of the tail pbuf.

Note
The caller MAY NOT reference the tail pbuf afterwards. Use pbuf_chain() for that purpose.

This function explicitly does not check for tot_len overflow to prevent failing to queue too long pbufs. This can produce invalid pbufs, so handle with care!

See also
pbuf_chain()

Definition at line 855 of file pbuf.c.

856{
857 struct pbuf *p;
858
859 LWIP_ERROR("(h != NULL) && (t != NULL) (programmer violates API)",
860 ((h != NULL) && (t != NULL)), return;);
861
862 /* proceed to last pbuf of chain */
863 for (p = h; p->next != NULL; p = p->next) {
864 /* add total length of second chain to all totals of first chain */
865 p->tot_len = (u16_t)(p->tot_len + t->tot_len);
866 }
867 /* { p is last pbuf of first h chain, p->next == NULL } */
868 LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len);
869 LWIP_ASSERT("p->next == NULL", p->next == NULL);
870 /* add total length of second chain to last pbuf total of first chain */
871 p->tot_len = (u16_t)(p->tot_len + t->tot_len);
872 /* chain last pbuf of head (p) with first of tail (t) */
873 p->next = t;
874 /* p->next now references t, but the caller will drop its reference to t,
875 * so netto there is no change to the reference count of t.
876 */
877}
#define LWIP_ERROR(message, expression, handler)
Definition: debug.h:130
GLdouble GLdouble t
Definition: gl.h:2047
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
struct define * next
Definition: compiler.c:65

Referenced by pbuf_chain(), slipif_rxbyte(), START_TEST(), and test_tcp_netif_output().

◆ pbuf_chain()

void pbuf_chain ( struct pbuf h,
struct pbuf t 
)

Chain two pbufs (or pbuf chains) together.

The caller MUST call pbuf_free(t) once it has stopped using it. Use pbuf_cat() instead if you no longer use t.

Parameters
hhead pbuf (chain)
ttail pbuf (chain)
Note
The pbufs MUST belong to the same packet.
MAY NOT be called on a packet queue.

The ->tot_len fields of all pbufs of the head chain are adjusted. The ->next field of the last pbuf of the head chain is adjusted. The ->ref field of the first pbuf of the tail chain is adjusted.

Definition at line 897 of file pbuf.c.

898{
899 pbuf_cat(h, t);
900 /* t is now referenced by h */
901 pbuf_ref(t);
902 LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t));
903}
void pbuf_ref(struct pbuf *p)
Definition: pbuf.c:831
void pbuf_cat(struct pbuf *h, struct pbuf *t)
Definition: pbuf.c:855

◆ pbuf_clone()

struct pbuf * pbuf_clone ( pbuf_layer  layer,
pbuf_type  type,
struct pbuf p 
)

Allocates a new pbuf of same length (via pbuf_alloc()) and copies the source pbuf into this new pbuf (using pbuf_copy()).

Parameters
layerpbuf_layer of the new pbuf
typethis parameter decides how and where the pbuf should be allocated (
See also
pbuf_alloc())
Parameters
pthe source pbuf
Returns
a new pbuf or NULL if allocation fails

Definition at line 1337 of file pbuf.c.

1338{
1339 struct pbuf *q;
1340 err_t err;
1341 q = pbuf_alloc(layer, p->tot_len, type);
1342 if (q == NULL) {
1343 return NULL;
1344 }
1345 err = pbuf_copy(q, p);
1346 LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */
1347 LWIP_ASSERT("pbuf_copy failed", err == ERR_OK);
1348 return q;
1349}
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:373
s8_t err_t
Definition: err.h:96
@ ERR_OK
Definition: err.h:55
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:224
err_t pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from)
Definition: pbuf.c:959
#define err(...)

Referenced by pbuf_coalesce().

◆ pbuf_coalesce()

struct pbuf * pbuf_coalesce ( struct pbuf p,
pbuf_layer  layer 
)

Creates a single pbuf out of a queue of pbufs.

Remarks
: Either the source pbuf 'p' is freed by this function or the original pbuf 'p' is returned, therefore the caller has to check the result!
Parameters
pthe source pbuf
layerpbuf_layer of the new pbuf
Returns
a new, single pbuf (p->next is NULL) or the old pbuf if allocation fails

Definition at line 1309 of file pbuf.c.

1310{
1311 struct pbuf *q;
1312 if (p->next == NULL) {
1313 return p;
1314 }
1316 if (q == NULL) {
1317 /* @todo: what do we do now? */
1318 return p;
1319 }
1320 pbuf_free(p);
1321 return q;
1322}
struct pbuf * pbuf_clone(pbuf_layer layer, pbuf_type type, struct pbuf *p)
Definition: pbuf.c:1337

◆ pbuf_copy()

err_t pbuf_copy ( struct pbuf p_to,
const struct pbuf p_from 
)

Copy the contents of one packet buffer into another.

Note
Only one packet is copied, no packet queue!
Parameters
p_topbuf destination of the copy
p_frompbuf source of the copy
Returns
ERR_OK if pbuf was copied ERR_ARG if one of the pbufs is NULL or p_to is not big enough to hold p_from ERR_VAL if any of the pbufs are part of a queue

Definition at line 959 of file pbuf.c.

960{
961 LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n",
962 (const void *)p_to, (const void *)p_from));
963
964 LWIP_ERROR("pbuf_copy: invalid source", p_from != NULL, return ERR_ARG;);
965 return pbuf_copy_partial_pbuf(p_to, p_from, p_from->tot_len, 0);
966}
@ ERR_ARG
Definition: err.h:88
err_t pbuf_copy_partial_pbuf(struct pbuf *p_to, const struct pbuf *p_from, u16_t copy_len, u16_t offset)
Definition: pbuf.c:986
u16_t tot_len
Definition: pbuf.h:200

Referenced by pbuf_clone(), START_TEST(), and test_tcp_netif_output().

◆ pbuf_copy_partial()

u16_t pbuf_copy_partial ( const struct pbuf buf,
void dataptr,
u16_t  len,
u16_t  offset 
)

Copy (part of) the contents of a packet buffer to an application supplied buffer.

Parameters
bufthe pbuf from which to copy data
dataptrthe application supplied buffer
lenlength of data to copy (dataptr must be big enough). No more than buf->tot_len will be copied, irrespective of len
offsetoffset into the packet buffer from where to begin copying len bytes
Returns
the number of bytes copied, or 0 on failure

Definition at line 1058 of file pbuf.c.

1059{
1060 const struct pbuf *p;
1061 u16_t left = 0;
1062 u16_t buf_copy_len;
1063 u16_t copied_total = 0;
1064
1065 LWIP_ERROR("pbuf_copy_partial: invalid buf", (buf != NULL), return 0;);
1066 LWIP_ERROR("pbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;);
1067
1068 /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */
1069 for (p = buf; len != 0 && p != NULL; p = p->next) {
1070 if ((offset != 0) && (offset >= p->len)) {
1071 /* don't copy from this buffer -> on to the next */
1072 offset = (u16_t)(offset - p->len);
1073 } else {
1074 /* copy from this buffer. maybe only partially. */
1075 buf_copy_len = (u16_t)(p->len - offset);
1076 if (buf_copy_len > len) {
1077 buf_copy_len = len;
1078 }
1079 /* copy the necessary parts of the buffer */
1080 MEMCPY(&((char *)dataptr)[left], &((char *)p->payload)[offset], buf_copy_len);
1081 copied_total = (u16_t)(copied_total + buf_copy_len);
1082 left = (u16_t)(left + buf_copy_len);
1083 len = (u16_t)(len - buf_copy_len);
1084 offset = 0;
1085 }
1086 }
1087 return copied_total;
1088}
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLint left
Definition: glext.h:7726
GLenum GLsizei len
Definition: glext.h:6722
int const JOCTET * dataptr
Definition: jpeglib.h:1031
#define MEMCPY(DST, SRC, BYTES)
Definition: macros.h:231

Referenced by get_tcp_flags_from_packet(), LibTCPGetDataFromConnectionQueue(), netif_output(), pbuf_get_contiguous(), START_TEST(), test_netif_linkoutput(), and test_tcp_tx_full_window_lost().

◆ pbuf_copy_partial_pbuf()

err_t pbuf_copy_partial_pbuf ( struct pbuf p_to,
const struct pbuf p_from,
u16_t  copy_len,
u16_t  offset 
)

Copy part or all of one packet buffer into another, to a specified offset.

Note
Only data in one packet is copied, no packet queue!
Argument order is shared with pbuf_copy, but different than pbuf_copy_partial.
Parameters
p_topbuf destination of the copy
p_frompbuf source of the copy
copy_lennumber of bytes to copy
offsetoffset in destination pbuf where to copy to
Returns
ERR_OK if copy_len bytes were copied ERR_ARG if one of the pbufs is NULL or p_from is shorter than copy_len or p_to is not big enough to hold copy_len at offset ERR_VAL if any of the pbufs are part of a queue

Definition at line 986 of file pbuf.c.

987{
988 size_t offset_to = offset, offset_from = 0, len;
989
990 LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy_partial_pbuf(%p, %p, %"U16_F", %"U16_F")\n",
991 (const void *)p_to, (const void *)p_from, copy_len, offset));
992
993 /* is the copy_len in range? */
994 LWIP_ERROR("pbuf_copy_partial_pbuf: copy_len bigger than source", ((p_from != NULL) &&
995 (p_from->tot_len >= copy_len)), return ERR_ARG;);
996 /* is the target big enough to hold the source? */
997 LWIP_ERROR("pbuf_copy_partial_pbuf: target not big enough", ((p_to != NULL) &&
998 (p_to->tot_len >= (offset + copy_len))), return ERR_ARG;);
999
1000 /* iterate through pbuf chain */
1001 do {
1002 /* copy one part of the original chain */
1003 if ((p_to->len - offset_to) >= (p_from->len - offset_from)) {
1004 /* complete current p_from fits into current p_to */
1005 len = p_from->len - offset_from;
1006 } else {
1007 /* current p_from does not fit into current p_to */
1008 len = p_to->len - offset_to;
1009 }
1010 len = LWIP_MIN(copy_len, len);
1011 MEMCPY((u8_t *)p_to->payload + offset_to, (u8_t *)p_from->payload + offset_from, len);
1012 offset_to += len;
1013 offset_from += len;
1014 copy_len = (u16_t)(copy_len - len);
1015 LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len);
1016 LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len);
1017 if (offset_from >= p_from->len) {
1018 /* on to next p_from (if any) */
1019 offset_from = 0;
1020 p_from = p_from->next;
1021 LWIP_ERROR("p_from != NULL", (p_from != NULL) || (copy_len == 0), return ERR_ARG;);
1022 }
1023 if (offset_to == p_to->len) {
1024 /* on to next p_to (if any) */
1025 offset_to = 0;
1026 p_to = p_to->next;
1027 LWIP_ERROR("p_to != NULL", (p_to != NULL) || (copy_len == 0), return ERR_ARG;);
1028 }
1029
1030 if ((p_from != NULL) && (p_from->len == p_from->tot_len)) {
1031 /* don't copy more than one packet! */
1032 LWIP_ERROR("pbuf_copy_partial_pbuf() does not allow packet queues!",
1033 (p_from->next == NULL), return ERR_VAL;);
1034 }
1035 if ((p_to != NULL) && (p_to->len == p_to->tot_len)) {
1036 /* don't copy more than one packet! */
1037 LWIP_ERROR("pbuf_copy_partial_pbuf() does not allow packet queues!",
1038 (p_to->next == NULL), return ERR_VAL;);
1039 }
1040 } while (copy_len);
1041 LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy_partial_pbuf: copy complete.\n"));
1042 return ERR_OK;
1043}
@ ERR_VAL
Definition: err.h:67
struct pbuf * next
Definition: pbuf.h:188
u16_t len
Definition: pbuf.h:203

Referenced by pbuf_copy(), and START_TEST().

◆ pbuf_free()

u8_t pbuf_free ( struct pbuf p)

Dereference a pbuf chain or queue and deallocate any no-longer-used pbufs at the head of this chain or queue.

Decrements the pbuf reference count. If it reaches zero, the pbuf is deallocated.

For a pbuf chain, this is repeated for each pbuf in the chain, up to the first pbuf which has a non-zero reference count after decrementing. So, when all reference counts are one, the whole chain is free'd.

Parameters
pThe pbuf (chain) to be dereferenced.
Returns
the number of pbufs that were de-allocated from the head of the chain.
Note
the reference counter of a pbuf equals the number of pointers that refer to the pbuf (or into the pbuf).

Definition at line 727 of file pbuf.c.

728{
729 u8_t alloc_src;
730 struct pbuf *q;
731 u8_t count;
732
733 if (p == NULL) {
734 LWIP_ASSERT("p != NULL", p != NULL);
735 /* if assertions are disabled, proceed with debug output */
737 ("pbuf_free(p == NULL) was called.\n"));
738 return 0;
739 }
740 LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p));
741
743
744 count = 0;
745 /* de-allocate all consecutive pbufs from the head of the chain that
746 * obtain a zero reference count after decrementing*/
747 while (p != NULL) {
749 SYS_ARCH_DECL_PROTECT(old_level);
750 /* Since decrementing ref cannot be guaranteed to be a single machine operation
751 * we must protect it. We put the new ref into a local variable to prevent
752 * further protection. */
753 SYS_ARCH_PROTECT(old_level);
754 /* all pbufs in a chain are referenced at least once */
755 LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0);
756 /* decrease reference count (number of pointers to pbuf) */
757 ref = --(p->ref);
758 SYS_ARCH_UNPROTECT(old_level);
759 /* this pbuf is no longer referenced to? */
760 if (ref == 0) {
761 /* remember next pbuf in chain for next iteration */
762 q = p->next;
763 LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: deallocating %p\n", (void *)p));
764 alloc_src = pbuf_get_allocsrc(p);
765#if LWIP_SUPPORT_CUSTOM_PBUF
766 /* is this a custom pbuf? */
767 if ((p->flags & PBUF_FLAG_IS_CUSTOM) != 0) {
768 struct pbuf_custom *pc = (struct pbuf_custom *)p;
769 LWIP_ASSERT("pc->custom_free_function != NULL", pc->custom_free_function != NULL);
770 pc->custom_free_function(p);
771 } else
772#endif /* LWIP_SUPPORT_CUSTOM_PBUF */
773 {
774 /* is this a pbuf from the pool? */
776 memp_free(MEMP_PBUF_POOL, p);
777 /* is this a ROM or RAM referencing pbuf? */
778 } else if (alloc_src == PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF) {
779 memp_free(MEMP_PBUF, p);
780 /* type == PBUF_RAM */
781 } else if (alloc_src == PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP) {
782 mem_free(p);
783 } else {
784 /* @todo: support freeing other types */
785 LWIP_ASSERT("invalid pbuf type", 0);
786 }
787 }
788 count++;
789 /* proceed to next pbuf */
790 p = q;
791 /* p->ref > 0, this pbuf is still referenced to */
792 /* (and so the remaining pbufs in chain as well) */
793 } else {
794 LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, (u16_t)ref));
795 /* stop walking through the chain */
796 p = NULL;
797 }
798 }
799 PERF_STOP("pbuf_free");
800 /* return number of de-allocated pbufs */
801 return count;
802}
#define mem_free(ptr, bsize)
Definition: types.h:124
#define SYS_ARCH_UNPROTECT(lev)
Definition: cc.h:39
#define SYS_ARCH_PROTECT(lev)
Definition: cc.h:38
#define SYS_ARCH_DECL_PROTECT(lev)
Definition: cc.h:37
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define LWIP_PBUF_REF_T
Definition: opt.h:1607
void memp_free(memp_t type, void *mem)
Definition: memp.c:420
#define pbuf_get_allocsrc(p)
Definition: pbuf.h:283
#define PBUF_FLAG_IS_CUSTOM
Definition: pbuf.h:175
#define PERF_START
Definition: perf.h:3
#define PERF_STOP
Definition: perf.h:4
LWIP_PBUF_REF_T ref
Definition: pbuf.h:218
Definition: send.c:48

Referenced by create_ip4_input_fragment(), eth_mac_irq(), eth_rx_irq(), input_pkt(), InternalRecvEventHandler(), ip4_teardown(), LibTCPEmptyQueue(), main(), pbuf_alloc(), pbuf_coalesce(), pbuf_dechain(), pbuf_free_header(), pbuf_free_int(), pbuf_realloc(), slipif_rxbyte_input(), START_TEST(), tcpip_thread_handle_msg(), test_recv(), test_rst_generation_with_incoming_packet(), test_tcp_counters_recv(), test_tcp_recv_expect1byte(), and test_tcp_tx_full_window_lost().

◆ pbuf_get_at()

u8_t pbuf_get_at ( const struct pbuf p,
u16_t  offset 
)

Get one byte from the specified position in a pbuf WARNING: returns zero for offset >= p->tot_len

Parameters
ppbuf to parse
offsetoffset into p of the byte to return
Returns
byte at an offset into p OR ZERO IF 'offset' >= p->tot_len

Definition at line 1402 of file pbuf.c.

1403{
1404 int ret = pbuf_try_get_at(p, offset);
1405 if (ret >= 0) {
1406 return (u8_t)ret;
1407 }
1408 return 0;
1409}
int pbuf_try_get_at(const struct pbuf *p, u16_t offset)
Definition: pbuf.c:1420
int ret

Referenced by pbuf_memcmp(), and START_TEST().

◆ pbuf_get_contiguous()

void * pbuf_get_contiguous ( const struct pbuf p,
void buffer,
size_t  bufsize,
u16_t  len,
u16_t  offset 
)

Get part of a pbuf's payload as contiguous memory. The returned memory is either a pointer into the pbuf's payload or, if split over multiple pbufs, a copy into the user-supplied buffer.

Parameters
pthe pbuf from which to copy data
bufferthe application supplied buffer
bufsizesize of the application supplied buffer
lenlength of data to copy (dataptr must be big enough). No more than buf->tot_len will be copied, irrespective of len
offsetoffset into the packet buffer from where to begin copying len bytes
Returns
the number of bytes copied, or 0 on failure

Definition at line 1105 of file pbuf.c.

1106{
1107 const struct pbuf *q;
1108 u16_t out_offset;
1109
1110 LWIP_ERROR("pbuf_get_contiguous: invalid buf", (p != NULL), return NULL;);
1111 LWIP_ERROR("pbuf_get_contiguous: invalid dataptr", (buffer != NULL), return NULL;);
1112 LWIP_ERROR("pbuf_get_contiguous: invalid dataptr", (bufsize >= len), return NULL;);
1113
1114 q = pbuf_skip_const(p, offset, &out_offset);
1115 if (q != NULL) {
1116 if (q->len >= (out_offset + len)) {
1117 /* all data in this pbuf, return zero-copy */
1118 return (u8_t *)q->payload + out_offset;
1119 }
1120 /* need to copy */
1121 if (pbuf_copy_partial(q, buffer, len, out_offset) != len) {
1122 /* copying failed: pbuf is too short */
1123 return NULL;
1124 }
1125 return buffer;
1126 }
1127 /* pbuf is too short (offset does not fit in) */
1128 return NULL;
1129}
GLuint buffer
Definition: glext.h:5915
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
u16_t pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
Definition: pbuf.c:1058
static const struct pbuf * pbuf_skip_const(const struct pbuf *in, u16_t in_offset, u16_t *out_offset)
Definition: pbuf.c:1183

◆ pbuf_memcmp()

u16_t pbuf_memcmp ( const struct pbuf p,
u16_t  offset,
const void s2,
u16_t  n 
)

Compare pbuf contents at specified offset with memory s2, both of length n

Parameters
ppbuf to compare
offsetoffset into p at which to start comparing
s2buffer to compare
nlength of buffer to compare
Returns
zero if equal, nonzero otherwise (0xffff if p is too short, diffoffset+1 otherwise)

Definition at line 1465 of file pbuf.c.

1466{
1467 u16_t start = offset;
1468 const struct pbuf *q = p;
1469 u16_t i;
1470
1471 /* pbuf long enough to perform check? */
1472 if (p->tot_len < (offset + n)) {
1473 return 0xffff;
1474 }
1475
1476 /* get the correct pbuf from chain. We know it succeeds because of p->tot_len check above. */
1477 while ((q != NULL) && (q->len <= start)) {
1478 start = (u16_t)(start - q->len);
1479 q = q->next;
1480 }
1481
1482 /* return requested data if pbuf is OK */
1483 for (i = 0; i < n; i++) {
1484 /* We know pbuf_get_at() succeeds because of p->tot_len check above. */
1485 u8_t a = pbuf_get_at(q, (u16_t)(start + i));
1486 u8_t b = ((const u8_t *)s2)[i];
1487 if (a != b) {
1488 return (u16_t)LWIP_MIN(i + 1, 0xFFFF);
1489 }
1490 }
1491 return 0;
1492}
GLuint start
Definition: gl.h:1545
GLdouble n
Definition: glext.h:7729
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
u8_t pbuf_get_at(const struct pbuf *p, u16_t offset)
Definition: pbuf.c:1402
struct S2 s2

Referenced by pbuf_memfind().

◆ pbuf_memfind()

u16_t pbuf_memfind ( const struct pbuf p,
const void mem,
u16_t  mem_len,
u16_t  start_offset 
)

Find occurrence of mem (with length mem_len) in pbuf p, starting at offset start_offset.

Parameters
ppbuf to search, maximum length is 0xFFFE since 0xFFFF is used as return value 'not found'
memsearch for the contents of this buffer
mem_lenlength of 'mem'
start_offsetoffset into p at which to start searching
Returns
0xFFFF if substr was not found in p or the index where it was found

Definition at line 1507 of file pbuf.c.

1508{
1509 u16_t i;
1510 u16_t max_cmp_start = (u16_t)(p->tot_len - mem_len);
1511 if (p->tot_len >= mem_len + start_offset) {
1512 for (i = start_offset; i <= max_cmp_start; i++) {
1513 u16_t plus = pbuf_memcmp(p, i, mem, mem_len);
1514 if (plus == 0) {
1515 return i;
1516 }
1517 }
1518 }
1519 return 0xFFFF;
1520}
u16_t pbuf_memcmp(const struct pbuf *p, u16_t offset, const void *s2, u16_t n)
Definition: pbuf.c:1465
Definition: mem.c:349

Referenced by pbuf_strstr().

◆ pbuf_put_at()

void pbuf_put_at ( struct pbuf p,
u16_t  offset,
u8_t  data 
)

Put one byte to the specified position in a pbuf WARNING: silently ignores offset >= p->tot_len

Parameters
ppbuf to fill
offsetoffset into p of the byte to write
databyte to write at an offset into p

Definition at line 1442 of file pbuf.c.

1443{
1444 u16_t q_idx;
1445 struct pbuf *q = pbuf_skip(p, offset, &q_idx);
1446
1447 /* write requested data if pbuf is OK */
1448 if ((q != NULL) && (q->len > q_idx)) {
1449 ((u8_t *)q->payload)[q_idx] = data;
1450 }
1451}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
struct pbuf * pbuf_skip(struct pbuf *in, u16_t in_offset, u16_t *out_offset)
Definition: pbuf.c:1209

Referenced by START_TEST().

◆ pbuf_realloc()

void pbuf_realloc ( struct pbuf p,
u16_t  new_len 
)

Shrink a pbuf chain to a desired length.

Parameters
ppbuf to shrink.
new_lendesired new length of pbuf chain

Depending on the desired length, the first few pbufs in a chain might be skipped and left unchanged. The new last pbuf in the chain will be resized, and any remaining pbufs will be freed.

Note
If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted.
May not be called on a packet queue.
Despite its name, pbuf_realloc cannot grow the size of a pbuf (chain).

Definition at line 402 of file pbuf.c.

403{
404 struct pbuf *q;
405 u16_t rem_len; /* remaining length */
406 u16_t shrink;
407
408 LWIP_ASSERT("pbuf_realloc: p != NULL", p != NULL);
409
410 /* desired length larger than current length? */
411 if (new_len >= p->tot_len) {
412 /* enlarging not yet supported */
413 return;
414 }
415
416 /* the pbuf chain grows by (new_len - p->tot_len) bytes
417 * (which may be negative in case of shrinking) */
418 shrink = (u16_t)(p->tot_len - new_len);
419
420 /* first, step over any pbufs that should remain in the chain */
421 rem_len = new_len;
422 q = p;
423 /* should this pbuf be kept? */
424 while (rem_len > q->len) {
425 /* decrease remaining length by pbuf length */
426 rem_len = (u16_t)(rem_len - q->len);
427 /* decrease total length indicator */
428 q->tot_len = (u16_t)(q->tot_len - shrink);
429 /* proceed to next pbuf in chain */
430 q = q->next;
431 LWIP_ASSERT("pbuf_realloc: q != NULL", q != NULL);
432 }
433 /* we have now reached the new last pbuf (in q) */
434 /* rem_len == desired length for pbuf q */
435
436 /* shrink allocated memory for PBUF_RAM */
437 /* (other types merely adjust their length fields */
440 && ((q->flags & PBUF_FLAG_IS_CUSTOM) == 0)
441#endif /* LWIP_SUPPORT_CUSTOM_PBUF */
442 ) {
443 /* reallocate and adjust the length of the pbuf that will be split */
444 struct pbuf *r = (struct pbuf *)mem_trim(q, (mem_size_t)(((u8_t *)q->payload - (u8_t *)q) + rem_len));
445 LWIP_ASSERT("mem_trim returned r == NULL", r != NULL);
446 /* help to detect faulty overridden implementation of mem_trim */
447 LWIP_ASSERT("mem_trim returned r != q", r == q);
449 }
450 /* adjust length fields for new last pbuf */
451 q->len = rem_len;
452 q->tot_len = q->len;
453
454 /* any remaining pbufs in chain? */
455 if (q->next != NULL) {
456 /* free remaining pbufs in chain */
457 pbuf_free(q->next);
458 }
459 /* q is last packet in chain */
460 q->next = NULL;
461
462}
void * mem_trim(void *rmem, mem_size_t new_size)
Definition: mem.c:699
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define LWIP_SUPPORT_CUSTOM_PBUF
Definition: pbuf.h:55
#define pbuf_match_allocsrc(p, type)
Definition: pbuf.h:284

Referenced by slipif_rxbyte().

◆ pbuf_ref()

void pbuf_ref ( struct pbuf p)

Increment the reference count of the pbuf.

Parameters
ppbuf to increase reference counter of

Definition at line 831 of file pbuf.c.

832{
833 /* pbuf given? */
834 if (p != NULL) {
835 SYS_ARCH_SET(p->ref, (LWIP_PBUF_REF_T)(p->ref + 1));
836 LWIP_ASSERT("pbuf ref overflow", p->ref > 0);
837 }
838}
#define SYS_ARCH_SET(var, val)
Definition: sys.h:553

Referenced by pbuf_chain().

◆ pbuf_skip()

struct pbuf * pbuf_skip ( struct pbuf in,
u16_t  in_offset,
u16_t out_offset 
)

Skip a number of bytes at the start of a pbuf

Parameters
ininput pbuf
in_offsetoffset to skip
out_offsetresulting offset in the returned pbuf
Returns
the pbuf in the queue where the offset is or NULL when the offset is too high

Definition at line 1209 of file pbuf.c.

1210{
1211 const struct pbuf *out = pbuf_skip_const(in, in_offset, out_offset);
1212 return LWIP_CONST_CAST(struct pbuf *, out);
1213}
GLuint in
Definition: glext.h:9616
#define LWIP_CONST_CAST(target_type, val)
Definition: arch.h:240
static FILE * out
Definition: regtests2xml.c:44

Referenced by pbuf_put_at(), and pbuf_take_at().

◆ pbuf_take()

err_t pbuf_take ( struct pbuf buf,
const void dataptr,
u16_t  len 
)

Copy application supplied data into a pbuf. This function can only be used to copy the equivalent of buf->tot_len data.

Parameters
bufpbuf to fill with data
dataptrapplication supplied data buffer
lenlength of the application supplied data buffer
Returns
ERR_OK if successful, ERR_MEM if the pbuf is not big enough

Definition at line 1227 of file pbuf.c.

1228{
1229 struct pbuf *p;
1230 size_t buf_copy_len;
1231 size_t total_copy_len = len;
1232 size_t copied_total = 0;
1233
1234 LWIP_ERROR("pbuf_take: invalid buf", (buf != NULL), return ERR_ARG;);
1235 LWIP_ERROR("pbuf_take: invalid dataptr", (dataptr != NULL), return ERR_ARG;);
1236 LWIP_ERROR("pbuf_take: buf not large enough", (buf->tot_len >= len), return ERR_MEM;);
1237
1238 if ((buf == NULL) || (dataptr == NULL) || (buf->tot_len < len)) {
1239 return ERR_ARG;
1240 }
1241
1242 /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */
1243 for (p = buf; total_copy_len != 0; p = p->next) {
1244 LWIP_ASSERT("pbuf_take: invalid pbuf", p != NULL);
1245 buf_copy_len = total_copy_len;
1246 if (buf_copy_len > p->len) {
1247 /* this pbuf cannot hold all remaining data */
1248 buf_copy_len = p->len;
1249 }
1250 /* copy the necessary parts of the buffer */
1251 MEMCPY(p->payload, &((const char *)dataptr)[copied_total], buf_copy_len);
1252 total_copy_len -= buf_copy_len;
1253 copied_total += buf_copy_len;
1254 }
1255 LWIP_ASSERT("did not copy all data", total_copy_len == 0 && copied_total == len);
1256 return ERR_OK;
1257}
#define ERR_MEM
Definition: fontsub.h:52

Referenced by eth_mac_irq(), pbuf_take_at(), START_TEST(), tcp_create_segment_wnd(), and test_udp_create_test_packet().

◆ pbuf_take_at()

err_t pbuf_take_at ( struct pbuf buf,
const void dataptr,
u16_t  len,
u16_t  offset 
)

Same as pbuf_take() but puts data at an offset

Parameters
bufpbuf to fill with data
dataptrapplication supplied data buffer
lenlength of the application supplied data buffer
offsetoffset in pbuf where to copy dataptr to
Returns
ERR_OK if successful, ERR_MEM if the pbuf is not big enough

Definition at line 1271 of file pbuf.c.

1272{
1273 u16_t target_offset;
1274 struct pbuf *q = pbuf_skip(buf, offset, &target_offset);
1275
1276 /* return requested data if pbuf is OK */
1277 if ((q != NULL) && (q->tot_len >= target_offset + len)) {
1278 u16_t remaining_len = len;
1279 const u8_t *src_ptr = (const u8_t *)dataptr;
1280 /* copy the part that goes into the first pbuf */
1281 u16_t first_copy_len;
1282 LWIP_ASSERT("check pbuf_skip result", target_offset < q->len);
1283 first_copy_len = (u16_t)LWIP_MIN(q->len - target_offset, len);
1284 MEMCPY(((u8_t *)q->payload) + target_offset, dataptr, first_copy_len);
1285 remaining_len = (u16_t)(remaining_len - first_copy_len);
1286 src_ptr += first_copy_len;
1287 if (remaining_len > 0) {
1288 return pbuf_take(q->next, src_ptr, remaining_len);
1289 }
1290 return ERR_OK;
1291 }
1292 return ERR_MEM;
1293}
err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len)
Definition: pbuf.c:1227

Referenced by START_TEST().

◆ pbuf_try_get_at()

int pbuf_try_get_at ( const struct pbuf p,
u16_t  offset 
)

Get one byte from the specified position in a pbuf

Parameters
ppbuf to parse
offsetoffset into p of the byte to return
Returns
byte at an offset into p [0..0xFF] OR negative if 'offset' >= p->tot_len

Definition at line 1420 of file pbuf.c.

1421{
1422 u16_t q_idx;
1423 const struct pbuf *q = pbuf_skip_const(p, offset, &q_idx);
1424
1425 /* return requested data if pbuf is OK */
1426 if ((q != NULL) && (q->len > q_idx)) {
1427 return ((u8_t *)q->payload)[q_idx];
1428 }
1429 return -1;
1430}

Referenced by pbuf_get_at().