1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
#include "cethcan.h"
#include <net/if.h>
#include <net/ethernet.h>
#include <netpacket/packet.h>
#define ETHER_PROTO 0x88b7
#define ETHER_MCADDR 0xff, 0x3a, 0xf6, 'C', 'A', 'N'
struct ether {
struct can_user *u;
struct event *ev;
char *ifname;
int ifindex;
int sock;
};
static void ether_can_handler(void *arg, struct can_message *msg)
{
}
static void ether_sock_handler(int sock, short event, void *arg)
{
}
int ether_init(json_t *config)
{
struct ether *e;
const char *iface;
int ifindex;
struct packet_mreq pmr = {
.mr_type = PACKET_MR_MULTICAST,
.mr_alen = ETH_ALEN,
.mr_address = { ETHER_MCADDR },
};
if (!json_is_object(config)) {
lprintf("ethernet config must be an object/dictionary");
return 1;
}
if (!json_is_string(json_object_get(config, "interface"))) {
lprintf("ethernet config must have an 'interface' key");
return 1;
}
iface = json_string_value(json_object_get(config, "interface"));
ifindex = if_nametoindex(iface);
if (ifindex == 0) {
lprintf("ethernet interface '%s' error: %s",
iface, strerror(errno));
return 1;
}
e = calloc(sizeof(*e), 1);
e->ifname = strdup(iface);
e->ifindex = ifindex;
e->sock = socket(AF_PACKET, SOCK_RAW, htons(ETHER_PROTO));
if (e->sock == -1) {
lprintf("ethernet interface '%s' socket() error: %s",
iface, strerror(errno));
return 1;
}
pmr.mr_ifindex = ifindex;
if (setsockopt(e->sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
&pmr, sizeof(pmr))) {
lprintf("ethernet interface '%s' multicast join error: %s",
iface, strerror(errno));
return 1;
}
e->u = can_register_alloc(e, ether_can_handler, "ether[%s]", iface);
e->ev = event_new(ev_base, e->sock, EV_READ | EV_PERSIST, ether_sock_handler, e);
event_add(e->ev, NULL);
return 0;
}
|