blob: a58add3ff32ba0fad5843d882f3d84bd6643b546 [file] [log] [blame]
developer3abe1ad2022-01-24 11:13:32 +08001#include <sys/ioctl.h>
2#include <sys/socket.h>
3
4#include "atenl.h"
5
6int atenl_eth_init(struct atenl *an)
7{
8 struct sockaddr_ll addr = {};
9 struct ifreq ifr = {};
10 int ret;
11
12 memcpy(ifr.ifr_name, BRIDGE_NAME, strlen(BRIDGE_NAME));
13 ret = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_RACFG));
14 if (ret < 0) {
15 perror("socket");
16 goto out;
17 }
18 an->sock_eth = ret;
19
20 addr.sll_family = AF_PACKET;
21 addr.sll_ifindex = if_nametoindex(BRIDGE_NAME);
22
23 ret = bind(an->sock_eth, (struct sockaddr *)&addr, sizeof(addr));
24 if (ret < 0) {
25 perror("bind");
26 goto out;
27 }
28
29 ret = ioctl(an->sock_eth, SIOCGIFHWADDR, &ifr);
30 if (ret < 0) {
31 perror("ioctl(SIOCGIFHWADDR)");
32 goto out;
33 }
34
35 memcpy(an->mac_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
36 atenl_info("Open Ethernet socket success on %s, mac addr = " MACSTR "\n",
37 BRIDGE_NAME, MAC2STR(an->mac_addr));
38
39 ret = 0;
40out:
41 return ret;
42}
43
44int atenl_eth_recv(struct atenl *an, struct atenl_data *data)
45{
46 char buf[RACFG_PKT_MAX_SIZE];
47 int len = recvfrom(an->sock_eth, buf, sizeof(buf), 0, NULL, NULL);
48 struct ethhdr *hdr = (struct ethhdr *)buf;
49
50 atenl_dbg("[%d]%s: recv len = %d\n", getpid(), __func__, len);
51
52 if (len >= ETH_HLEN + RACFG_HLEN) {
53 if (hdr->h_proto == htons(ETH_P_RACFG) &&
54 (ether_addr_equal(an->mac_addr, hdr->h_dest) ||
55 is_broadcast_ether_addr(hdr->h_dest))) {
56 data->len = len;
57 memcpy(data->buf, buf, len);
58
59 return 0;
60 }
61 }
62
63 atenl_err("%s: packet len is too short\n", __func__);
64 return -EINVAL;
65}
66
67int atenl_eth_send(struct atenl *an, struct atenl_data *data)
68{
69 struct ethhdr *ehdr = (struct ethhdr *)data->buf;
70 struct sockaddr_ll addr = {};
71 int ret, len = data->len;
72
73 if (an->unicast)
74 ether_addr_copy(ehdr->h_dest, ehdr->h_source);
75 else
76 eth_broadcast_addr(ehdr->h_dest);
77
78 ether_addr_copy(ehdr->h_source, an->mac_addr);
79 ehdr->h_proto = htons(ETH_P_RACFG);
80
81 if (len < 60)
82 len = 60;
83 else if (len > 1514) {
84 atenl_err("%s: response ethernet length is too long\n", __func__);
85 return -1;
86 }
87
88 atenl_dbg_print_data(data, __func__, len);
89
90 addr.sll_family = PF_PACKET;
91 addr.sll_protocol = htons(ETH_P_RACFG);
92 addr.sll_ifindex = if_nametoindex(BRIDGE_NAME);
93 addr.sll_pkttype = PACKET_BROADCAST;
94 addr.sll_hatype = ARPHRD_ETHER;
95 addr.sll_halen = ETH_ALEN;
96 memset(addr.sll_addr, 0, 8);
97 eth_broadcast_addr(addr.sll_addr);
98
99 ret = sendto(an->sock_eth, data->buf, len, 0,
100 (struct sockaddr *)&addr, sizeof(addr));
101 if (ret < 0) {
102 perror("sendto");
103 return ret;
104 }
105
106 atenl_dbg("[%d]%s: send length = %d\n", getpid(), __func__, len);
107
108 return 0;
109}