u16_t net_calc_chksum(struct net_pkt *pkt, u8_t proto) { u16_t upper_layer_len; u16_t sum; switch (net_pkt_family(pkt)) { #if defined(CONFIG_NET_IPV4) case AF_INET: upper_layer_len = (NET_IPV4_HDR(pkt)->len[0] << 8) + NET_IPV4_HDR(pkt)->len[1] - net_pkt_ipv6_ext_len(pkt) - net_pkt_ip_hdr_len(pkt); if (proto == IPPROTO_ICMP) { return htons(calc_chksum(0, net_pkt_ip_data(pkt) + net_pkt_ip_hdr_len(pkt), upper_layer_len)); } else { sum = calc_chksum(upper_layer_len + proto, (u8_t *)&NET_IPV4_HDR(pkt)->src, 2 * sizeof(struct in_addr)); } break; #endif #if defined(CONFIG_NET_IPV6) case AF_INET6: upper_layer_len = (NET_IPV6_HDR(pkt)->len[0] << 8) + NET_IPV6_HDR(pkt)->len[1] - net_pkt_ipv6_ext_len(pkt); sum = calc_chksum(upper_layer_len + proto, (u8_t *)&NET_IPV6_HDR(pkt)->src, 2 * sizeof(struct in6_addr)); break; #endif default: NET_DBG("Unknown protocol family %d", net_pkt_family(pkt)); return 0; } sum = calc_chksum_pkt(sum, pkt, upper_layer_len); sum = (sum == 0) ? 0xffff : htons(sum); return sum; }
static inline int slip_input_byte(struct slip_context *slip, unsigned char c) { switch (slip->state) { case STATE_GARBAGE: if (c == SLIP_END) { slip->state = STATE_OK; } return 0; case STATE_ESC: if (c == SLIP_ESC_END) { c = SLIP_END; } else if (c == SLIP_ESC_ESC) { c = SLIP_ESC; } else { slip->state = STATE_GARBAGE; SLIP_STATS(slip->garbage++); return 0; } slip->state = STATE_OK; break; case STATE_OK: if (c == SLIP_ESC) { slip->state = STATE_ESC; return 0; } if (c == SLIP_END) { slip->state = STATE_OK; slip->first = false; if (slip->rx) { return 1; } return 0; } if (slip->first && !slip->rx) { /* Must have missed buffer allocation on first byte. */ return 0; } if (!slip->first) { slip->first = true; slip->rx = net_pkt_get_reserve_rx(0, K_NO_WAIT); if (!slip->rx) { SYS_LOG_ERR("[%p] cannot allocate pkt", slip); return 0; } slip->last = net_pkt_get_frag(slip->rx, K_NO_WAIT); if (!slip->last) { SYS_LOG_ERR("[%p] cannot allocate 1st data frag", slip); net_pkt_unref(slip->rx); slip->rx = NULL; return 0; } net_pkt_frag_add(slip->rx, slip->last); slip->ptr = net_pkt_ip_data(slip->rx); } break; } /* It is possible that slip->last is not set during the startup * of the device. If this happens do not continue and overwrite * some random memory. */ if (!slip->last) { return 0; } if (!net_buf_tailroom(slip->last)) { /* We need to allocate a new fragment */ struct net_buf *frag; frag = net_pkt_get_reserve_rx_data(0, K_NO_WAIT); if (!frag) { SYS_LOG_ERR("[%p] cannot allocate next data frag", slip); net_pkt_unref(slip->rx); slip->rx = NULL; slip->last = NULL; return 0; } net_buf_frag_insert(slip->last, frag); slip->last = frag; slip->ptr = slip->last->data; } /* The net_buf_add_u8() cannot add data to ll header so we need * a way to do it. */ if (slip->ptr < slip->last->data) { *slip->ptr = c; } else { slip->ptr = net_buf_add_u8(slip->last, c); } slip->ptr++; return 0; }