Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

ip6.c

Go to the documentation of this file.
00001 /*
00002  * ip6.c
00003  *
00004  * Copyright (c) 2002 Dug Song <dugsong@monkey.org>
00005  *
00006  * $Id: ip6.c,v 1.2 2005/01/23 07:36:54 dugsong Exp $
00007  */
00008 
00009 #include "config.h"
00010 
00011 #include "dnet.h"
00012 
00013 #define IP6_IS_EXT(n)   \
00014         ((n) == IP_PROTO_HOPOPTS || (n) == IP_PROTO_DSTOPTS || \
00015          (n) == IP_PROTO_ROUTING || (n) == IP_PROTO_FRAGMENT)
00016 
00017 void
00018 ip6_checksum(void *buf, size_t len)
00019 {
00020         struct ip6_hdr *ip6 = (struct ip6_hdr *)buf;
00021         struct ip6_ext_hdr *ext;
00022         u_char *p, nxt;
00023         int i, sum;
00024         
00025         nxt = ip6->ip6_nxt;
00026         
00027         for (i = IP6_HDR_LEN; IP6_IS_EXT(nxt); i += (ext->ext_len + 1) << 3) {
00028                 if (i >= (int)len) return;
00029                 ext = (struct ip6_ext_hdr *)((u_char *)buf + i);
00030                 nxt = ext->ext_nxt;
00031         }
00032         p = (u_char *)buf + i;
00033         len -= i;
00034         
00035         if (nxt == IP_PROTO_TCP) {
00036                 struct tcp_hdr *tcp = (struct tcp_hdr *)p;
00037                 
00038                 if (len >= TCP_HDR_LEN) {
00039                         tcp->th_sum = 0;
00040                         sum = ip_cksum_add(tcp, len, 0) + htons(nxt + len);
00041                         sum = ip_cksum_add(&ip6->ip6_src, 32, sum);
00042                         tcp->th_sum = ip_cksum_carry(sum);
00043                 }
00044         } else if (nxt == IP_PROTO_UDP) {
00045                 struct udp_hdr *udp = (struct udp_hdr *)p;
00046 
00047                 if (len >= UDP_HDR_LEN) {
00048                         udp->uh_sum = 0;
00049                         sum = ip_cksum_add(udp, len, 0) + htons(nxt + len);
00050                         sum = ip_cksum_add(&ip6->ip6_src, 32, sum);
00051                         if ((udp->uh_sum = ip_cksum_carry(sum)) == 0)
00052                                 udp->uh_sum = 0xffff;
00053                 }
00054         } else if (nxt == IP_PROTO_ICMPV6) {
00055                 struct icmp_hdr *icmp = (struct icmp_hdr *)p;
00056 
00057                 if (len >= ICMP_HDR_LEN) {
00058                         icmp->icmp_cksum = 0;
00059                         sum = ip_cksum_add(icmp, len, 0) + htons(nxt + len);
00060                         sum = ip_cksum_add(&ip6->ip6_src, 32, sum);
00061                         icmp->icmp_cksum = ip_cksum_carry(sum);
00062                 }               
00063         } else if (nxt == IP_PROTO_ICMP || nxt == IP_PROTO_IGMP) {
00064                 struct icmp_hdr *icmp = (struct icmp_hdr *)p;
00065                 
00066                 if (len >= ICMP_HDR_LEN) {
00067                         icmp->icmp_cksum = 0;
00068                         sum = ip_cksum_add(icmp, len, 0);
00069                         icmp->icmp_cksum = ip_cksum_carry(sum);
00070                 }
00071         }
00072 }

Generated on Sun May 14 14:51:12 2006 by  doxygen 1.4.2