Пример #1
0
static int ip6_rcv(struct sk_buff *skb, struct net_device *dev) {
	ip6hdr_t *ip6h = ip6_hdr(skb);
	const struct net_proto *nproto;

	if (ip6h->version != 6) {
		dev->stats.rx_err++;
		skb_free(skb);
		return 0; /* error: invalid hdr */
	}

	if (skb->dev->hdr_len + IP6_HEADER_SIZE
			+ ntohs(ip6h->payload_len) > skb->len) {
		dev->stats.rx_length_errors++;
		skb_free(skb);
		return 0; /* error: invalid length */
	}

	/* Check recipiant */
	assert(skb->dev != NULL);
	assert(inetdev_get_by_dev(skb->dev) != NULL);
	if (0 != memcmp(&inetdev_get_by_dev(skb->dev)->ifa6_address,
				&skb->nh.ip6h->daddr, sizeof(struct in6_addr))) {
//		skb_free(skb);
//		return 0; /* error: not for us */
	}

	/* Setup transport layer header */
	skb->h.raw = skb->nh.raw + IP6_HEADER_SIZE;

	nproto = net_proto_lookup(ETH_P_IPV6, ip6h->nexthdr);
	if (nproto != NULL) {
		return nproto->handle(skb);
	}

//	printk("ipv6 packet accepted, %#x\n", ip6h->nexthdr);

	skb_free(skb);
	return 0; /* error: nobody wants this packet */
}
Пример #2
0
static int udp_rcv(struct sk_buff *skb) {
	struct sock *sk;

	assert(skb != NULL);
	assert(ip_check_version(ip_hdr(skb))
			|| ip6_check_version(ip6_hdr(skb)));

	/* Check CRC */
	if (MODOPS_VERIFY_CHKSUM) {
		uint16_t old_check;
		old_check = skb->h.uh->check;
		udp_set_check_field(skb->h.uh, skb->nh.raw);
		if (old_check != skb->h.uh->check) {
			return 0; /* error: bad checksum */
		}
	}

	sk = sock_lookup(NULL, udp_sock_ops,
			ip_check_version(ip_hdr(skb))
				? udp4_rcv_tester : udp6_rcv_tester,
			skb);
	if (sk != NULL) {
		if (ip_check_version(ip_hdr(skb))
				? udp4_accept_dst(sk, skb)
				: udp6_accept_dst(sk, skb)) {
			sock_rcv(sk, skb, skb->h.raw + UDP_HEADER_SIZE,
					udp_data_length(udp_hdr(skb)));
		}
		else {
			skb_free(skb);
		}
	}
	else {
		icmp_discard(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH);
	}

	return 0;
}