2 * Copyright (c) 2012 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <sys/sockio.h>
32 #include <sys/ioctl.h>
33 #include <net/pktap.h>
40 const char *ifname
= NULL
;
41 unsigned int ifindex
= 0;
43 int num_filter_entries
= 0;
44 struct pktap_filter set_filter
[PKTAP_MAX_FILTERS
];
46 static const char *parameters_format
= " %-24s %s\n";
51 printf("# usage: %s -i <ifname> -g -p <filter_rule> -s <filter_rule> -h\n", s
);
52 printf(" Get or set filtering rules on a pktap interface\n");
53 printf(" Options:\n");
54 printf(parameters_format
, "-h", "display this help");
55 printf(parameters_format
, "-i <ifname>", "name pktap interface");
56 printf(parameters_format
, "-g", "get filter rules");
57 printf(parameters_format
, "-p <filter_rule> param", "add a pass rule");
58 printf(parameters_format
, "-s <filter_rule> param", "add a skip rule");
59 printf(" Format of <filter_rule> parameter:\n");
60 printf(parameters_format
, "type <iftype>", "interfaces of given type");
61 printf(parameters_format
, "", "use 0 for any interface type");
62 printf(parameters_format
, "name <ifname>", "interface of given name");
66 print_filter_entry(struct pktap_filter
*filter
)
68 printf("filter_op: %u filter_param %u ", filter
->filter_op
, filter
->filter_param
);
69 if (filter
->filter_param
== PKTAP_FILTER_PARAM_IF_TYPE
)
70 printf("%u", filter
->filter_param_if_type
);
71 else if (filter
->filter_param
== PKTAP_FILTER_PARAM_IF_NAME
)
72 printf("%s", filter
->filter_param_if_name
);
75 int main(int argc
, char * const argv
[])
82 //printf("sizeof(struct pktap_filter) %lu\n", sizeof(struct pktap_filter));
83 //printf("sizeof(pktap_filter) %lu\n", sizeof(set_filter));
85 while ((ch
= getopt(argc
, argv
, "ghi:p:s:")) != -1) {
99 ifindex
= if_nametoindex(ifname
);
101 err(1, "if_nametoindex(%s) failed", ifname
);
107 /* -p (type|name) <value> */
108 struct pktap_filter entry
;
110 if (num_filter_entries
>= PKTAP_MAX_FILTERS
)
111 errx(1, "Too many filter entries, max is %u", PKTAP_MAX_FILTERS
);
112 if (optind
+ 1 > argc
)
113 errx(1, "-%c needs two arguments optind %d argc %d", ch
, optind
, argc
);
115 entry
.filter_op
= PKTAP_FILTER_OP_PASS
;
117 entry
.filter_op
= PKTAP_FILTER_OP_SKIP
;
118 if (strcmp(optarg
, "type") == 0) {
119 entry
.filter_param
= PKTAP_FILTER_PARAM_IF_TYPE
;
120 entry
.filter_param_if_type
= (uint32_t)strtoul(argv
[optind
], NULL
, 0);
121 } else if (strcmp(optarg
, "name") == 0) {
122 entry
.filter_param
= PKTAP_FILTER_PARAM_IF_NAME
;
123 snprintf(entry
.filter_param_if_name
, sizeof(entry
.filter_param_if_name
), "%s", argv
[optind
]);
125 errx(1, "syntax error -p %s", optarg
);
126 printf("Addin entry: ");
127 print_filter_entry(&entry
);
129 set_filter
[num_filter_entries
] = entry
;
131 num_filter_entries
++;
138 err(1, "syntax error");
144 errx(1, "missing interface");
146 fd
= socket(PF_INET
, SOCK_DGRAM
, 0);
148 err(1, "socket(PF_INET, SOCK_DGRAM, 0)");
150 if (num_filter_entries
> 0) {
151 for (i
= num_filter_entries
; i
< PKTAP_MAX_FILTERS
; i
++) {
152 struct pktap_filter
*filter
= set_filter
+ i
;
153 filter
->filter_op
= PKTAP_FILTER_OP_NONE
;
154 filter
->filter_param
= PKTAP_FILTER_PARAM_NONE
;
157 snprintf(ifdr
.ifd_name
, sizeof(ifdr
.ifd_name
), "%s", ifname
);
158 ifdr
.ifd_cmd
= PKTP_CMD_FILTER_SET
;
159 ifdr
.ifd_len
= sizeof(set_filter
);
160 ifdr
.ifd_data
= &set_filter
[0];
162 if (ioctl(fd
, SIOCSDRVSPEC
, &ifdr
) == -1)
163 err(1, "ioctl(SIOCSDRVSPEC)");
168 struct pktap_filter get_filter
[PKTAP_MAX_FILTERS
];
170 snprintf(ifdr
.ifd_name
, sizeof(ifdr
.ifd_name
), "%s", ifname
);
171 ifdr
.ifd_cmd
= PKTP_CMD_FILTER_GET
;
172 ifdr
.ifd_len
= sizeof(get_filter
);
173 ifdr
.ifd_data
= &get_filter
[0];
175 if (ioctl(fd
, SIOCGDRVSPEC
, &ifdr
) == -1)
176 err(1, "ioctl(SIOCGDRVSPEC)");
178 for (i
= 0; i
< PKTAP_MAX_FILTERS
; i
++) {
179 struct pktap_filter
*filter
= get_filter
+ i
;
182 print_filter_entry(filter
);