]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/lldp-network.c
122688ac3c8ca33d909370af927f47b34e2e6dad
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 Copyright (C) 2014 Tom Gundersen
4 Copyright (C) 2014 Susant Sahani
7 #include <linux/filter.h>
8 #include <netinet/if_ether.h>
11 #include "lldp-network.h"
12 #include "socket-util.h"
14 int lldp_network_bind_raw_socket(int ifindex
) {
16 static const struct sock_filter filter
[] = {
17 BPF_STMT(BPF_LD
+ BPF_W
+ BPF_ABS
, offsetof(struct ethhdr
, h_dest
)), /* A <- 4 bytes of destination MAC */
18 BPF_JUMP(BPF_JMP
+ BPF_JEQ
+ BPF_K
, 0x0180c200, 1, 0), /* A != 01:80:c2:00 */
19 BPF_STMT(BPF_RET
+ BPF_K
, 0), /* drop packet */
20 BPF_STMT(BPF_LD
+ BPF_H
+ BPF_ABS
, offsetof(struct ethhdr
, h_dest
) + 4), /* A <- remaining 2 bytes of destination MAC */
21 BPF_JUMP(BPF_JMP
+ BPF_JEQ
+ BPF_K
, 0x0000, 3, 0), /* A != 00:00 */
22 BPF_JUMP(BPF_JMP
+ BPF_JEQ
+ BPF_K
, 0x0003, 2, 0), /* A != 00:03 */
23 BPF_JUMP(BPF_JMP
+ BPF_JEQ
+ BPF_K
, 0x000e, 1, 0), /* A != 00:0e */
24 BPF_STMT(BPF_RET
+ BPF_K
, 0), /* drop packet */
25 BPF_STMT(BPF_LD
+ BPF_H
+ BPF_ABS
, offsetof(struct ethhdr
, h_proto
)), /* A <- protocol */
26 BPF_JUMP(BPF_JMP
+ BPF_JEQ
+ BPF_K
, ETHERTYPE_LLDP
, 1, 0), /* A != ETHERTYPE_LLDP */
27 BPF_STMT(BPF_RET
+ BPF_K
, 0), /* drop packet */
28 BPF_STMT(BPF_RET
+ BPF_K
, (uint32_t) -1), /* accept packet */
31 static const struct sock_fprog fprog
= {
32 .len
= ELEMENTSOF(filter
),
33 .filter
= (struct sock_filter
*) filter
,
36 struct packet_mreq mreq
= {
37 .mr_ifindex
= ifindex
,
38 .mr_type
= PACKET_MR_MULTICAST
,
40 .mr_address
= { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x00 }
43 union sockaddr_union saddrll
= {
44 .ll
.sll_family
= AF_PACKET
,
45 .ll
.sll_ifindex
= ifindex
,
48 _cleanup_close_
int fd
= -1;
53 fd
= socket(PF_PACKET
, SOCK_RAW
|SOCK_CLOEXEC
|SOCK_NONBLOCK
,
54 htobe16(ETHERTYPE_LLDP
));
58 r
= setsockopt(fd
, SOL_SOCKET
, SO_ATTACH_FILTER
, &fprog
, sizeof(fprog
));
62 r
= setsockopt(fd
, SOL_PACKET
, PACKET_ADD_MEMBERSHIP
, &mreq
, sizeof(mreq
));
66 mreq
.mr_address
[ETH_ALEN
- 1] = 0x03;
67 r
= setsockopt(fd
, SOL_PACKET
, PACKET_ADD_MEMBERSHIP
, &mreq
, sizeof(mreq
));
71 mreq
.mr_address
[ETH_ALEN
- 1] = 0x0E;
72 r
= setsockopt(fd
, SOL_PACKET
, PACKET_ADD_MEMBERSHIP
, &mreq
, sizeof(mreq
));
76 r
= bind(fd
, &saddrll
.sa
, sizeof(saddrll
.ll
));