1 /*
2  * mod_delay.c
3  *
4  * Copyright (c) 2001 Dug Song <dugsong@monkey.org>
5  *
6  * $Id: mod_delay.c,v 1.4 2002/04/07 22:55:20 dugsong Exp $
7  */
8 
9 #include "config.h"
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 
15 #include "pkt.h"
16 #include "mod.h"
17 
18 #define DELAY_FIRST	1
19 #define DELAY_LAST	2
20 #define DELAY_RANDOM	3
21 
22 struct delay_data {
23 	rand_t		*rnd;
24 	int		 which;
25 	struct timeval	 tv;
26 };
27 
28 void *
delay_close(void * d)29 delay_close(void *d)
30 {
31 	struct delay_data *data = (struct delay_data *)d;
32 
33 	if (data != NULL) {
34 		rand_close(data->rnd);
35 		free(data);
36 	}
37 	return (NULL);
38 }
39 
40 void *
delay_open(int argc,char * argv[])41 delay_open(int argc, char *argv[])
42 {
43 	struct delay_data *data;
44 	uint64_t usec;
45 
46 	if (argc != 3)
47 		return (NULL);
48 
49 	if ((data = malloc(sizeof(*data))) == NULL)
50 		return (NULL);
51 
52 	data->rnd = rand_open();
53 
54 	if (strcasecmp(argv[1], "first") == 0)
55 		data->which = DELAY_FIRST;
56 	else if (strcasecmp(argv[1], "last") == 0)
57 		data->which = DELAY_LAST;
58 	else if (strcasecmp(argv[1], "random") == 0)
59 		data->which = DELAY_RANDOM;
60 	else
61 		return (delay_close(data));
62 
63 	if ((usec = atoi(argv[2])) <= 0)
64 		return (delay_close(data));
65 
66 	usec *= 1000;
67 	data->tv.tv_sec = usec / 1000000;
68 	data->tv.tv_usec = usec % 1000000;
69 
70 	return (data);
71 }
72 
73 int
delay_apply(void * d,struct pktq * pktq)74 delay_apply(void *d, struct pktq *pktq)
75 {
76 	struct delay_data *data = (struct delay_data *)d;
77 	struct pkt *pkt;
78 
79 	if (data->which == DELAY_FIRST)
80 		pkt = TAILQ_FIRST(pktq);
81 	else if (data->which == DELAY_LAST)
82 		pkt = TAILQ_LAST(pktq, pktq);
83 	else
84 		pkt = pktq_random(data->rnd, pktq);
85 
86 	memcpy(&pkt->pkt_ts, &data->tv, sizeof(pkt->pkt_ts));
87 
88 	return (0);
89 }
90 
91 struct mod mod_delay = {
92 	"delay",			/* name */
93 	"delay first|last|random <ms>",	/* usage */
94 	delay_open,			/* open */
95 	delay_apply,			/* apply */
96 	delay_close			/* close */
97 };
98