123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- /*
- * mod_ip_opt.c
- *
- * Copyright (c) 2001 Dug Song <dugsong@monkey.org>
- *
- * $Id$
- */
- #include "config.h"
- #include "defines.h"
- #include "common.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "pkt.h"
- #include "mod.h"
- #include "iputil.h"
- void *
- ip_opt_close(void *d)
- {
- if (d != NULL)
- free(d);
- return (NULL);
- }
- void *
- ip_opt_open(int argc, char *argv[])
- {
- struct ip_opt *opt;
- struct addr addr;
- int i, j;
-
- if (argc < 4)
- return (NULL);
-
- if ((opt = calloc(1, sizeof(*opt))) == NULL)
- return (NULL);
-
- if (strcasecmp(argv[1], "lsrr") == 0) {
- opt->opt_type = IP_OPT_LSRR;
- } else if (strcasecmp(argv[1], "ssrr") == 0) {
- opt->opt_type = IP_OPT_SSRR;
- } else if (strcasecmp(argv[1], "raw") == 0) {
- if (raw_ip_opt_parse(argc - 2, &argv[2], &opt->opt_type, &opt->opt_len,
- &opt->opt_data.data8[0], sizeof(opt->opt_data.data8)) != 0)
- return (ip_opt_close(opt));
- return opt;
- } else
- return (ip_opt_close(opt));
-
- if ((i = atoi(argv[2])) < 4 || i > 0xff) {
- warn("<ptr> must be >= 4, and should be a multiple of 4");
- return (ip_opt_close(opt));
- }
- opt->opt_data.rr.ptr = i;
-
- for (i = 3, j = 0; i < argc && j < 9; i++, j++) {
- if (addr_aton(argv[i], &addr) < 0) {
- return (ip_opt_close(opt));
- }
- opt->opt_data.rr.iplist[j] = addr.addr_ip;
- }
- opt->opt_len = IP_OPT_LEN + 1 + (IP_ADDR_LEN * j);
-
- return (opt);
- }
- int
- ip_opt_apply(void *d, struct pktq *pktq)
- {
- struct ip_opt *opt = (struct ip_opt *)d;
- struct pkt *pkt;
- size_t len;
- TAILQ_FOREACH(pkt, pktq, pkt_next) {
- uint16_t eth_type = htons(pkt->pkt_eth->eth_type);
- if (eth_type == ETH_TYPE_IP) {
- len = ip_add_option(pkt->pkt_ip, PKT_BUF_LEN - ETH_HDR_LEN,
- IP_PROTO_IP, opt, opt->opt_len);
- if (len > 0) {
- pkt->pkt_end += len;
- pkt_decorate(pkt);
- ip_checksum(pkt->pkt_ip,
- pkt->pkt_end - pkt->pkt_eth_data);
- }
- }
- }
- return (0);
- }
- struct mod mod_ip_opt = {
- "ip_opt", /* name */
- "ip_opt [lsrr|ssrr <ptr> <ip-addr> ...] | [raw <byte stream>]", /* usage */
- ip_opt_open, /* open */
- ip_opt_apply, /* apply */
- ip_opt_close /* close */
- };
|