pktgenctl: Update according to recent libc changes
[dragonfly.git] / tools / tools / netrate / pktgenctl / pktgenctl.c
CommitLineData
4fa8e46e
SZ
1/*
2 * Copyright (c) 2008 The DragonFly Project. All rights reserved.
3 *
4 * This code is derived from software contributed to The DragonFly Project
5 * by Sepherosa Ziehau <sepherosa@gmail.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
c95ebcd6 34 * $DragonFly: src/tools/tools/netrate/pktgenctl/pktgenctl.c,v 1.3 2008/03/29 11:45:46 sephe Exp $
4fa8e46e
SZ
35 */
36
37#include <sys/types.h>
38#include <sys/ioctl.h>
39#include <sys/stat.h>
40#include <sys/socket.h>
41
42#include <arpa/inet.h>
43#include <netinet/in.h>
44#include <net/if.h>
45#include <net/if_dl.h>
46#include <net/ethernet.h>
47
48#include <err.h>
49#include <fcntl.h>
50#include <stdio.h>
51#include <stdlib.h>
52#include <string.h>
53#include <unistd.h>
54
55#include "pktgen/pktgen.h"
56
57#define PKTGEN_DEVPATH "/dev/pktg0"
58
59#define DEFAULT_SPORT 3001
60#define DEFAULT_DPORT 3000
61
62#define INDST_MASK 0x1
63#define INSRC_MASK 0x2
64#define EADDR_MASK 0x4
65#define IFACE_MASK 0x8
66#define DATALEN_MASK 0x10
67#define SPORT_MASK 0x20
68#define DPORT_MASK 0x40
69#define CPUID_MASK 0x80
70#define DURATION_MASK 0x100
71#define YIELD_MASK 0x200
72
73#define MASK_NEEDED (INDST_MASK | INSRC_MASK | EADDR_MASK | IFACE_MASK)
74
75static void
76usage(void)
77{
c95ebcd6 78 fprintf(stderr, "pktgenctl -d dst_inaddr[,ndst] -s src_inaddr[,nsrc] "
4fa8e46e 79 "-e (gw_eaddr|dst_eaddr) -i iface "
c95ebcd6 80 "[-p src_port[,nsport]] [-P dst_port[,ndport]] "
4fa8e46e
SZ
81 "[-m data_len] [-c cpuid] [-l duration] [-y yield]\n");
82 exit(1);
83}
84
c95ebcd6
SZ
85static int
86get_range(char *str)
87{
88 char *ptr;
89
90 ptr = strstr(str, ",");
91 if (ptr == NULL) {
92 return 0;
93 } else {
94 *ptr = '\0';
95 return atoi(ptr + 1);
96 }
97}
98
4fa8e46e
SZ
99int
100main(int argc, char *argv[])
101{
102 struct pktgen_conf conf;
103 struct sockaddr *sa;
104 struct sockaddr_in *dst_sin, *src_sin;
105 struct sockaddr_dl sdl;
106 char eaddr_str[32];
107 uint32_t arg_mask = 0;
108 int fd, c, n;
109
110 memset(&conf, 0, sizeof(conf));
111
112 conf.pc_cpuid = 0;
113 conf.pc_duration = 10;
114 conf.pc_datalen = 10;
115
116 sa = &conf.pc_dst_lladdr;
117 sa->sa_family = AF_LINK;
118 sa->sa_len = ETHER_ADDR_LEN;
119
120 dst_sin = &conf.pc_dst;
121 dst_sin->sin_family = AF_INET;
122 dst_sin->sin_port = htons(DEFAULT_DPORT);
123
124 src_sin = &conf.pc_src;
125 src_sin->sin_family = AF_INET;
126 src_sin->sin_port = htons(DEFAULT_SPORT);
127
128 while ((c = getopt(argc, argv, "d:s:e:i:p:P:m:c:l:y:")) != -1) {
129 switch (c) {
130 case 'd':
c95ebcd6 131 conf.pc_ndaddr = get_range(optarg);
4fa8e46e
SZ
132 n = inet_pton(AF_INET, optarg,
133 &dst_sin->sin_addr.s_addr);
134 if (n == 0)
135 errx(1, "-d: invalid inet address");
136 else if (n < 0)
137 err(1, "-d");
138 arg_mask |= INDST_MASK;
139 break;
140
141 case 's':
c95ebcd6 142 conf.pc_nsaddr = get_range(optarg);
4fa8e46e
SZ
143 n = inet_pton(AF_INET, optarg,
144 &src_sin->sin_addr.s_addr);
145 if (n == 0)
146 errx(1, "-s: invalid inet address");
147 else if (n < 0)
148 err(1, "-s");
149 arg_mask |= INSRC_MASK;
150 break;
151
152 case 'e':
153 strcpy(eaddr_str, "if0.");
154 strlcpy(&eaddr_str[strlen("if0.")], optarg,
155 sizeof(eaddr_str) - strlen("if0."));
156
157 memset(&sdl, 0, sizeof(sdl));
158 sdl.sdl_len = sizeof(sdl);
2c0c3dfc 159 link_addr(eaddr_str, &sdl);
4fa8e46e
SZ
160 bcopy(LLADDR(&sdl), sa->sa_data, ETHER_ADDR_LEN);
161 arg_mask |= EADDR_MASK;
4fa8e46e
SZ
162 break;
163
164 case 'i':
165 strlcpy(conf.pc_ifname, optarg, sizeof(conf.pc_ifname));
166 arg_mask |= IFACE_MASK;
167 break;
168
169 case 'p':
c95ebcd6 170 conf.pc_nsport = get_range(optarg);
4fa8e46e
SZ
171 src_sin->sin_port = htons(atoi(optarg));
172 arg_mask |= SPORT_MASK;
173 break;
174
175 case 'P':
c95ebcd6 176 conf.pc_ndport = get_range(optarg);
4fa8e46e
SZ
177 dst_sin->sin_port = htons(atoi(optarg));
178 arg_mask |= DPORT_MASK;
179 break;
180
181 case 'm':
182 conf.pc_datalen = atoi(optarg);
183 arg_mask |= DATALEN_MASK;
184 break;
185
186 case 'c':
187 conf.pc_cpuid = atoi(optarg);
188 arg_mask |= CPUID_MASK;
189 break;
190
191 case 'l':
192 conf.pc_duration = atoi(optarg);
193 arg_mask |= DURATION_MASK;
194 break;
195
196 case 'y':
197 conf.pc_yield = atoi(optarg);
198 arg_mask |= YIELD_MASK;
199 break;
200 }
201 }
202
203 if ((arg_mask & MASK_NEEDED) != MASK_NEEDED)
204 usage();
205
206 fd = open(PKTGEN_DEVPATH, O_RDONLY);
207 if (fd < 0)
208 err(1, "open(" PKTGEN_DEVPATH ")");
209
210 if (ioctl(fd, PKTGENSCONF, &conf) < 0)
211 err(1, "ioctl(PKTGENSCONF)");
212
213 if (ioctl(fd, PKTGENSTART) < 0)
214 err(1, "ioctl(PKTGENSTART)");
215
216 close(fd);
217 exit(0);
218}