strace/tests/net-packet_mreq.c
Dmitry V. Levin 92e347b556 Add copyright headers to some files that lack them
We do our best to keep copyright headers up to date, yet
git history provides better information on this subject
and is more accurate than copyright headers.
2018-12-24 23:46:43 +00:00

110 lines
3.4 KiB
C

/*
* Copyright (c) 2018 The strace developers.
* All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "tests.h"
#include <stdio.h>
#include <sys/socket.h>
#include <linux/if_packet.h>
static const char *errstr;
static long
packet_mreq_membership(int optname, void *optval, socklen_t len)
{
long rc = setsockopt(-1, SOL_PACKET, optname, optval, len);
errstr = sprintrc(rc);
return rc;
}
static void
test_packet_mreq(const int optname, const char *const optname_str)
{
TAIL_ALLOC_OBJECT_CONST_PTR(struct packet_mreq, pmreq);
socklen_t len = sizeof(struct packet_mreq);
/* setsockopt with optname unknown */
packet_mreq_membership(-1, NULL, 0);
printf("setsockopt(-1, SOL_PACKET, %#x /* PACKET_??? */, NULL, 0) = %s\n",
-1, errstr);
/* setsockopt with mr_type unknown */
pmreq->mr_ifindex = 0;
pmreq->mr_alen = ARRAY_SIZE(pmreq->mr_address);
packet_mreq_membership(optname, pmreq, len);
printf("setsockopt(-1, SOL_PACKET, %s, {mr_ifindex=%d,"
" mr_type=%#x /* PACKET_MR_??? */, mr_alen=%d, mr_address=",
optname_str, pmreq->mr_ifindex, pmreq->mr_type, pmreq->mr_alen);
for (unsigned int i = 0; i < ARRAY_SIZE(pmreq->mr_address); i++) {
printf("%02x", pmreq->mr_address[i]);
}
printf("}, %d) = %s\n", len, errstr);
/* setsockopt with mr_type unknown and mr_alen > sizeof(mr_address) */
pmreq->mr_alen = ARRAY_SIZE(pmreq->mr_address) + 1;
packet_mreq_membership(optname, pmreq, len);
printf("setsockopt(-1, SOL_PACKET, %s, {mr_ifindex=%d,"
" mr_type=%#x /* PACKET_MR_??? */, mr_alen=%d, mr_address=",
optname_str, pmreq->mr_ifindex, pmreq->mr_type, pmreq->mr_alen);
for (unsigned int i = 0; i < ARRAY_SIZE(pmreq->mr_address); i++) {
printf("%02x", pmreq->mr_address[i]);
}
printf("}, %d) = %s\n", len, errstr);
/* setsockopt with mr_type unknown and mr_alen < sizeof(mr_address) */
pmreq->mr_alen = ARRAY_SIZE(pmreq->mr_address) - 1;
packet_mreq_membership(optname, pmreq, len);
printf("setsockopt(-1, SOL_PACKET, %s, {mr_ifindex=%d,"
" mr_type=%#x /* PACKET_MR_??? */, mr_alen=%d, mr_address=",
optname_str, pmreq->mr_ifindex, pmreq->mr_type, pmreq->mr_alen);
for (unsigned int i = 0; i < pmreq->mr_alen; i++) {
printf("%02x", pmreq->mr_address[i]);
}
printf("}, %d) = %s\n", len, errstr);
/* setsockopt with valid mr_type */
pmreq->mr_alen = ARRAY_SIZE(pmreq->mr_address);
static const struct {
unsigned short type;
const char *const type_str;
} a[] = {
{ ARG_STR(PACKET_MR_MULTICAST) },
{ ARG_STR(PACKET_MR_PROMISC) },
{ ARG_STR(PACKET_MR_ALLMULTI) },
#ifdef PACKET_MR_UNICAST
{ ARG_STR(PACKET_MR_UNICAST) },
#endif
};
for (unsigned int i = 0; i < ARRAY_SIZE(a); i++) {
pmreq->mr_type = a[i].type;
packet_mreq_membership(optname, pmreq, len);
printf("setsockopt(-1, SOL_PACKET, %s, {mr_ifindex=%d,"
" mr_type=%s, mr_alen=%d, mr_address=",
optname_str, pmreq->mr_ifindex, a[i].type_str, pmreq->mr_alen);
for (unsigned int i = 0; i < pmreq->mr_alen; i++) {
printf("%02x", pmreq->mr_address[i]);
}
printf("}, %d) = %s\n", len, errstr);
}
/* setsockopt with optlen larger than usual */
len = len + 1;
packet_mreq_membership(optname, pmreq, len);
printf("setsockopt(-1, SOL_PACKET, %s, %p,"
" %d) = %s\n", optname_str, pmreq, len, errstr);
}
int
main(void)
{
test_packet_mreq(ARG_STR(PACKET_ADD_MEMBERSHIP));
test_packet_mreq(ARG_STR(PACKET_DROP_MEMBERSHIP));
puts("+++ exited with 0 +++");
return 0;
}