You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
2.9 KiB
138 lines
2.9 KiB
/**
|
|
* Copyright (C) 2018 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#define _GNU_SOURCE
|
|
#define ARRAY_SIZE(__a) (sizeof(__a) / sizeof((__a)[0]))
|
|
#include <errno.h>
|
|
#include <linux/filter.h>
|
|
#include <linux/netlink.h>
|
|
#include <stdlib.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
#include <unistd.h>
|
|
|
|
static struct sock_filter nlattr[] = {
|
|
{ 0000, 0, 0, 0x87654321 },
|
|
{ 0x01, 0, 0, 0x0000002a },
|
|
{ 0x20, 0, 0, 0xfffff00c },
|
|
{ 0x16, 0, 0, 0000000000 },
|
|
};
|
|
|
|
static struct sock_fprog bpf_nlattr = {
|
|
.len = ARRAY_SIZE(nlattr),
|
|
.filter = nlattr,
|
|
};
|
|
|
|
static struct sock_filter nlattr_nest[] = {
|
|
{ 0000, 0, 0, 0x87654321 },
|
|
{ 0x01, 0, 0, 0x0000002a },
|
|
{ 0x20, 0, 0, 0xfffff010 },
|
|
{ 0x16, 0, 0, 0000000000 },
|
|
};
|
|
|
|
static struct sock_fprog bpf_nlattr_nest = {
|
|
.len = ARRAY_SIZE(nlattr_nest),
|
|
.filter = nlattr_nest,
|
|
};
|
|
|
|
static struct sock_filter nest_rem[] = {
|
|
{ 0000, 0, 0, 0000000000 },
|
|
{ 0x01, 0, 0, 0x0000002a },
|
|
{ 0x20, 0, 0, 0xfffff010 },
|
|
{ 0x16, 0, 0, 0000000000 },
|
|
};
|
|
|
|
static struct sock_fprog bpf_nest_rem = {
|
|
.len = ARRAY_SIZE(nest_rem),
|
|
.filter = nest_rem,
|
|
};
|
|
|
|
static int send_receive_packet(int s[2], const void* pkt, int len)
|
|
{
|
|
char tmp[1024];
|
|
ssize_t ret;
|
|
|
|
ret = send(s[1], pkt, len, 0);
|
|
if (ret != len) {
|
|
return -1;
|
|
}
|
|
|
|
ret = recv(s[0], tmp, len, MSG_DONTWAIT);
|
|
if (ret < 0 && errno == EAGAIN)
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
struct nlattr chkrem[2] = {
|
|
[0] = {
|
|
.nla_len = 0xfff0,
|
|
.nla_type = 0,
|
|
},
|
|
[1] = {
|
|
.nla_len = sizeof(struct nlattr),
|
|
.nla_type = 42,
|
|
},
|
|
};
|
|
__u16 chksz = 0xfefe;
|
|
int s[2], ret;
|
|
|
|
ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, s);
|
|
if (ret) {
|
|
return -1;
|
|
}
|
|
|
|
ret = setsockopt(s[0], SOL_SOCKET, SO_ATTACH_FILTER,
|
|
&bpf_nlattr, sizeof(bpf_nlattr));
|
|
if (ret < 0) {
|
|
return -1;
|
|
}
|
|
|
|
ret = send_receive_packet(s, &chksz, sizeof(chksz));
|
|
if (ret) {
|
|
ret = 113;
|
|
goto out;
|
|
}
|
|
|
|
ret = setsockopt(s[0], SOL_SOCKET, SO_ATTACH_FILTER,
|
|
&bpf_nlattr_nest, sizeof(bpf_nlattr_nest));
|
|
if (ret < 0) {
|
|
return -1;
|
|
}
|
|
|
|
ret = send_receive_packet(s, &chksz, sizeof(chksz));
|
|
if (ret) {
|
|
ret = 113;
|
|
goto out;
|
|
}
|
|
|
|
ret = setsockopt(s[0], SOL_SOCKET, SO_ATTACH_FILTER,
|
|
&bpf_nest_rem, sizeof(bpf_nest_rem));
|
|
if (ret < 0) {
|
|
return -1;
|
|
}
|
|
|
|
ret = send_receive_packet(s, chkrem, sizeof(chkrem));
|
|
if(ret){
|
|
ret = 113;
|
|
}
|
|
|
|
out:
|
|
return ret;
|
|
}
|