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