1 /*
2 * mod_tcp_opt.c
3 *
4 * Copyright (c) 2001 Dug Song <dugsong@monkey.org>
5 *
6 * $Id: mod_tcp_opt.c,v 1.5 2002/04/07 22:55:20 dugsong Exp $
7 */
8
9 #include "config.h"
10
11 #include <err.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15
16 #include "pkt.h"
17 #include "mod.h"
18
19 void *
tcp_opt_close(void * d)20 tcp_opt_close(void *d)
21 {
22 if (d != NULL)
23 free(d);
24 return (NULL);
25 }
26
27 void *
tcp_opt_open(int argc,char * argv[])28 tcp_opt_open(int argc, char *argv[])
29 {
30 struct tcp_opt *opt;
31 int i;
32
33 if (argc < 3)
34 return (NULL);
35
36 if ((opt = calloc(1, sizeof(*opt))) == NULL)
37 return (NULL);
38
39 if (strcasecmp(argv[1], "mss") == 0) {
40 opt->opt_type = TCP_OPT_MSS;
41 opt->opt_len = TCP_OPT_LEN + 2;
42
43 if ((i = atoi(argv[2])) <= 0 || i > 0xffff) {
44 warnx("mss <size> must be from 0-65535");
45 return (tcp_opt_close(opt));
46 }
47 opt->opt_data.mss = htons(i);
48 } else if (strcasecmp(argv[1], "wscale") == 0) {
49 opt->opt_type = TCP_OPT_WSCALE;
50 opt->opt_len = TCP_OPT_LEN + 2;
51
52 if ((i = atoi(argv[2])) <= 0 || i > 0xff) {
53 warnx("wscale <size> must be from 0-255");
54 return (tcp_opt_close(opt));
55 }
56 opt->opt_data.wscale = i;
57 } else
58 return (tcp_opt_close(opt));
59
60 return (opt);
61 }
62
63 int
tcp_opt_apply(void * d,struct pktq * pktq)64 tcp_opt_apply(void *d, struct pktq *pktq)
65 {
66 struct tcp_opt *opt = (struct tcp_opt *)d;
67 struct pkt *pkt;
68 size_t len;
69
70 TAILQ_FOREACH(pkt, pktq, pkt_next) {
71 len = ip_add_option(pkt->pkt_ip,
72 sizeof(pkt->pkt_data) - ETH_HDR_LEN,
73 IP_PROTO_TCP, opt, opt->opt_len);
74
75 if (len > 0) {
76 pkt->pkt_end += len;
77 pkt_decorate(pkt);
78 ip_checksum(pkt->pkt_ip, pkt->pkt_end -
79 pkt->pkt_eth_data);
80 }
81 }
82 return (0);
83 }
84
85 struct mod mod_tcp_opt = {
86 "tcp_opt", /* name */
87 "tcp_opt mss|wscale <size>", /* usage */
88 tcp_opt_open, /* open */
89 tcp_opt_apply, /* apply */
90 tcp_opt_close /* close */
91 };
92