blob: 54a8d2cbf36f3e13611289442eebcc8324ac5192 [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{
developer5698c9c2022-05-30 16:40:23 +080046 struct ethhdr *hdr;
47 int len;
developer3abe1ad2022-01-24 11:13:32 +080048
developer5698c9c2022-05-30 16:40:23 +080049 len = recvfrom(an->sock_eth, data->buf, sizeof(data->buf), 0, NULL, NULL);
developer3abe1ad2022-01-24 11:13:32 +080050
developer5698c9c2022-05-30 16:40:23 +080051 if (len < ETH_HLEN + RACFG_HLEN) {
52 atenl_err("packet len is too short: %d\n", len);
53 return -EINVAL;
54 }
55
56 hdr = (struct ethhdr *)data->buf;
57 if (hdr->h_proto != htons(ETH_P_RACFG)) {
58 atenl_err("invalid protocol type\n");
59 return -EINVAL;
60 }
developer3abe1ad2022-01-24 11:13:32 +080061
developer5698c9c2022-05-30 16:40:23 +080062 if (!ether_addr_equal(an->mac_addr, hdr->h_dest) &&
63 !is_broadcast_ether_addr(hdr->h_dest)) {
64 atenl_err("invalid dest MAC\n");
65 return -EINVAL;
developer3abe1ad2022-01-24 11:13:32 +080066 }
67
developer5698c9c2022-05-30 16:40:23 +080068 data->len = len;
69
70 return 0;
developer3abe1ad2022-01-24 11:13:32 +080071}
72
73int atenl_eth_send(struct atenl *an, struct atenl_data *data)
74{
75 struct ethhdr *ehdr = (struct ethhdr *)data->buf;
76 struct sockaddr_ll addr = {};
77 int ret, len = data->len;
78
79 if (an->unicast)
80 ether_addr_copy(ehdr->h_dest, ehdr->h_source);
81 else
82 eth_broadcast_addr(ehdr->h_dest);
83
84 ether_addr_copy(ehdr->h_source, an->mac_addr);
85 ehdr->h_proto = htons(ETH_P_RACFG);
86
87 if (len < 60)
88 len = 60;
89 else if (len > 1514) {
developer5698c9c2022-05-30 16:40:23 +080090 atenl_err("response ethernet length is too long\n");
developer3abe1ad2022-01-24 11:13:32 +080091 return -1;
92 }
93
developer5698c9c2022-05-30 16:40:23 +080094 atenl_dbg_print_data(data->buf, __func__, len);
developer3abe1ad2022-01-24 11:13:32 +080095
96 addr.sll_family = PF_PACKET;
97 addr.sll_protocol = htons(ETH_P_RACFG);
98 addr.sll_ifindex = if_nametoindex(BRIDGE_NAME);
99 addr.sll_pkttype = PACKET_BROADCAST;
100 addr.sll_hatype = ARPHRD_ETHER;
101 addr.sll_halen = ETH_ALEN;
102 memset(addr.sll_addr, 0, 8);
103 eth_broadcast_addr(addr.sll_addr);
104
105 ret = sendto(an->sock_eth, data->buf, len, 0,
106 (struct sockaddr *)&addr, sizeof(addr));
107 if (ret < 0) {
108 perror("sendto");
109 return ret;
110 }
111
developer3abe1ad2022-01-24 11:13:32 +0800112 return 0;
113}