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