Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (c) 2017 JingPiao Chen <chenjingpiao (at) gmail.com>
      3  * Copyright (c) 2017 The strace developers.
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. The name of the author may not be used to endorse or promote products
     15  *    derived from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include "tests.h"
     30 
     31 #include <stdio.h>
     32 #include <string.h>
     33 #include <stdint.h>
     34 #include <net/if.h>
     35 #include "test_nlattr.h"
     36 #include <sys/socket.h>
     37 #include <linux/filter.h>
     38 #include <linux/packet_diag.h>
     39 #include <linux/rtnetlink.h>
     40 #include <linux/sock_diag.h>
     41 
     42 static void
     43 init_packet_diag_msg(struct nlmsghdr *const nlh, const unsigned int msg_len)
     44 {
     45 	SET_STRUCT(struct nlmsghdr, nlh,
     46 		.nlmsg_len = msg_len,
     47 		.nlmsg_type = SOCK_DIAG_BY_FAMILY,
     48 		.nlmsg_flags = NLM_F_DUMP
     49 	);
     50 
     51 	struct packet_diag_msg *const msg = NLMSG_DATA(nlh);
     52 	SET_STRUCT(struct packet_diag_msg, msg,
     53 		.pdiag_family = AF_PACKET,
     54 		.pdiag_type = SOCK_STREAM
     55 	);
     56 }
     57 
     58 static void
     59 print_packet_diag_msg(const unsigned int msg_len)
     60 {
     61 	printf("{len=%u, type=SOCK_DIAG_BY_FAMILY"
     62 	       ", flags=NLM_F_DUMP, seq=0, pid=0}"
     63 	       ", {pdiag_family=AF_PACKET"
     64 	       ", pdiag_type=SOCK_STREAM, pdiag_num=0"
     65 	       ", pdiag_ino=0, pdiag_cookie=[0, 0]}",
     66 	       msg_len);
     67 }
     68 
     69 static void
     70 print_packet_diag_mclist(const struct packet_diag_mclist *const dml)
     71 {
     72 	printf("{pdmc_index=" IFINDEX_LO_STR);
     73 	PRINT_FIELD_U(", ", *dml, pdmc_count);
     74 	PRINT_FIELD_U(", ", *dml, pdmc_type);
     75 	PRINT_FIELD_U(", ", *dml, pdmc_alen);
     76 	printf(", pdmc_addr=");
     77 	print_quoted_hex(dml->pdmc_addr, dml->pdmc_alen);
     78 	printf("}");
     79 }
     80 
     81 static const struct sock_filter filter[] = {
     82 	BPF_STMT(BPF_LD|BPF_B|BPF_ABS, SKF_AD_OFF+SKF_AD_PKTTYPE),
     83 	BPF_STMT(BPF_RET|BPF_K, 0x2a)
     84 };
     85 
     86 static void
     87 print_sock_filter(const struct sock_filter *const f)
     88 {
     89 	if (f == filter)
     90 		printf("BPF_STMT(BPF_LD|BPF_B|BPF_ABS"
     91 		       ", SKF_AD_OFF+SKF_AD_PKTTYPE)");
     92 	else
     93 		printf("BPF_STMT(BPF_RET|BPF_K, 0x2a)");
     94 }
     95 
     96 int
     97 main(void)
     98 {
     99 	skip_if_unavailable("/proc/self/fd/");
    100 
    101 	int fd = create_nl_socket(NETLINK_SOCK_DIAG);
    102 	const unsigned int hdrlen = sizeof(struct packet_diag_msg);
    103 	void *const nlh0 = tail_alloc(NLMSG_SPACE(hdrlen));
    104 
    105 	static char pattern[4096];
    106 	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
    107 
    108 	static const struct packet_diag_info pinfo = {
    109 		.pdi_index = 0xabcddafa,
    110 		.pdi_version = 0xbabcdafb,
    111 		.pdi_reserve = 0xcfaacdaf,
    112 		.pdi_copy_thresh = 0xdabacdaf,
    113 		.pdi_tstamp = 0xeafbaadf,
    114 		.pdi_flags = PDI_RUNNING
    115 	};
    116 	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
    117 			   init_packet_diag_msg, print_packet_diag_msg,
    118 			   PACKET_DIAG_INFO, pattern, pinfo,
    119 			   PRINT_FIELD_U("{", pinfo, pdi_index);
    120 			   PRINT_FIELD_U(", ", pinfo, pdi_version);
    121 			   PRINT_FIELD_U(", ", pinfo, pdi_reserve);
    122 			   PRINT_FIELD_U(", ", pinfo, pdi_copy_thresh);
    123 			   PRINT_FIELD_U(", ", pinfo, pdi_tstamp);
    124 			   printf(", pdi_flags=PDI_RUNNING}"));
    125 
    126 	const struct packet_diag_mclist dml[] = {
    127 		{
    128 			.pdmc_index = ifindex_lo(),
    129 			.pdmc_count = 0xabcdaefc,
    130 			.pdmc_type = 0xcdaf,
    131 			.pdmc_alen = 4,
    132 			.pdmc_addr = "1234"
    133 		},
    134 		{
    135 			.pdmc_index = ifindex_lo(),
    136 			.pdmc_count = 0xdaefeafc,
    137 			.pdmc_type = 0xadef,
    138 			.pdmc_alen = 4,
    139 			.pdmc_addr = "5678"
    140 		}
    141 	};
    142 	TEST_NLATTR_ARRAY(fd, nlh0, hdrlen,
    143 			  init_packet_diag_msg, print_packet_diag_msg,
    144 			  PACKET_DIAG_MCLIST, pattern, dml,
    145 			  print_packet_diag_mclist);
    146 
    147 	static const struct packet_diag_ring pdr = {
    148 		.pdr_block_size = 0xabcdafed,
    149 		.pdr_block_nr = 0xbcadefae,
    150 		.pdr_frame_size = 0xcabdfeac,
    151 		.pdr_frame_nr = 0xdeaeadef,
    152 		.pdr_retire_tmo = 0xedbafeac,
    153 		.pdr_sizeof_priv = 0xfeadeacd,
    154 		.pdr_features = 0xadebadea
    155 	};
    156 	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
    157 			   init_packet_diag_msg, print_packet_diag_msg,
    158 			   PACKET_DIAG_RX_RING, pattern, pdr,
    159 			   PRINT_FIELD_U("{", pdr, pdr_block_size);
    160 			   PRINT_FIELD_U(", ", pdr, pdr_block_nr);
    161 			   PRINT_FIELD_U(", ", pdr, pdr_frame_size);
    162 			   PRINT_FIELD_U(", ", pdr, pdr_frame_nr);
    163 			   PRINT_FIELD_U(", ", pdr, pdr_retire_tmo);
    164 			   PRINT_FIELD_U(", ", pdr, pdr_sizeof_priv);
    165 			   PRINT_FIELD_U(", ", pdr, pdr_features);
    166 			   printf("}"));
    167 
    168 	TEST_NLATTR_ARRAY(fd, nlh0, hdrlen,
    169 			  init_packet_diag_msg, print_packet_diag_msg,
    170 			  PACKET_DIAG_FILTER, pattern, filter,
    171 			  print_sock_filter);
    172 
    173 	printf("+++ exited with 0 +++\n");
    174 	return 0;
    175 }
    176