Prusa MINI Firmware overview
inet_chksum.c File Reference
#include "lwip/opt.h"
#include "lwip/inet_chksum.h"
#include "lwip/def.h"
#include "lwip/ip_addr.h"
#include <string.h>

Macros

#define LWIP_CHKSUM   lwip_standard_chksum
 
#define LWIP_CHKSUM_ALGORITHM   2
 

Functions

u16_t lwip_standard_chksum (const void *dataptr, int len)
 
static u16_t inet_cksum_pseudo_base (struct pbuf *p, u8_t proto, u16_t proto_len, u32_t acc)
 
u16_t ip_chksum_pseudo (struct pbuf *p, u8_t proto, u16_t proto_len, const ip_addr_t *src, const ip_addr_t *dest)
 
static u16_t inet_cksum_pseudo_partial_base (struct pbuf *p, u8_t proto, u16_t proto_len, u16_t chksum_len, u32_t acc)
 
u16_t ip_chksum_pseudo_partial (struct pbuf *p, u8_t proto, u16_t proto_len, u16_t chksum_len, const ip_addr_t *src, const ip_addr_t *dest)
 
u16_t inet_chksum (const void *dataptr, u16_t len)
 
u16_t inet_chksum_pbuf (struct pbuf *p)
 

Detailed Description

Incluse internet checksum functions.
These are some reference implementations of the checksum algorithm, with the aim of being simple, correct and fully portable. Checksumming is the first thing you would want to optimize for your platform. If you create your own version, link it in and in your cc.h put:

#define LWIP_CHKSUM your_checksum_routine

Or you can select from the implementations below by defining LWIP_CHKSUM_ALGORITHM to 1, 2 or 3.

Macro Definition Documentation

◆ LWIP_CHKSUM

#define LWIP_CHKSUM   lwip_standard_chksum

◆ LWIP_CHKSUM_ALGORITHM

#define LWIP_CHKSUM_ALGORITHM   2

Function Documentation

◆ lwip_standard_chksum()

u16_t lwip_standard_chksum ( const void dataptr,
int  len 
)
134 {
135  const u8_t *pb = (const u8_t *)dataptr;
136  const u16_t *ps;
137  u16_t t = 0;
138  u32_t sum = 0;
139  int odd = ((mem_ptr_t)pb & 1);
140 
141  /* Get aligned to u16_t */
142  if (odd && len > 0) {
143  ((u8_t *)&t)[1] = *pb++;
144  len--;
145  }
146 
147  /* Add the bulk of the data */
148  ps = (const u16_t *)(const void *)pb;
149  while (len > 1) {
150  sum += *ps++;
151  len -= 2;
152  }
153 
154  /* Consume left-over byte, if any */
155  if (len > 0) {
156  ((u8_t *)&t)[0] = *(const u8_t *)ps;
157  }
158 
159  /* Add end bytes */
160  sum += t;
161 
162  /* Fold 32-bit sum to 16 bits
163  calling this twice is probably faster than if statements... */
164  sum = FOLD_U32T(sum);
165  sum = FOLD_U32T(sum);
166 
167  /* Swap if alignment was odd */
168  if (odd) {
169  sum = SWAP_BYTES_IN_WORD(sum);
170  }
171 
172  return (u16_t)sum;
173 }

◆ inet_cksum_pseudo_base()

static u16_t inet_cksum_pseudo_base ( struct pbuf p,
u8_t  proto,
u16_t  proto_len,
u32_t  acc 
)
static

Parts of the pseudo checksum which are common to IPv4 and IPv6

261 {
262  struct pbuf *q;
263  u8_t swapped = 0;
264 
265  /* iterate through all pbuf in chain */
266  for (q = p; q != NULL; q = q->next) {
267  LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
268  (void *)q, (void *)q->next));
269  acc += LWIP_CHKSUM(q->payload, q->len);
270  /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
271  /* just executing this next line is probably faster that the if statement needed
272  to check whether we really need to execute it, and does no harm */
273  acc = FOLD_U32T(acc);
274  if (q->len % 2 != 0) {
275  swapped = 1 - swapped;
276  acc = SWAP_BYTES_IN_WORD(acc);
277  }
278  /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
279  }
280 
281  if (swapped) {
282  acc = SWAP_BYTES_IN_WORD(acc);
283  }
284 
285  acc += (u32_t)lwip_htons((u16_t)proto);
286  acc += (u32_t)lwip_htons(proto_len);
287 
288  /* Fold 32-bit sum to 16 bits
289  calling this twice is probably faster than if statements... */
290  acc = FOLD_U32T(acc);
291  acc = FOLD_U32T(acc);
292  LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
293  return (u16_t)~(acc & 0xffffUL);
294 }
Here is the call graph for this function:

◆ ip_chksum_pseudo()

u16_t ip_chksum_pseudo ( struct pbuf p,
u8_t  proto,
u16_t  proto_len,
const ip_addr_t src,
const ip_addr_t dest 
)
381 {
382 #if LWIP_IPV6
383  if (IP_IS_V6(dest)) {
384  return ip6_chksum_pseudo(p, proto, proto_len, ip_2_ip6(src), ip_2_ip6(dest));
385  }
386 #endif /* LWIP_IPV6 */
387 #if LWIP_IPV4 && LWIP_IPV6
388  else
389 #endif /* LWIP_IPV4 && LWIP_IPV6 */
390 #if LWIP_IPV4
391  {
392  return inet_chksum_pseudo(p, proto, proto_len, ip_2_ip4(src), ip_2_ip4(dest));
393  }
394 #endif /* LWIP_IPV4 */
395 }

◆ inet_cksum_pseudo_partial_base()

static u16_t inet_cksum_pseudo_partial_base ( struct pbuf p,
u8_t  proto,
u16_t  proto_len,
u16_t  chksum_len,
u32_t  acc 
)
static

Parts of the pseudo checksum which are common to IPv4 and IPv6

401 {
402  struct pbuf *q;
403  u8_t swapped = 0;
404  u16_t chklen;
405 
406  /* iterate through all pbuf in chain */
407  for (q = p; (q != NULL) && (chksum_len > 0); q = q->next) {
408  LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
409  (void *)q, (void *)q->next));
410  chklen = q->len;
411  if (chklen > chksum_len) {
412  chklen = chksum_len;
413  }
414  acc += LWIP_CHKSUM(q->payload, chklen);
415  chksum_len -= chklen;
416  LWIP_ASSERT("delete me", chksum_len < 0x7fff);
417  /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
418  /* fold the upper bit down */
419  acc = FOLD_U32T(acc);
420  if (q->len % 2 != 0) {
421  swapped = 1 - swapped;
422  acc = SWAP_BYTES_IN_WORD(acc);
423  }
424  /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
425  }
426 
427  if (swapped) {
428  acc = SWAP_BYTES_IN_WORD(acc);
429  }
430 
431  acc += (u32_t)lwip_htons((u16_t)proto);
432  acc += (u32_t)lwip_htons(proto_len);
433 
434  /* Fold 32-bit sum to 16 bits
435  calling this twice is probably faster than if statements... */
436  acc = FOLD_U32T(acc);
437  acc = FOLD_U32T(acc);
438  LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
439  return (u16_t)~(acc & 0xffffUL);
440 }
Here is the call graph for this function:

◆ ip_chksum_pseudo_partial()

u16_t ip_chksum_pseudo_partial ( struct pbuf p,
u8_t  proto,
u16_t  proto_len,
u16_t  chksum_len,
const ip_addr_t src,
const ip_addr_t dest 
)
528 {
529 #if LWIP_IPV6
530  if (IP_IS_V6(dest)) {
531  return ip6_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ip_2_ip6(src), ip_2_ip6(dest));
532  }
533 #endif /* LWIP_IPV6 */
534 #if LWIP_IPV4 && LWIP_IPV6
535  else
536 #endif /* LWIP_IPV4 && LWIP_IPV6 */
537 #if LWIP_IPV4
538  {
539  return inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ip_2_ip4(src), ip_2_ip4(dest));
540  }
541 #endif /* LWIP_IPV4 */
542 }

◆ inet_chksum()

u16_t inet_chksum ( const void dataptr,
u16_t  len 
)
556 {
557  return (u16_t)~(unsigned int)LWIP_CHKSUM(dataptr, len);
558 }

◆ inet_chksum_pbuf()

u16_t inet_chksum_pbuf ( struct pbuf p)

Calculate a checksum over a chain of pbufs (without pseudo-header, much like inet_chksum only pbufs are used).

Parameters
ppbuf chain over that the checksum should be calculated
Returns
checksum (as u16_t) to be saved directly in the protocol header
569 {
570  u32_t acc;
571  struct pbuf *q;
572  u8_t swapped;
573 
574  acc = 0;
575  swapped = 0;
576  for (q = p; q != NULL; q = q->next) {
577  acc += LWIP_CHKSUM(q->payload, q->len);
578  acc = FOLD_U32T(acc);
579  if (q->len % 2 != 0) {
580  swapped = 1 - swapped;
581  acc = SWAP_BYTES_IN_WORD(acc);
582  }
583  }
584 
585  if (swapped) {
586  acc = SWAP_BYTES_IN_WORD(acc);
587  }
588  return (u16_t)~(acc & 0xffffUL);
589 }
IP_IS_V6
#define IP_IS_V6(ipaddr)
Definition: ip_addr.h:296
pbuf::len
u16_t len
Definition: pbuf.h:159
LWIP_ASSERT
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:116
INET_DEBUG
#define INET_DEBUG
Definition: opt.h:2687
u16_t
uint16_t u16_t
Definition: arch.h:121
u32_t
uint32_t u32_t
Definition: arch.h:123
pbuf::next
struct pbuf * next
Definition: pbuf.h:144
LWIP_CHKSUM
#define LWIP_CHKSUM
Definition: inet_chksum.c:57
NULL
#define NULL
Definition: usbd_def.h:53
SWAP_BYTES_IN_WORD
#define SWAP_BYTES_IN_WORD(w)
Definition: inet_chksum.h:47
fsdata_file::len
int len
Definition: fsdata.h:42
u8_t
uint8_t u8_t
Definition: arch.h:119
ip_2_ip6
#define ip_2_ip6(ipaddr)
Definition: ip_addr.h:301
lwip_htons
u16_t lwip_htons(u16_t n)
Definition: def.c:76
mem_ptr_t
uintptr_t mem_ptr_t
Definition: arch.h:125
createSpeedLookupTable.int
int
Definition: createSpeedLookupTable.py:15
X32_F
#define X32_F
Definition: arch.h:158
FOLD_U32T
#define FOLD_U32T(u)
Definition: inet_chksum.h:52
pbuf
Definition: pbuf.h:142
LWIP_DEBUGF
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:164
pbuf::payload
void * payload
Definition: pbuf.h:147