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