1 /*
2  * mod_ip_opt.c
3  *
4  * Copyright (c) 2001 Dug Song <dugsong@monkey.org>
5  *
6  * $Id: mod_ip_opt.c,v 1.7 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 *
ip_opt_close(void * d)20 ip_opt_close(void *d)
21 {
22 	if (d != NULL)
23 		free(d);
24 	return (NULL);
25 }
26 
27 void *
ip_opt_open(int argc,char * argv[])28 ip_opt_open(int argc, char *argv[])
29 {
30 	struct ip_opt *opt;
31 	struct addr addr;
32 	int i, j;
33 
34 	if (argc < 4)
35 		return (NULL);
36 
37 	if ((opt = calloc(1, sizeof(*opt))) == NULL)
38 		return (NULL);
39 
40 	if (strcasecmp(argv[1], "lsrr") == 0) {
41 		opt->opt_type = IP_OPT_LSRR;
42 	} else if (strcasecmp(argv[1], "ssrr") == 0) {
43 		opt->opt_type = IP_OPT_SSRR;
44 	} else
45 		return (ip_opt_close(opt));
46 
47 	if ((i = atoi(argv[2])) < 4 || i > 0xff) {
48 		warnx("<ptr> must be >= 4, and should be a multiple of 4");
49 		return (ip_opt_close(opt));
50 	}
51 	opt->opt_data.rr.ptr = i;
52 
53 	for (i = 3, j = 0; i < argc && j < 9; i++, j++) {
54 		if (addr_aton(argv[i], &addr) < 0) {
55 			return (ip_opt_close(opt));
56 		}
57 		opt->opt_data.rr.iplist[j] = addr.addr_ip;
58 	}
59 	opt->opt_len = IP_OPT_LEN + 1 + (IP_ADDR_LEN * j);
60 
61 	return (opt);
62 }
63 
64 int
ip_opt_apply(void * d,struct pktq * pktq)65 ip_opt_apply(void *d, struct pktq *pktq)
66 {
67 	struct ip_opt *opt = (struct ip_opt *)d;
68 	struct pkt *pkt;
69 	size_t len;
70 
71 	TAILQ_FOREACH(pkt, pktq, pkt_next) {
72 		len = ip_add_option(pkt->pkt_ip, PKT_BUF_LEN - ETH_HDR_LEN,
73 		    IP_PROTO_IP, opt, opt->opt_len);
74 
75 		if (len > 0) {
76 			pkt->pkt_end += len;
77 			pkt_decorate(pkt);
78 			ip_checksum(pkt->pkt_ip,
79 			    pkt->pkt_end - pkt->pkt_eth_data);
80 		}
81 	}
82 	return (0);
83 }
84 
85 struct mod mod_ip_opt = {
86 	"ip_opt",					/* name */
87 	"ip_opt lsrr|ssrr <ptr> <ip-addr> ...",		/* usage */
88 	ip_opt_open,					/* open */
89 	ip_opt_apply,					/* apply */
90 	ip_opt_close					/* close */
91 };
92