00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <linux/errno.h>
00020 #include <linux/types.h>
00021 #include <linux/socket.h>
00022 #include <linux/sockios.h>
00023 #include <linux/sched.h>
00024 #include <linux/net.h>
00025 #include <linux/netdevice.h>
00026 #include <linux/in6.h>
00027 #include <linux/icmpv6.h>
00028
00029 #include <net/sock.h>
00030 #include <net/snmp.h>
00031
00032 #include <net/ipv6.h>
00033 #include <net/protocol.h>
00034 #include <net/transp_v6.h>
00035 #include <net/rawv6.h>
00036 #include <net/ndisc.h>
00037 #include <net/ip6_route.h>
00038 #include <net/addrconf.h>
00039
00040
00041 int ipv6_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
00042 {
00043 struct ipv6hdr *hdr;
00044 u32 pkt_len;
00045
00046 if (skb->pkt_type == PACKET_OTHERHOST)
00047 goto drop;
00048
00049 ipv6_statistics.Ip6InReceives++;
00050
00051
00052
00053
00054 ((struct inet6_skb_parm *)skb->cb)->iif = dev->ifindex;
00055
00056 hdr = skb->nh.ipv6h;
00057
00058 if (skb->len < sizeof(struct ipv6hdr) || hdr->version != 6)
00059 goto err;
00060
00061 pkt_len = ntohs(hdr->payload_len);
00062
00063
00064 if (pkt_len || hdr->nexthdr != NEXTHDR_HOP) {
00065 if (pkt_len + sizeof(struct ipv6hdr) > skb->len)
00066 goto truncated;
00067 skb_trim(skb, pkt_len + sizeof(struct ipv6hdr));
00068 }
00069
00070 if (hdr->nexthdr == NEXTHDR_HOP) {
00071 skb->h.raw = (u8*)(hdr+1);
00072 if (!ipv6_parse_hopopts(skb, &hdr->nexthdr)) {
00073 ipv6_statistics.Ip6InHdrErrors++;
00074 return 0;
00075 }
00076 }
00077
00078 if (skb->dst == NULL)
00079 ip6_route_input(skb);
00080
00081 return skb->dst->input(skb);
00082
00083 truncated:
00084 ipv6_statistics.Ip6InTruncatedPkts++;
00085 err:
00086 ipv6_statistics.Ip6InHdrErrors++;
00087 drop:
00088 kfree_skb(skb);
00089 return 0;
00090 }
00091
00092
00093
00094
00095
00096 static __inline__ int icmpv6_filter(struct sock *sk, struct sk_buff *skb)
00097 {
00098 struct icmp6hdr *icmph;
00099 struct raw6_opt *opt;
00100 int bit_nr;
00101
00102 opt = &sk->tp_pinfo.tp_raw;
00103 icmph = (struct icmp6hdr *) skb->h.raw;
00104 bit_nr = icmph->icmp6_type;
00105 if (bit_nr >= (8 * 32))
00106 return 0;
00107 return ((opt->filter.data[bit_nr >> 5] & (1 << bit_nr)) != 0);
00108 }
00109
00110
00111
00112
00113
00114
00115 static struct sock * ipv6_raw_deliver(struct sk_buff *skb,
00116 int nexthdr, unsigned long len)
00117 {
00118 struct in6_addr *saddr;
00119 struct in6_addr *daddr;
00120 struct sock *sk, *sk2;
00121 __u8 hash;
00122
00123 saddr = &skb->nh.ipv6h->saddr;
00124 daddr = saddr + 1;
00125
00126 hash = nexthdr & (MAX_INET_PROTOS - 1);
00127
00128 sk = raw_v6_htable[hash];
00129
00130
00131
00132
00133
00134
00135 if (sk == NULL)
00136 return NULL;
00137
00138 sk = raw_v6_lookup(sk, nexthdr, daddr, saddr);
00139
00140 if (sk) {
00141 sk2 = sk;
00142
00143 while ((sk2 = raw_v6_lookup(sk2->next, nexthdr, daddr, saddr))) {
00144 struct sk_buff *buff;
00145
00146 if (nexthdr == IPPROTO_ICMPV6 &&
00147 icmpv6_filter(sk2, skb))
00148 continue;
00149
00150 buff = skb_clone(skb, GFP_ATOMIC);
00151 if (buff)
00152 rawv6_rcv(sk2, buff, len);
00153 }
00154 }
00155
00156 if (sk && nexthdr == IPPROTO_ICMPV6 && icmpv6_filter(sk, skb))
00157 sk = NULL;
00158
00159 return sk;
00160 }
00161
00162
00163
00164
00165
00166 int ip6_input(struct sk_buff *skb)
00167 {
00168 struct ipv6hdr *hdr = skb->nh.ipv6h;
00169 struct inet6_protocol *ipprot;
00170 struct sock *raw_sk;
00171 __u8 *nhptr;
00172 int nexthdr;
00173 int found = 0;
00174 u8 hash;
00175 int len;
00176
00177 skb->h.raw = skb->nh.raw + sizeof(struct ipv6hdr);
00178
00179
00180
00181
00182
00183 nexthdr = hdr->nexthdr;
00184 nhptr = &hdr->nexthdr;
00185
00186
00187 if (nexthdr == NEXTHDR_HOP) {
00188 nhptr = (u8*)(hdr+1);
00189 nexthdr = *nhptr;
00190 skb->h.raw += (nhptr[1]+1)<<3;
00191 }
00192
00193
00194
00195
00196
00197 if (nexthdr != IPPROTO_TCP && nexthdr != IPPROTO_UDP) {
00198 nhptr = ipv6_parse_exthdrs(&skb, nhptr);
00199 if (nhptr == NULL)
00200 return 0;
00201 nexthdr = *nhptr;
00202 hdr = skb->nh.ipv6h;
00203 }
00204 len = skb->tail - skb->h.raw;
00205
00206 raw_sk = ipv6_raw_deliver(skb, nexthdr, len);
00207
00208 hash = nexthdr & (MAX_INET_PROTOS - 1);
00209 for (ipprot = (struct inet6_protocol *) inet6_protos[hash];
00210 ipprot != NULL;
00211 ipprot = (struct inet6_protocol *) ipprot->next) {
00212 struct sk_buff *buff = skb;
00213
00214 if (ipprot->protocol != nexthdr)
00215 continue;
00216
00217 if (ipprot->copy || raw_sk)
00218 buff = skb_clone(skb, GFP_ATOMIC);
00219
00220 ipprot->handler(buff, len);
00221 found = 1;
00222 }
00223
00224 if (raw_sk) {
00225 rawv6_rcv(raw_sk, skb, len);
00226 found = 1;
00227 }
00228
00229
00230
00231
00232 if (!found) {
00233 ipv6_statistics.Ip6InUnknownProtos++;
00234 icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, nhptr);
00235 }
00236
00237 return 0;
00238 }
00239
00240 int ip6_mc_input(struct sk_buff *skb)
00241 {
00242 struct ipv6hdr *hdr;
00243 int deliver = 0;
00244 int discard = 1;
00245
00246 ipv6_statistics.Ip6InMcastPkts++;
00247
00248 hdr = skb->nh.ipv6h;
00249 if (ipv6_chk_mcast_addr(skb->dev, &hdr->daddr))
00250 deliver = 1;
00251
00252
00253
00254
00255 #if 0
00256 if (ipv6_config.multicast_route) {
00257 int addr_type;
00258
00259 addr_type = ipv6_addr_type(&hdr->daddr);
00260
00261 if (!(addr_type & (IPV6_ADDR_LOOPBACK | IPV6_ADDR_LINKLOCAL))) {
00262 struct sk_buff *skb2;
00263 struct dst_entry *dst;
00264
00265 dst = skb->dst;
00266
00267 if (deliver) {
00268 skb2 = skb_clone(skb, GFP_ATOMIC);
00269 } else {
00270 discard = 0;
00271 skb2 = skb;
00272 }
00273
00274 dst->output(skb2);
00275 }
00276 }
00277 #endif
00278
00279 if (deliver) {
00280 discard = 0;
00281 ip6_input(skb);
00282 }
00283
00284 if (discard)
00285 kfree_skb(skb);
00286
00287 return 0;
00288 }