summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorflipk <flipk@cvs.openbsd.org>1997-06-22 04:58:07 +0000
committerflipk <flipk@cvs.openbsd.org>1997-06-22 04:58:07 +0000
commit51aaa5c2dfb218972a46206b44af4f00657ce50c (patch)
tree07a6c8bd510f24cb2df5c1aadfcd2af8195ec7b8 /sys
parented410fe72b46c9690bc7971dbf67047f4a1b84fe (diff)
wasn't a race after all. properly initialize event_q pointers so the
last one doesn't point off the end.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/rnd.c380
-rw-r--r--sys/dev/rndioctl.h6
-rw-r--r--sys/dev/rndvar.h22
-rw-r--r--sys/kern/kern_sysctl.c6
-rw-r--r--sys/sys/sysctl.h6
5 files changed, 280 insertions, 140 deletions
diff --git a/sys/dev/rnd.c b/sys/dev/rnd.c
index 2afc3d7ea53..6f870732409 100644
--- a/sys/dev/rnd.c
+++ b/sys/dev/rnd.c
@@ -1,9 +1,9 @@
-/* $OpenBSD: rnd.c,v 1.27 1997/06/21 04:59:36 flipk Exp $ */
+/* $OpenBSD: rnd.c,v 1.28 1997/06/22 04:58:05 flipk Exp $ */
/*
* random.c -- A strong random number generator
*
- * Copyright (c) 1996 Michael Shalayeff.
+ * Copyright (c) 1996, 1997 Michael Shalayeff.
*
* Version 1.00, last modified 26-May-96
*
@@ -239,6 +239,7 @@
#include <sys/fcntl.h>
#include <sys/vnode.h>
#include <sys/md5k.h>
+#include <sys/sysctl.h>
#include <net/netisr.h>
@@ -274,25 +275,39 @@ int rnd_debug = 0x0000;
#error No primitive polynomial available for chosen POOLWORDS
#endif
+/* p60/256kL2 reported to have some drops w/ these numbers */
+#define QEVLEN 40
+#define QEVSLOW 32 /* yet another 0.75 for 60-minutes hour /-; */
+#define QEVSBITS 4
+
/* There is actually only one of these, globally. */
struct random_bucket {
u_int add_ptr;
u_int entropy_count;
- int input_rotate;
- u_int32_t *pool;
+ u_char input_rotate;
+ u_int32_t pool[POOLWORDS];
};
/* There is one of these per entropy source */
struct timer_rand_state {
u_long last_time;
- int last_delta;
- int dont_count_entropy:1;
+ u_int last_delta;
+ u_char dont_count_entropy:1;
};
struct arc4_stream {
- u_char i;
- u_char j;
- u_char s[256];
+ u_int8_t i;
+ u_int8_t j;
+ u_int8_t s[256];
+ int cnt;
+};
+
+struct rand_event {
+ struct rand_event *re_next;
+ struct timer_rand_state *re_state;
+ u_char re_nbits;
+ u_long re_time;
+ u_int re_val;
};
/* tags for different random sources */
@@ -300,29 +315,33 @@ struct arc4_stream {
#define ENT_DISK 0x200
#define ENT_TTY 0x300
+struct rndstats rndstats;
static struct random_bucket random_state;
static int arc4random_uninitialized = 2;
-static struct arc4_stream arc4random_state;
-static u_int32_t random_pool[POOLWORDS];
+static struct arc4_stream arc4_state;
static struct timer_rand_state mouse_timer_state;
static struct timer_rand_state extract_timer_state;
static struct timer_rand_state disk_timer_state;
static struct timer_rand_state net_timer_state;
static struct timer_rand_state tty_timer_state;
+static struct rand_event event_space[QEVLEN];
static int rnd_sleep = 0;
+static int rnd_attached = 0;
+static int rnd_enqueued = 0;
+static struct rand_event *event_q = NULL;
+static struct rand_event *event_free;
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
-static __inline void add_entropy_word __P((struct random_bucket *,
- const u_int32_t));
-void add_timer_randomness __P((struct random_bucket *,
- struct timer_rand_state *, u_int));
-static __inline int extract_entropy __P((struct random_bucket *, char *, int));
-void arc4_init __P((struct arc4_stream *, u_char *, int));
-static __inline void arc4_stir (struct arc4_stream *);
-static __inline u_char arc4_getbyte __P((struct arc4_stream *));
+static __inline void add_entropy_word __P((const u_int32_t));
+static void enqueue_randomness __P((register struct timer_rand_state*, u_int));
+void dequeue_randomness __P((void *));
+static __inline int extract_entropy __P((register u_int8_t *, int));
+void arc4_init __P((u_int8_t *, int));
+static __inline void arc4_stir __P((void));
+static __inline u_int8_t arc4_getbyte __P((void));
/* Arcfour random stream generator. This code is derived from section
* 17.1 of Applied Cryptography, second edition, which describes a
@@ -343,55 +362,67 @@ static __inline u_char arc4_getbyte __P((struct arc4_stream *));
*/
void
-arc4_init (struct arc4_stream *as, u_char *data, int len)
+arc4_init (register u_int8_t *data, int len)
{
- int n;
- u_char si;
+ register u_int8_t si;
+ register int n;
- as->i--;
+ arc4_state.i--;
for (n = 0; n < 256; n++) {
- as->i = (as->i + 1) & 0xff;
- si = as->s[as->i];
- as->j = (as->j + si + data[n % len]) & 0xff;
- as->s[as->i] = as->s[as->j];
- as->s[as->j] = si;
+ arc4_state.i = (arc4_state.i + 1) & 0xff;
+ si = arc4_state.s[arc4_state.i];
+ arc4_state.j = (arc4_state.j + si + data[n % len]) & 0xff;
+ arc4_state.s[arc4_state.i] = arc4_state.s[arc4_state.j];
+ arc4_state.s[arc4_state.j] = si;
}
+ arc4_state.cnt = 0;
}
-static __inline u_char
-arc4_getbyte (struct arc4_stream *as)
+static __inline u_int8_t
+arc4_getbyte (void)
{
- u_char si, sj;
-
- as->i = (as->i + 1) & 0xff;
- si = as->s[as->i];
- as->j = (as->j + si) & 0xff;
- sj = as->s[as->j];
- as->s[as->i] = sj;
- as->s[as->j] = si;
- return (as->s[(si + sj) & 0xff]);
+ register u_int8_t si, sj;
+
+ rndstats.arc4_reads++;
+ arc4_state.cnt++;
+ arc4_state.i = (arc4_state.i + 1) & 0xff;
+ si = arc4_state.s[arc4_state.i];
+ arc4_state.j = (arc4_state.j + si) & 0xff;
+ sj = arc4_state.s[arc4_state.j];
+ arc4_state.s[arc4_state.i] = sj;
+ arc4_state.s[arc4_state.j] = si;
+ return (arc4_state.s[(si + sj) & 0xff]);
}
-static inline void
+static __inline void
arc4maybeinit (void)
{
- if (arc4random_uninitialized) {
- if (arc4random_uninitialized > 1
- || random_state.entropy_count >= 128) {
- arc4random_uninitialized--;
- arc4_stir (&arc4random_state);
- }
- }
+ if (arc4random_uninitialized) {
+ if (arc4random_uninitialized > 1
+ || random_state.entropy_count >= 128) {
+ arc4random_uninitialized--;
+ arc4_stir ();
+ }
+ }
}
u_int32_t
arc4random (void)
{
- arc4maybeinit ();
- return ((arc4_getbyte (&arc4random_state) << 24)
- | (arc4_getbyte (&arc4random_state) << 16)
- | (arc4_getbyte (&arc4random_state) << 8)
- | arc4_getbyte (&arc4random_state));
+ arc4maybeinit ();
+ return ((arc4_getbyte () << 24) | (arc4_getbyte () << 16)
+ | (arc4_getbyte () << 8) | arc4_getbyte ());
+}
+
+static __inline void
+arc4_stir (void)
+{
+ u_int8_t buf[256];
+
+ microtime ((struct timeval *) buf);
+ get_random_bytes (buf + sizeof (struct timeval),
+ sizeof (buf) - sizeof (struct timeval));
+ arc4_init (buf, sizeof (buf));
}
void
@@ -399,16 +430,30 @@ randomattach(void)
{
int i;
struct timeval tv;
+ struct rand_event *rep;
+
+ if (rnd_attached) {
+#ifdef DEBUG
+ printf("random: second attach\n");
+#endif
+ return;
+ }
random_state.add_ptr = 0;
random_state.entropy_count = 0;
- random_state.pool = random_pool;
extract_timer_state.dont_count_entropy = 1;
+ bzero(&rndstats, sizeof(rndstats));
+
+ bzero(&event_space, sizeof(event_space));
+ event_free = event_space;
+ for (rep = event_space; rep < &event_space[QEVLEN]; rep++)
+ rep->re_next = rep + 1;
for (i = 0; i < 256; i++)
- arc4random_state.s[i] = i;
+ arc4_state.s[i] = i;
microtime (&tv);
- arc4_init (&arc4random_state, (u_char *) &tv, sizeof (tv));
+ arc4_init ((u_int8_t *) &tv, sizeof (tv));
+ rnd_attached = 1;
}
int
@@ -446,34 +491,36 @@ randomclose(dev, flag, mode, p)
* get affected. --- TYT, 10/11/95
*/
static __inline void
-add_entropy_word(r, input)
- struct random_bucket *r;
+add_entropy_word(input)
const u_int32_t input;
{
u_int i;
u_int32_t w;
- w = (input << r->input_rotate) | (input >> (32 - r->input_rotate));
- i = r->add_ptr = (r->add_ptr - 1) & (POOLWORDS-1);
+ w = (input << random_state.input_rotate) |
+ (input >> (32 - random_state.input_rotate));
+ i = random_state.add_ptr = (random_state.add_ptr - 1) & (POOLWORDS-1);
if (i)
- r->input_rotate = (r->input_rotate + 7) & 31;
+ random_state.input_rotate =
+ (random_state.input_rotate + 7) & 31;
else
/*
* At the beginning of the pool, add an extra 7 bits
* rotation, so that successive passes spread the
* input bits across the pool evenly.
*/
- r->input_rotate = (r->input_rotate + 14) & 31;
+ random_state.input_rotate =
+ (random_state.input_rotate + 14) & 31;
/* XOR in the various taps */
- w ^= r->pool[(i+TAP1)&(POOLWORDS-1)];
- w ^= r->pool[(i+TAP2)&(POOLWORDS-1)];
- w ^= r->pool[(i+TAP3)&(POOLWORDS-1)];
- w ^= r->pool[(i+TAP4)&(POOLWORDS-1)];
- w ^= r->pool[(i+TAP5)&(POOLWORDS-1)];
- w ^= r->pool[i];
+ w ^= random_state.pool[(i+TAP1)&(POOLWORDS-1)];
+ w ^= random_state.pool[(i+TAP2)&(POOLWORDS-1)];
+ w ^= random_state.pool[(i+TAP3)&(POOLWORDS-1)];
+ w ^= random_state.pool[(i+TAP4)&(POOLWORDS-1)];
+ w ^= random_state.pool[(i+TAP5)&(POOLWORDS-1)];
+ w ^= random_state.pool[i];
/* Rotate w left 1 bit (stolen from SHA) and store */
- r->pool[i] = (w << 1) | (w >> 31);
+ random_state.pool[i] = (w << 1) | (w >> 31);
}
/*
@@ -488,34 +535,30 @@ add_entropy_word(r, input)
* are used for a high-resolution timer.
*
*/
-void
-add_timer_randomness(r, state, num)
- struct random_bucket *r;
- struct timer_rand_state *state;
- u_int num;
+static void
+enqueue_randomness(state, val)
+ register struct timer_rand_state *state;
+ u_int val;
{
- int delta, delta2;
u_int nbits;
- u_long time;
struct timeval tv;
+ register struct rand_event *rep;
+ int s;
+ u_long time;
+
+ rndstats.rnd_enqs++;
microtime(&tv);
time = tv.tv_usec ^ tv.tv_sec;
-
- add_entropy_word(r, (u_int32_t)num);
- add_entropy_word(r, time);
-
/*
* Calculate number of bits of randomness we probably
* added. We take into account the first and second order
* deltas in order to make our estimate.
*/
if (!state->dont_count_entropy) {
+ register int delta, delta2;
delta = time - state->last_time;
- state->last_time = time;
-
delta2 = delta - state->last_delta;
- state->last_delta = delta;
if (delta < 0) delta = -delta;
if (delta2 < 0) delta2 = -delta2;
@@ -523,36 +566,114 @@ add_timer_randomness(r, state, num)
for (nbits = 0; delta; nbits++)
delta >>= 1;
- r->entropy_count += nbits;
-
- /* Prevent overflow */
- if (r->entropy_count > POOLBITS)
- r->entropy_count = POOLBITS;
+ if (rnd_enqueued > QEVSLOW && nbits < QEVSBITS) {
+ rndstats.rnd_drople++;
+ return;
+ }
+ state->last_time = time;
+ state->last_delta = delta;
+ }
+
+ s = splhigh();
+ if ((rep = event_free) == NULL) {
+ splx(s);
+ rndstats.rnd_drops++;
+ return;
}
+ event_free = rep->re_next;
- if (r->entropy_count > 8 && rnd_sleep != 0) {
- rnd_sleep--;
+ rep->re_state = state;
+ rep->re_nbits = nbits;
+ rep->re_time = time;
+ rep->re_val = val;
+
+ rep->re_next = event_q;
+ event_q = rep;
+ rep = rep->re_next;
+ splx(s);
+ rndstats.rnd_timer++;
+ rnd_enqueued++;
+
+ if (rep == NULL)
+ timeout(dequeue_randomness, NULL, 1);
+
+}
+
+void
+dequeue_randomness(v)
+ void *v;
+{
+ register struct rand_event *rep;
+ register u_int32_t val, time;
+ u_int nbits;
+ int s;
+
+ rndstats.rnd_deqs++;
+
+ do {
+ s = splhigh();
+ if (event_q == NULL) {
+ splx(s);
+ return;
+ }
+ rep = event_q;
+ event_q = rep->re_next;
+ val = rep->re_val;
+ time = rep->re_time;
+ nbits = rep->re_nbits;
+ rep->re_next = event_free;
+ event_free = rep;
+ splx(s);
+ rnd_enqueued--;
+
+ /* Prevent overflow */
+ if ((random_state.entropy_count + nbits) > POOLBITS &&
+ arc4_state.cnt > 253)
+ arc4_stir();
+
+ add_entropy_word(val);
+ add_entropy_word(time);
+
+ random_state.entropy_count += nbits;
+ rndstats.rnd_total += nbits;
+ if (random_state.entropy_count > POOLBITS)
+ random_state.entropy_count = POOLBITS;
+
+ if (random_state.entropy_count > 8 && rnd_sleep != 0) {
+ rnd_sleep--;
#ifdef DEBUG
- if (rnd_debug & RD_WAIT)
- printf("rnd: wakeup[%d]{%u}\n",
- rnd_sleep, r->entropy_count);
+ if (rnd_debug & RD_WAIT)
+ printf("rnd: wakeup[%d]{%u}\n",
+ rnd_sleep, random_state.entropy_count);
#endif
- wakeup(&rnd_sleep);
- }
+ wakeup(&rnd_sleep);
+ }
+ } while(1);
+
}
void
add_mouse_randomness(mouse_data)
u_int32_t mouse_data;
{
- add_timer_randomness(&random_state, &mouse_timer_state, mouse_data);
+ /* Has randomattach run yet? */
+ if (!rnd_attached)
+ return;
+
+ rndstats.rnd_mouse++;
+ enqueue_randomness(&mouse_timer_state, mouse_data);
}
void
add_net_randomness(isr)
int isr;
{
- add_timer_randomness(&random_state, &net_timer_state, ENT_NET + isr);
+ /* Has randomattach run yet? */
+ if (!rnd_attached)
+ return;
+
+ rndstats.rnd_net++;
+ enqueue_randomness(&net_timer_state, ENT_NET + isr);
}
void
@@ -562,9 +683,10 @@ add_disk_randomness(n)
u_int8_t c;
/* Has randomattach run yet? */
- if (random_state.pool == NULL)
+ if (!rnd_attached)
return;
+ rndstats.rnd_disk++;
c = n & 0xff;
n >>= 8;
c ^= n & 0xff;
@@ -572,7 +694,7 @@ add_disk_randomness(n)
c ^= n & 0xff;
n >>= 8;
c ^= n & 0xff;
- add_timer_randomness(&random_state, &disk_timer_state, ENT_DISK + c);
+ enqueue_randomness(&disk_timer_state, ENT_DISK + c);
}
void
@@ -580,10 +702,11 @@ add_tty_randomness(c)
int c;
{
/* Has randomattach run yet? */
- if (random_state.pool == NULL)
+ if (!rnd_attached)
return;
- add_timer_randomness(&random_state, &tty_timer_state, ENT_TTY + c);
+ rndstats.rnd_tty++;
+ enqueue_randomness(&tty_timer_state, ENT_TTY + c);
}
#if POOLWORDS % 16
@@ -596,42 +719,41 @@ add_tty_randomness(c)
* number of bytes that are actually obtained.
*/
static __inline int
-extract_entropy(r, buf, nbytes)
- struct random_bucket *r;
- char *buf;
+extract_entropy(buf, nbytes)
+ register u_int8_t *buf;
int nbytes;
{
int ret, i;
MD5_CTX tmp;
- add_timer_randomness(r, &extract_timer_state, nbytes);
+ enqueue_randomness(&extract_timer_state, nbytes);
/* Redundant, but just in case... */
- if (r->entropy_count > POOLBITS)
- r->entropy_count = POOLBITS;
+ if (random_state.entropy_count > POOLBITS)
+ random_state.entropy_count = POOLBITS;
ret = nbytes;
- if (r->entropy_count / 8 >= nbytes)
- r->entropy_count -= nbytes*8;
+ if (random_state.entropy_count / 8 >= nbytes)
+ random_state.entropy_count -= nbytes*8;
else
- r->entropy_count = 0;
+ random_state.entropy_count = 0;
while (nbytes) {
/* Hash the pool to get the output */
MD5Init(&tmp);
for (i = 0; i < POOLWORDS; i += 16)
- MD5Update(&tmp, (u_int8_t*)r->pool+i, 16);
+ MD5Update(&tmp, (u_int8_t*)random_state.pool+i, 16);
/* Modify pool so next hash will produce different results */
for (i = 0; i < sizeof(tmp.buffer)/sizeof(tmp.buffer[0]); i++)
- add_entropy_word(r, tmp.buffer[i]);
+ add_entropy_word(tmp.buffer[i]);
/*
* Run the MD5 Transform one more time, since we want
* to add at least minimal obscuring of the inputs to
* add_entropy_word(). --- TYT
*/
- MD5Update(&tmp, (u_int8_t*)r->pool, 16);
+ MD5Update(&tmp, (u_int8_t*)random_state.pool, 16);
/*
* In case the hash function has some recognizable
@@ -650,7 +772,7 @@ extract_entropy(r, buf, nbytes)
bcopy((caddr_t)&tmp.buffer, buf, i);
nbytes -= i;
buf += i;
- add_timer_randomness(r, &extract_timer_state, nbytes);
+ enqueue_randomness(&extract_timer_state, nbytes);
}
/* Wipe data from memory */
@@ -669,7 +791,8 @@ get_random_bytes(buf, nbytes)
void *buf;
size_t nbytes;
{
- extract_entropy(&random_state, (char *) buf, nbytes);
+ extract_entropy((u_int8_t *) buf, nbytes);
+ rndstats.rnd_used += nbytes * 8;
}
int
@@ -705,6 +828,7 @@ randomread(dev, uio, ioflag)
rnd_sleep);
#endif
rnd_sleep++;
+ rndstats.rnd_waits++;
ret = tsleep(&rnd_sleep, PWAIT | PCATCH,
"rndrd", 0);
#ifdef DEBUG
@@ -715,12 +839,13 @@ randomread(dev, uio, ioflag)
break;
}
n = min(n, random_state.entropy_count / 8);
+ rndstats.rnd_reads++;
#ifdef DEBUG
if (rnd_debug & RD_OUTPUT)
printf("rnd: %u possible output\n", n);
#endif
case RND_URND:
- n = extract_entropy(&random_state, (char *)buf, n);
+ n = extract_entropy((char *)buf, n);
#ifdef DEBUG
if (rnd_debug & RD_OUTPUT)
printf("rnd: %u bytes for output\n", n);
@@ -733,11 +858,11 @@ randomread(dev, uio, ioflag)
break;
case RND_ARND:
{
- u_char *cp = (u_char *) buf;
- u_char *end = cp + n;
+ u_int8_t *cp = (u_int8_t *) buf;
+ u_int8_t *end = cp + n;
arc4maybeinit ();
while (cp < end)
- *cp++ = arc4_getbyte (&arc4random_state);
+ *cp++ = arc4_getbyte ();
break;
}
}
@@ -763,17 +888,6 @@ randomselect(dev, rw, p)
return 0;
}
-static __inline void
-arc4_stir (struct arc4_stream *as)
-{
- u_char buf[256];
-
- microtime ((struct timeval *) buf);
- get_random_bytes (buf + sizeof (struct timeval),
- sizeof (buf) - sizeof (struct timeval));
- arc4_init (&arc4random_state, buf, sizeof (buf));
-}
-
int
randomwrite(dev, uio, flags)
dev_t dev;
@@ -796,15 +910,15 @@ randomwrite(dev, uio, flags)
if (!ret) {
int i;
while (n % sizeof(u_int32_t))
- ((u_char *) buf)[n++] = 0;
+ ((u_int8_t *) buf)[n++] = 0;
n >>= 2;
for (i = 0; i < n; i++)
- add_entropy_word(&random_state, buf[i]);
+ add_entropy_word(buf[i]);
}
}
if (minor(dev) == RND_ARND && !ret)
- arc4_stir (&arc4random_state);
+ arc4_stir ();
return ret;
}
@@ -845,7 +959,7 @@ randomioctl(dev, cmd, data, flag, p)
return EPERM;
if (random_state.entropy_count < 64)
return EAGAIN;
- arc4_stir (&arc4random_state);
+ arc4_stir ();
ret = 0;
break;
default:
diff --git a/sys/dev/rndioctl.h b/sys/dev/rndioctl.h
index a536bb8d2f4..b5f161932df 100644
--- a/sys/dev/rndioctl.h
+++ b/sys/dev/rndioctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rndioctl.h,v 1.4 1997/06/21 04:59:37 flipk Exp $ */
+/* $OpenBSD: rndioctl.h,v 1.5 1997/06/22 04:58:06 flipk Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff.
@@ -38,14 +38,14 @@
#ifndef __RNDIOCTL_H__
#define __RNDIOCTL_H__
+/* ioctl()'s for the random number generator */
+
struct rnd_pool_info {
size_t entropy_count;
size_t buf_size;
u_int32_t *buf;
};
-/* ioctl()'s for the random number generator */
-
#define RNDGETENTCNT _IOR('R', 0, sizeof(u_int))
#define RNDADDTOENTCNT _IOW('R', 1, sizeof(u_int))
#define RNDGETPOOL _IOWR('R', 2, sizeof(struct rnd_pool_info))
diff --git a/sys/dev/rndvar.h b/sys/dev/rndvar.h
index 39ac7934b38..28edbc99322 100644
--- a/sys/dev/rndvar.h
+++ b/sys/dev/rndvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rndvar.h,v 1.8 1997/06/21 04:59:37 flipk Exp $ */
+/* $OpenBSD: rndvar.h,v 1.9 1997/06/22 04:58:06 flipk Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff.
@@ -46,7 +46,27 @@
#define RND_ARND 4 /* aRC4 based random number generator */
#define RND_NODEV 5 /* First invalid minor device number */
+struct rndstats {
+ u_long rnd_total; /* total bits of entropy generated */
+ u_long rnd_used; /* strong data bits read so far */
+ u_long arc4_reads;/* aRC4 data bytes read so far */
+
+ u_long rnd_timer; /* timer calls */
+ u_long rnd_mouse; /* mouse calls */
+ u_long rnd_tty; /* tty calls */
+ u_long rnd_disk; /* block devices calls */
+ u_long rnd_net; /* net calls */
+
+ u_long rnd_reads; /* strong read calls */
+ u_long rnd_waits; /* sleep for data */
+ u_long rnd_enqs; /* enqueue calls */
+ u_long rnd_deqs; /* dequeue calls */
+ u_long rnd_drops; /* queue-full drops */
+ u_long rnd_drople;/* queue low watermark low entropy drops */
+};
+
#ifdef _KERNEL
+extern struct rndstats rndstats;
extern void add_mouse_randomness __P((u_int32_t));
extern void add_net_randomness __P((int));
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 92a41ad969c..ccbeeb7f360 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.17 1997/06/21 04:59:44 flipk Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.18 1997/06/22 04:58:03 flipk Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -60,6 +60,7 @@
#include <sys/mount.h>
#include <sys/syscallargs.h>
+#include <dev/rndvar.h>
#ifdef DDB
#include <ddb/db_var.h>
@@ -297,6 +298,9 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
return (sysctl_int(oldp, oldlenp, newp, newlen, &sominconn));
case KERN_USERMOUNT:
return (sysctl_int(oldp, oldlenp, newp, newlen, &usermount));
+ case KERN_RND:
+ return (sysctl_rdstruct(oldp, oldlenp, newp, &rndstats,
+ sizeof(rndstats)));
default:
return (EOPNOTSUPP);
}
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index ea95ee21f74..cfd99337fdf 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysctl.h,v 1.13 1997/06/21 04:59:47 flipk Exp $ */
+/* $OpenBSD: sysctl.h,v 1.14 1997/06/22 04:58:04 flipk Exp $ */
/* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */
/*
@@ -141,7 +141,8 @@ struct ctlname {
#define KERN_SOMAXCONN 28 /* int: listen queue maximum */
#define KERN_SOMINCONN 29 /* int: half-open controllable param */
#define KERN_USERMOUNT 30 /* int: users may mount filesystems */
-#define KERN_MAXID 31 /* number of valid kern ids */
+#define KERN_RND 31 /* struct: rnd(4) statistics */
+#define KERN_MAXID 32 /* number of valid kern ids */
#define CTL_KERN_NAMES { \
{ 0, 0 }, \
@@ -175,6 +176,7 @@ struct ctlname {
{ "somaxconn", CTLTYPE_INT }, \
{ "sominconn", CTLTYPE_INT }, \
{ "usermount", CTLTYPE_INT }, \
+ { "random", CTLTYPE_STRUCT }, \
}
/*