2 * Copyright (c) 2008 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Sepherosa Ziehau <sepherosa@gmail.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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
34 * $DragonFly: src/tools/tools/netrate/pktgenctl/pktgenctl.c,v 1.2 2008/03/26 15:05:33 sephe Exp $
37 #include <sys/types.h>
38 #include <sys/ioctl.h>
40 #include <sys/socket.h>
42 #include <arpa/inet.h>
43 #include <netinet/in.h>
45 #include <net/if_dl.h>
46 #include <net/ethernet.h>
55 #include "pktgen/pktgen.h"
57 #define PKTGEN_DEVPATH "/dev/pktg0"
59 #define DEFAULT_SPORT 3001
60 #define DEFAULT_DPORT 3000
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
73 #define MASK_NEEDED (INDST_MASK | INSRC_MASK | EADDR_MASK | IFACE_MASK)
78 fprintf(stderr
, "pktgenctl -d dst_inaddr -s src_inaddr "
79 "-e (gw_eaddr|dst_eaddr) -i iface "
80 "[-p src_port] [-P dst_port] "
81 "[-m data_len] [-c cpuid] [-l duration] [-y yield]\n");
86 main(int argc
, char *argv
[])
88 struct pktgen_conf conf
;
90 struct sockaddr_in
*dst_sin
, *src_sin
;
91 struct sockaddr_dl sdl
;
93 uint32_t arg_mask
= 0;
96 memset(&conf
, 0, sizeof(conf
));
99 conf
.pc_duration
= 10;
100 conf
.pc_datalen
= 10;
102 sa
= &conf
.pc_dst_lladdr
;
103 sa
->sa_family
= AF_LINK
;
104 sa
->sa_len
= ETHER_ADDR_LEN
;
106 dst_sin
= &conf
.pc_dst
;
107 dst_sin
->sin_family
= AF_INET
;
108 dst_sin
->sin_port
= htons(DEFAULT_DPORT
);
110 src_sin
= &conf
.pc_src
;
111 src_sin
->sin_family
= AF_INET
;
112 src_sin
->sin_port
= htons(DEFAULT_SPORT
);
114 while ((c
= getopt(argc
, argv
, "d:s:e:i:p:P:m:c:l:y:")) != -1) {
117 n
= inet_pton(AF_INET
, optarg
,
118 &dst_sin
->sin_addr
.s_addr
);
120 errx(1, "-d: invalid inet address");
123 arg_mask
|= INDST_MASK
;
127 n
= inet_pton(AF_INET
, optarg
,
128 &src_sin
->sin_addr
.s_addr
);
130 errx(1, "-s: invalid inet address");
133 arg_mask
|= INSRC_MASK
;
137 strcpy(eaddr_str
, "if0.");
138 strlcpy(&eaddr_str
[strlen("if0.")], optarg
,
139 sizeof(eaddr_str
) - strlen("if0."));
141 memset(&sdl
, 0, sizeof(sdl
));
142 sdl
.sdl_len
= sizeof(sdl
);
143 if (ascii2addr(AF_LINK
, eaddr_str
, &sdl
) < 0)
144 errx(1, "-e: invalid ethernet address");
145 bcopy(LLADDR(&sdl
), sa
->sa_data
, ETHER_ADDR_LEN
);
146 arg_mask
|= EADDR_MASK
;
150 strlcpy(conf
.pc_ifname
, optarg
, sizeof(conf
.pc_ifname
));
151 arg_mask
|= IFACE_MASK
;
155 src_sin
->sin_port
= htons(atoi(optarg
));
156 arg_mask
|= SPORT_MASK
;
160 dst_sin
->sin_port
= htons(atoi(optarg
));
161 arg_mask
|= DPORT_MASK
;
165 conf
.pc_datalen
= atoi(optarg
);
166 arg_mask
|= DATALEN_MASK
;
170 conf
.pc_cpuid
= atoi(optarg
);
171 arg_mask
|= CPUID_MASK
;
175 conf
.pc_duration
= atoi(optarg
);
176 arg_mask
|= DURATION_MASK
;
180 conf
.pc_yield
= atoi(optarg
);
181 arg_mask
|= YIELD_MASK
;
186 if ((arg_mask
& MASK_NEEDED
) != MASK_NEEDED
)
189 fd
= open(PKTGEN_DEVPATH
, O_RDONLY
);
191 err(1, "open(" PKTGEN_DEVPATH
")");
193 if (ioctl(fd
, PKTGENSCONF
, &conf
) < 0)
194 err(1, "ioctl(PKTGENSCONF)");
196 if (ioctl(fd
, PKTGENSTART
) < 0)
197 err(1, "ioctl(PKTGENSTART)");