1 /*
2 * mod_drop.c
3 *
4 * Copyright (c) 2001 Dug Song <dugsong@monkey.org>
5 *
6 * $Id: mod_drop.c,v 1.3 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 DROP_FIRST 1
19 #define DROP_LAST 2
20 #define DROP_RANDOM 3
21
22 struct drop_data {
23 rand_t *rnd;
24 int which;
25 int percent;
26 };
27
28 void *
drop_close(void * d)29 drop_close(void *d)
30 {
31 struct drop_data *data = (struct drop_data *)d;
32
33 if (data != NULL) {
34 rand_close(data->rnd);
35 free(data);
36 }
37 return (NULL);
38 }
39
40 void *
drop_open(int argc,char * argv[])41 drop_open(int argc, char *argv[])
42 {
43 struct drop_data *data;
44
45 if (argc != 3)
46 return (NULL);
47
48 if ((data = calloc(1, sizeof(*data))) == NULL)
49 return (NULL);
50
51 data->rnd = rand_open();
52
53 if (strcasecmp(argv[1], "first") == 0)
54 data->which = DROP_FIRST;
55 else if (strcasecmp(argv[1], "last") == 0)
56 data->which = DROP_LAST;
57 else if (strcasecmp(argv[1], "random") == 0)
58 data->which = DROP_RANDOM;
59 else
60 return (drop_close(data));
61
62 if ((data->percent = atoi(argv[2])) <= 0 || data->percent > 100)
63 return (drop_close(data));
64
65 return (data);
66 }
67
68 int
drop_apply(void * d,struct pktq * pktq)69 drop_apply(void *d, struct pktq *pktq)
70 {
71 struct drop_data *data = (struct drop_data *)d;
72 struct pkt *pkt;
73
74 if (data->percent < 100 &&
75 (rand_uint16(data->rnd) % 100) > data->percent)
76 return (0);
77
78 if (data->which == DROP_FIRST)
79 pkt = TAILQ_FIRST(pktq);
80 else if (data->which == DROP_LAST)
81 pkt = TAILQ_LAST(pktq, pktq);
82 else
83 pkt = pktq_random(data->rnd, pktq);
84
85 TAILQ_REMOVE(pktq, pkt, pkt_next);
86 pkt_free(pkt);
87
88 return (0);
89 }
90
91 struct mod mod_drop = {
92 "drop", /* name */
93 "drop first|last|random <prob-%>", /* usage */
94 drop_open, /* open */
95 drop_apply, /* apply */
96 drop_close /* close */
97 };
98