embox

Форк
0
/
ndp.c 
94 строки · 2.3 Кб
1
/**
2
 * @file
3
 * @brief
4
 *
5
 * @date 27.05.13
6
 * @author Ilia Vaprol
7
 */
8

9
#include <arpa/inet.h>
10
#include <assert.h>
11
#include <errno.h>
12
#include <stddef.h>
13
#include <string.h>
14

15
#include <util/binalign.h>
16

17
#include <net/l0/net_tx.h>
18
#include <net/l3/icmpv6.h>
19
#include <net/l3/ipv6.h>
20
#include <net/l2/ethernet.h>
21
#include <net/lib/icmpv6.h>
22
#include <net/lib/ipv6.h>
23
#include <net/inetdevice.h>
24
#include <net/netdevice.h>
25
#include <net/skbuff.h>
26

27
static int ndp_xmit(struct sk_buff *skb, struct net_device *dev) {
28
	struct net_header_info hdr_info;
29

30
	assert(skb != NULL);
31
	assert(dev != NULL);
32

33
	hdr_info.type = ETH_P_IPV6;
34
	hdr_info.src_hw = dev->dev_addr;
35
	hdr_info.dst_hw = dev->broadcast;
36

37
	return net_tx(skb, &hdr_info);
38
}
39

40
int ndp_send(uint8_t type, uint8_t code, const void *body,
41
		size_t body_sz, struct net_device *dev) {
42
	struct sk_buff *skb;
43
	struct in_device *in_dev;
44
	struct in6_addr dst_ip6;
45

46
	assert(dev != NULL);
47

48
	skb = skb_alloc(dev->hdr_len + IP6_HEADER_SIZE
49
			+ ICMP6_MIN_HEADER_SIZE + body_sz);
50
	if (skb == NULL) {
51
		return -ENOMEM;
52
	}
53

54
	skb->dev = dev;
55
	skb->nh.raw = skb->mac.raw + dev->hdr_len;
56
	skb->h.raw = skb->nh.raw + IP6_HEADER_SIZE;
57

58
	in_dev = inetdev_get_by_dev(dev);
59
	assert(in_dev != NULL);
60

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

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

68
	return ndp_xmit(skb, dev);
69
}
70

71
int ndp_discover(struct net_device *dev, const void *tpa) {
72
#ifdef __clang__
73
#pragma clang diagnostic push
74
#pragma clang diagnostic ignored "-Wgnu-variable-sized-type-not-at-end"
75
#endif
76
	struct {
77
		struct ndpbody_neighbor_solicit body;
78
		struct ndpoptions_ll_addr ops;
79
		char __ops_ll_addr_storage[MAX_ADDR_LEN];
80
	} __attribute__((packed)) nbr_solicit;
81
#ifdef __clang__
82
#pragma clang diagnostic pop
83
#endif
84

85
	nbr_solicit.body.zero = 0;
86
	memcpy(&nbr_solicit.body.target, tpa, sizeof(nbr_solicit.body.target));
87
	nbr_solicit.ops.hdr.type = NDP_SOURCE_LL_ADDR;
88
	nbr_solicit.ops.hdr.len =
89
			binalign_bound(sizeof nbr_solicit.ops + dev->addr_len, 8) / 8;
90
	memcpy(nbr_solicit.ops.ll_addr, &dev->dev_addr[0], dev->addr_len);
91

92
	return ndp_send(NDP_NEIGHBOR_SOLICIT, 0, &nbr_solicit,
93
			sizeof(nbr_solicit.body) + sizeof(nbr_solicit.ops) + dev->addr_len, dev);
94
}
95

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.