Ejemplo n.º 1
0
int ndp_send(uint8_t type, uint8_t code, const void *body,
		size_t body_sz, struct net_device *dev) {
	struct sk_buff *skb;
	struct in_device *in_dev;
	struct in6_addr dst_ip6;

	assert(dev != NULL);

	skb = skb_alloc(dev->hdr_len + IP6_HEADER_SIZE
			+ ICMP6_MIN_HEADER_SIZE + body_sz);
	if (skb == NULL) {
		return -ENOMEM;
	}

	skb->dev = dev;
	skb->nh.raw = skb->mac.raw + dev->hdr_len;
	skb->h.raw = skb->nh.raw + IP6_HEADER_SIZE;

	in_dev = inetdev_get_by_dev(dev);
	assert(in_dev != NULL);

	inet_pton(AF_INET6, "ff02::1:ff02:10", &dst_ip6);
	ip6_build(skb->nh.ip6h, ICMP6_MIN_HEADER_SIZE + body_sz,
			IPPROTO_ICMPV6, 255, &in_dev->ifa6_address, &dst_ip6);

	icmp6_build(skb->h.icmp6h, type, code, body, body_sz);
	icmp6_set_check_field(skb->h.icmp6h, skb->nh.ip6h);

	return ndp_xmit(skb, dev);
}
Ejemplo n.º 2
0
static inline ip6_addr
get_ip6_ll(const void *p)
{
  return ip6_build(0xfe800000, 0, get_u32(p+0), get_u32(p+4));
}
Ejemplo n.º 3
0
static int ip6_make(const struct sock *sk,
		const struct sockaddr *to,
		size_t *data_size, struct sk_buff **out_skb) {
	size_t hdr_size, max_size;
	struct sk_buff *skb;
	struct net_device *dev;
	const struct inet6_sock *in6_sk;
	const struct sockaddr_in6 *to_in6;
	uint8_t nexthdr;
	const struct in6_addr *src_ip6;
	struct in6_addr dst_ip6;

	assert((to == NULL) || (to->sa_family == AF_INET6));
	assert(data_size != NULL);
	assert(out_skb != NULL);
	assert((sk != NULL) || (*out_skb != NULL));

	in6_sk = to_const_inet6_sock(sk);
	to_in6 = (const struct sockaddr_in6 *)to;

	assert((to_in6 == NULL)
			|| (to_in6->sin6_family == AF_INET6));

	memcpy(&dst_ip6, to_in6 != NULL ? &to_in6->sin6_addr
				: in6_sk != NULL ? &in6_sk->dst_in6.sin6_addr
				: &(*out_skb)->nh.ip6h->saddr, /* make a reply */
			sizeof dst_ip6);
	/* FIXME use route */
	if (0 == memcmp(&dst_ip6, &in6addr_loopback,
				sizeof dst_ip6)) {
		dev = netdev_get_by_name("lo");
	}
	else {
		dev = netdev_get_by_name("eth0");
	}
	assert(dev != NULL);

	assert(inetdev_get_by_dev(dev) != NULL);
	src_ip6 = &inetdev_get_by_dev(dev)->ifa6_address;

	nexthdr = in6_sk != NULL ? in6_sk->sk.opt.so_protocol
			: (*out_skb)->nh.ip6h->nexthdr;

	hdr_size = dev->hdr_len + IP6_HEADER_SIZE;
	max_size = min(dev->mtu, skb_max_size());
	if (hdr_size > max_size) {
		return -EMSGSIZE;
	}

	*data_size = min(*data_size, max_size - hdr_size);

	skb = skb_realloc(hdr_size + *data_size, *out_skb);
	if (skb == NULL) {
		return -ENOMEM;
	}

	skb->dev = dev;
	skb->nh.raw = skb->mac.raw + dev->hdr_len;
	skb->h.raw = skb->nh.raw + IP6_HEADER_SIZE;

	ip6_build(skb->nh.ip6h, *data_size, nexthdr, 64, src_ip6,
			&dst_ip6);

	*out_skb = skb;

	return 0;
}