Get rid of duplicated checksums with IPv6 pseudo-headers.
#define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */
/* in print-ip6.c */
-extern int nextproto6_cksum(const struct ip6_hdr *, const u_short *, u_int, u_int);
+extern int nextproto6_cksum(const struct ip6_hdr *, const u_int8_t *, u_int, u_int);
#endif /* not _NETINET_IP6_H_ */
extern void ip6_print(netdissect_options *,const u_char *, u_int);
#if 0
extern void ip6_opt_print(netdissect_options *,const u_char *, int);
-extern int nextproto6_cksum(const struct ip6_hdr *, const u_short *, u_int, u_int);
+extern int nextproto6_cksum(const struct ip6_hdr *, const u_int8_t *, u_int, u_int);
extern int hbhopt_print(netdissect_options *,const u_char *);
extern int dstopt_print(netdissect_options *,const u_char *);
extern int frag6_print(netdissect_options *,const u_char *,
#ifdef INET6
static int dccp6_cksum(const struct ip6_hdr *ip6, const struct dccp_hdr *dh, u_int len)
{
- int cov = dccp_csum_coverage(dh, len);
- struct {
- struct in6_addr ph_src;
- struct in6_addr ph_dst;
- u_int32_t ph_len;
- u_int8_t ph_zero[3];
- u_int8_t ph_nxt;
- } ph;
- struct cksum_vec vec[2];
-
- /* pseudo-header */
- memset(&ph, 0, sizeof(ph));
- ph.ph_src = ip6->ip6_src;
- ph.ph_dst = ip6->ip6_dst;
- ph.ph_len = htonl(len);
- ph.ph_nxt = IPPROTO_DCCP;
-
- vec[0].ptr = (const u_int8_t *)(void *)&ph;
- vec[0].len = sizeof(ph);
- vec[1].ptr = (const u_int8_t *)(void *)dh;
- vec[1].len = cov;
- return in_cksum(vec, 2);
+ return nextproto6_cksum(ip6, (const u_int8_t *)(void *)dh,
+ dccp_csum_coverage(dh, len), IPPROTO_DCCP);
}
#endif
static int icmp6_cksum(const struct ip6_hdr *ip6, const struct icmp6_hdr *icp,
u_int len)
{
- size_t i;
- register const u_int16_t *sp;
- u_int32_t sum;
- union {
- struct {
- struct in6_addr ph_src;
- struct in6_addr ph_dst;
- u_int32_t ph_len;
- u_int8_t ph_zero[3];
- u_int8_t ph_nxt;
- } ph;
- u_int16_t pa[20];
- } phu;
-
- /* pseudo-header */
- memset(&phu, 0, sizeof(phu));
- phu.ph.ph_src = ip6->ip6_src;
- phu.ph.ph_dst = ip6->ip6_dst;
- phu.ph.ph_len = htonl(len);
- phu.ph.ph_nxt = IPPROTO_ICMPV6;
-
- sum = 0;
- for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++)
- sum += phu.pa[i];
-
- sp = (const u_int16_t *)icp;
-
- for (i = 0; i < (len & ~1); i += 2)
- sum += *sp++;
-
- if (len & 1)
- sum += htons((*(const u_int8_t *)sp) << 8);
-
- while (sum > 0xffff)
- sum = (sum & 0xffff) + (sum >> 16);
- sum = ~sum & 0xffff;
-
- return (sum);
+ return (nextproto6_cksum(ip6, (const u_int8_t *)(void *)icp, len,
+ IPPROTO_ICMPV6));
}
enum ND_RPL_CODE {
* Compute a V6-style checksum by building a pseudoheader.
*/
int
-nextproto6_cksum(const struct ip6_hdr *ip6, const u_short *data,
+nextproto6_cksum(const struct ip6_hdr *ip6, const u_int8_t *data,
u_int len, u_int next_proto)
{
struct {
vec[0].ptr = (const u_int8_t *)(void *)&ph;
vec[0].len = sizeof(ph);
- vec[1].ptr = (const u_int8_t *)(void *)data;
+ vec[1].ptr = data;
vec[1].len = len;
return in_cksum(vec, 2);
}
case IPPROTO_PIM:
- pim_print(cp, len, nextproto6_cksum(ip6, (u_short *)cp, len,
+ pim_print(cp, len, nextproto6_cksum(ip6, cp, len,
IPPROTO_PIM));
return;
#ifdef INET6
else if (IP_V(ip) == 6 && ip6->ip6_plen) {
if (TTEST2(tp->th_sport, length)) {
- sum = nextproto6_cksum(ip6, (u_short *)tp, length, IPPROTO_TCP);
+ sum = nextproto6_cksum(ip6, (const u_int8_t *)tp, length, IPPROTO_TCP);
tcp_sum = EXTRACT_16BITS(&tp->th_sum);
(void)printf(", cksum 0x%04x", tcp_sum);
static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up,
u_int len)
{
- struct {
- struct in6_addr ph_src;
- struct in6_addr ph_dst;
- u_int32_t ph_len;
- u_int8_t ph_zero[3];
- u_int8_t ph_nxt;
- } ph;
- struct cksum_vec vec[2];
-
- /* pseudo-header */
- memset(&ph, 0, sizeof(ph));
- ph.ph_src = ip6->ip6_src;
- ph.ph_dst = ip6->ip6_dst;
- ph.ph_len = htonl(len);
- ph.ph_nxt = IPPROTO_UDP;
-
- vec[0].ptr = (const u_int8_t *)(void *)&ph;
- vec[0].len = sizeof(ph);
- vec[1].ptr = (const u_int8_t *)(void *)up;
- vec[1].len = len;
- return (in_cksum(vec, 2));
+ return (nextproto6_cksum(ip6, (const u_int8_t *)(void *)up, len,
+ IPPROTO_UDP));
}
#endif