Beispiel #1
0
/* New version of ip_checksum, notice this version does not change it into 
 * network order. It is useful to keep it in host order for further processing
 */ 
uint16_t __ip_checksum(void *dataptr, unsigned int len, uint32_t sum)
{
  uint8_t *pb = (uint8_t *)dataptr;
  uint16_t *ps, t = 0;
  int odd = ((uintptr_t)pb & 1);

  /* Get aligned to uint16_t */
	// this means pb started on some weird address..
	// but in our world this should never happen.. since the payload should always be aligned..
	// right..

  if (odd && len > 0) {
		// change the second half of t to what pb is
		// and advance pb
    ((uint8_t *)&t)[1] = *pb++;
    len--;
  }

  /* Add the bulk of the data */
  ps = (uint16_t *)(void *)pb;
  while (len > 1) {
    sum += *ps++;
    len -= 2;
  }

  /* Consume left-over byte, if any */
  if (len > 0) {
    ((uint8_t *)&t)[0] = *(uint8_t *)ps;
  }

  /* Add end bytes */
  sum += t;

  /* Fold 32-bit sum to 16 bits
     calling this twice is propably faster than if statements... */
  sum = FOLD_U32T(sum);
  sum = FOLD_U32T(sum);

  /* Swap if alignment was odd */
  if (odd) {
    sum = byte_swap16(sum);
  }

  return (uint16_t)sum;
}
Beispiel #2
0
/** Add a checksum of newly added data to the segment */
static void ICACHE_FLASH_ATTR
tcp_seg_add_chksum(u16_t chksum, u16_t len, u16_t *seg_chksum,
				   u8_t *seg_chksum_swapped) {
	u32_t helper;
	/* add chksum to old chksum and fold to u16_t */
	helper = chksum + *seg_chksum;
	chksum = FOLD_U32T(helper);
	if ((len & 1) != 0) {
		*seg_chksum_swapped = 1 - *seg_chksum_swapped;
		chksum = SWAP_BYTES_IN_WORD(chksum);
	}
	*seg_chksum = chksum;
}
Beispiel #3
0
/* ip addresses need to be network order, protolen and proto are HO */
uint16_t inet_chksum_pseudo(struct pbuf *p, uint32_t src, uint32_t dest, uint8_t proto, uint16_t proto_len) {
  uint32_t acc;
  uint32_t addr;
  struct pbuf *q;
  uint8_t swapped;

  acc = 0;
  swapped = 0;
  /* iterate through all pbuf in chain */
  for(q = p; q != NULL; q = STAILQ_NEXT(q, next)) {
    acc += __ip_checksum(q->payload, q->len, 0);
    acc = FOLD_U32T(acc);
    if (q->len % 2 != 0) {
      swapped = 1 - swapped;
      acc = byte_swap16(acc);
    }
  }

  if (swapped) {
    acc = byte_swap16(acc);
  }

  addr = (src);
  acc += (addr & 0xffffUL);
  acc += ((addr >> 16) & 0xffffUL);
  addr = (dest);
  acc += (addr & 0xffffUL);
  acc += ((addr >> 16) & 0xffffUL);
  acc += (uint32_t)htons((uint16_t)proto);
  acc += (uint32_t)htons(proto_len);

  /* Fold 32-bit sum to 16 bits
     calling this twice is propably faster than if statements... */
  acc = FOLD_U32T(acc);
  acc = FOLD_U32T(acc);
  return (uint16_t)~(acc & 0xffffUL);
}