mod_ip_opt.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * mod_ip_opt.c
  3. *
  4. * Copyright (c) 2001 Dug Song <dugsong@monkey.org>
  5. *
  6. * $Id: mod_ip_opt.c 2191 2009-02-01 21:34:27Z aturner $
  7. */
  8. #include "config.h"
  9. #include "defines.h"
  10. #include "common.h"
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include "pkt.h"
  15. #include "mod.h"
  16. void *
  17. ip_opt_close(void *d)
  18. {
  19. if (d != NULL)
  20. free(d);
  21. return (NULL);
  22. }
  23. void *
  24. ip_opt_open(int argc, char *argv[])
  25. {
  26. struct ip_opt *opt;
  27. struct addr addr;
  28. int i, j;
  29. if (argc < 4)
  30. return (NULL);
  31. if ((opt = calloc(1, sizeof(*opt))) == NULL)
  32. return (NULL);
  33. if (strcasecmp(argv[1], "lsrr") == 0) {
  34. opt->opt_type = IP_OPT_LSRR;
  35. } else if (strcasecmp(argv[1], "ssrr") == 0) {
  36. opt->opt_type = IP_OPT_SSRR;
  37. } else
  38. return (ip_opt_close(opt));
  39. if ((i = atoi(argv[2])) < 4 || i > 0xff) {
  40. warn("<ptr> must be >= 4, and should be a multiple of 4");
  41. return (ip_opt_close(opt));
  42. }
  43. opt->opt_data.rr.ptr = i;
  44. for (i = 3, j = 0; i < argc && j < 9; i++, j++) {
  45. if (addr_aton(argv[i], &addr) < 0) {
  46. return (ip_opt_close(opt));
  47. }
  48. opt->opt_data.rr.iplist[j] = addr.addr_ip;
  49. }
  50. opt->opt_len = IP_OPT_LEN + 1 + (IP_ADDR_LEN * j);
  51. return (opt);
  52. }
  53. int
  54. ip_opt_apply(void *d, struct pktq *pktq)
  55. {
  56. struct ip_opt *opt = (struct ip_opt *)d;
  57. struct pkt *pkt;
  58. size_t len;
  59. TAILQ_FOREACH(pkt, pktq, pkt_next) {
  60. len = ip_add_option(pkt->pkt_ip, PKT_BUF_LEN - ETH_HDR_LEN,
  61. IP_PROTO_IP, opt, opt->opt_len);
  62. if (len > 0) {
  63. pkt->pkt_end += len;
  64. pkt_decorate(pkt);
  65. ip_checksum(pkt->pkt_ip,
  66. pkt->pkt_end - pkt->pkt_eth_data);
  67. }
  68. }
  69. return (0);
  70. }
  71. struct mod mod_ip_opt = {
  72. "ip_opt", /* name */
  73. "ip_opt lsrr|ssrr <ptr> <ip-addr> ...", /* usage */
  74. ip_opt_open, /* open */
  75. ip_opt_apply, /* apply */
  76. ip_opt_close /* close */
  77. };