1 /* $NetBSD: rndctl.c,v 1.18 2008/11/06 16:01:54 apb Exp $ */
4 * Copyright (c) 1997 Michael Graff.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the author nor the names of other contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #include <sys/cdefs.h>
34 __RCSID("$NetBSD: rndctl.c,v 1.18 2008/11/06 16:01:54 apb Exp $");
38 #include <sys/types.h>
39 #include <sys/ioctl.h>
55 arg_t source_types
[] = {
56 { "???", RND_TYPE_UNKNOWN
},
57 { "disk", RND_TYPE_DISK
},
58 { "net", RND_TYPE_NET
},
59 { "tape", RND_TYPE_TAPE
},
60 { "tty", RND_TYPE_TTY
},
61 { "rng", RND_TYPE_RNG
},
65 static void usage(void);
66 u_int32_t
find_type(char *name
);
67 const char *find_name(u_int32_t
);
68 void do_ioctl(rndctl_t
*);
69 char * strflags(u_int32_t
);
70 void do_list(int, u_int32_t
, char *);
77 fprintf(stderr
, "usage: %s -CEce [-d devname | -t devtype]\n",
79 fprintf(stderr
, " %s -ls [-d devname | -t devtype]\n",
91 while (a
->a_name
!= NULL
) {
92 if (strcmp(a
->a_name
, name
) == 0)
97 errx(1, "device name %s unknown", name
);
102 find_name(u_int32_t type
)
108 while (a
->a_name
!= NULL
) {
109 if (type
== a
->a_type
)
114 warnx("device type %u unknown", type
);
119 do_ioctl(rndctl_t
*rctl
)
124 fd
= open("/dev/urandom", O_RDONLY
, 0644);
128 res
= ioctl(fd
, RNDCTL
, rctl
);
130 err(1, "ioctl(RNDCTL)");
136 strflags(u_int32_t fl
)
138 static char str
[512];
141 if (fl
& RND_FLAG_NO_ESTIMATE
)
144 strlcat(str
, "estimate", sizeof(str
));
146 if (fl
& RND_FLAG_NO_COLLECT
)
150 strlcat(str
, ", ", sizeof(str
));
151 strlcat(str
, "collect", sizeof(str
));
157 #define HEADER "Source Bits Type Flags\n"
160 do_list(int all
, u_int32_t type
, char *name
)
163 rndstat_name_t rstat_name
;
169 fd
= open("/dev/urandom", O_RDONLY
, 0644);
173 if (all
== 0 && type
== 0xff) {
174 strncpy(rstat_name
.name
, name
, sizeof(rstat_name
.name
));
175 res
= ioctl(fd
, RNDGETSRCNAME
, &rstat_name
);
177 err(1, "ioctl(RNDGETSRCNAME)");
179 printf("%-16s %10u %-4s %s\n",
180 rstat_name
.source
.name
,
181 rstat_name
.source
.total
,
182 find_name(rstat_name
.source
.type
),
183 strflags(rstat_name
.source
.flags
));
189 * Run through all the devices present in the system, and either
190 * print out ones that match, or print out all of them.
195 rstat
.count
= RND_MAXSTATCOUNT
;
197 res
= ioctl(fd
, RNDGETSRCNUM
, &rstat
);
199 err(1, "ioctl(RNDGETSRCNUM)");
201 if (rstat
.count
== 0)
204 for (i
= 0; i
< rstat
.count
; i
++) {
206 type
== rstat
.source
[i
].type
)
207 printf("%-16s %10u %-4s %s\n",
208 rstat
.source
[i
].name
,
209 rstat
.source
[i
].total
,
210 find_name(rstat
.source
[i
].type
),
211 strflags(rstat
.source
[i
].flags
));
213 start
+= rstat
.count
;
225 fd
= open("/dev/urandom", O_RDONLY
, 0644);
229 if (ioctl(fd
, RNDGETPOOLSTAT
, &rs
) < 0)
230 err(1, "ioctl(RNDGETPOOLSTAT)");
232 printf("\t%9u bits mixed into pool\n", rs
.added
);
233 printf("\t%9u bits currently stored in pool (max %u)\n",
234 rs
.curentropy
, rs
.maxentropy
);
235 printf("\t%9u bits of entropy discarded due to full pool\n",
237 printf("\t%9u hard-random bits generated\n", rs
.removed
);
238 printf("\t%9u pseudo-random bits generated\n", rs
.generated
);
244 main(int argc
, char **argv
)
247 int ch
, cmd
, lflag
, mflag
, sflag
;
260 while ((ch
= getopt(argc
, argv
, "CEcelt:d:s")) != -1) {
263 rctl
.flags
|= RND_FLAG_NO_COLLECT
;
264 rctl
.mask
|= RND_FLAG_NO_COLLECT
;
268 rctl
.flags
|= RND_FLAG_NO_ESTIMATE
;
269 rctl
.mask
|= RND_FLAG_NO_ESTIMATE
;
273 rctl
.flags
&= ~RND_FLAG_NO_COLLECT
;
274 rctl
.mask
|= RND_FLAG_NO_COLLECT
;
278 rctl
.flags
&= ~RND_FLAG_NO_ESTIMATE
;
279 rctl
.mask
|= RND_FLAG_NO_ESTIMATE
;
290 type
= find_type(optarg
);
298 strlcpy(name
, optarg
, sizeof(name
));
312 * No leftover non-option arguments.
318 * Cannot list and modify at the same time.
320 if ((lflag
!= 0 || sflag
!= 0) && mflag
!= 0)
324 * Bomb out on no-ops.
326 if (lflag
== 0 && mflag
== 0 && sflag
== 0)
330 * If not listing, we need a device name or a type.
332 if (lflag
== 0 && cmd
== 0 && sflag
== 0)
340 strncpy(rctl
.name
, name
, sizeof(rctl
.name
));
350 do_list(cmd
== 0, type
, name
);