]> git.saurik.com Git - apple/network_cmds.git/blame - pktapctl/pktapctl.c
network_cmds-606.100.3.tar.gz
[apple/network_cmds.git] / pktapctl / pktapctl.c
CommitLineData
9dc66a05
A
1/*
2 * Copyright (c) 2012 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
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>
34#include <stdio.h>
35#include <unistd.h>
36#include <err.h>
37#include <stdlib.h>
38#include <string.h>
39
40const char *ifname = NULL;
41unsigned int ifindex = 0;
42int do_get = 0;
43int num_filter_entries = 0;
44struct pktap_filter set_filter[PKTAP_MAX_FILTERS];
45
46static const char *parameters_format = " %-24s %s\n";
47
48static void
49usage(const char *s)
50{
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");
63}
64
65static void
66print_filter_entry(struct pktap_filter *filter)
67{
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);
73}
74
75int main(int argc, char * const argv[])
76{
77 int ch;
78 struct ifdrv ifdr;
79 int fd = -1;
80 int i;
81
82 //printf("sizeof(struct pktap_filter) %lu\n", sizeof(struct pktap_filter));
83 //printf("sizeof(pktap_filter) %lu\n", sizeof(set_filter));
84
85 while ((ch = getopt(argc, argv, "ghi:p:s:")) != -1) {
86 switch (ch) {
87 case 'g':
88 do_get++;
89 break;
90
91 case 'h':
92 usage(argv[0]);
93 exit(0);
94 /* NOT REACHED */
95
96 case 'i':
97 ifname = optarg;
98
99 ifindex = if_nametoindex(ifname);
100 if (ifindex == 0)
101 err(1, "if_nametoindex(%s) failed", ifname);
102
103 break;
104
105 case 'p':
106 case 's': {
107 /* -p (type|name) <value> */
108 struct pktap_filter entry;
109
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);
114 if (ch == 'p')
115 entry.filter_op = PKTAP_FILTER_OP_PASS;
116 else
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]);
124 } else
125 errx(1, "syntax error -p %s", optarg);
126 printf("Addin entry: ");
127 print_filter_entry(&entry);
128 printf("\n");
129 set_filter[num_filter_entries] = entry;
130
131 num_filter_entries++;
132 optind++;
133 break;
134 }
135
136 case '?':
137 default:
138 err(1, "syntax error");
139 exit(0);
140 /* NOT REACHED */
141 }
142 }
143 if (ifname == NULL)
144 errx(1, "missing interface");
145
146 fd = socket(PF_INET, SOCK_DGRAM, 0);
147 if (fd == -1)
148 err(1, "socket(PF_INET, SOCK_DGRAM, 0)");
149
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;
155 }
156
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];
161
162 if (ioctl(fd, SIOCSDRVSPEC, &ifdr) == -1)
163 err(1, "ioctl(SIOCSDRVSPEC)");
164
165 }
166
167 if (do_get) {
168 struct pktap_filter get_filter[PKTAP_MAX_FILTERS];
169
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];
174
175 if (ioctl(fd, SIOCGDRVSPEC, &ifdr) == -1)
176 err(1, "ioctl(SIOCGDRVSPEC)");
177
178 for (i = 0; i < PKTAP_MAX_FILTERS; i++) {
179 struct pktap_filter *filter = get_filter + i;
180
181 printf("[%d] ", i);
182 print_filter_entry(filter);
183 printf("\n");
184 }
185 }
186
187 return 0;
188}
189