mtutest.c
上传用户:asjy5858
上传日期:2007-01-05
资源大小:2k
文件大小:4k
开发平台:

Unix_Linux

  1. /* http://www.cotse.com  Fear the swimming Elephant! */
  2. /*
  3.  * mtutest.c (C) 1995 Darren Reed <avalon@coombs.anu.edu.au>
  4.  *
  5.  * This was written to test what size TCP fragments would get through
  6.  * various TCP/IP packet filters, as used in IP firewalls.  In certain
  7.  * conditions, enough of the TCP header is missing for unpredictable
  8.  * results unless the filter is aware that this can happen.
  9.  *
  10.  * The author provides this program as-is, with no guarantee for its
  11.  * suitability for any specific purpose.  The author takes no responsibility
  12.  * for the misuse/abuse of this program and provides it for the sole purpose
  13.  * of testing packet filter policies.  This file maybe distributed freely
  14.  * providing it is not modified and that this notice remains in tact.
  15.  *
  16.  * This was written and tested (successfully) on SunOS 4.1.x.
  17.  * To compiile: cc -Bstatic mtutest.c -o mtutest -lkvm
  18.  */
  19. #include <stdio.h>
  20. #include <sys/types.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <unistd.h>
  24. #include <fcntl.h>
  25. #include <errno.h>
  26. #include <netdb.h>
  27. #include <sys/socket.h>
  28. #include <sys/sockio.h>
  29. #include <net/if.h>
  30. #include <netinet/in.h>
  31. #include <netinet/in_systm.h>
  32. #include <netinet/ip.h>
  33. #include <netinet/tcp.h>
  34. #include <signal.h>
  35. #include <kvm.h>
  36. #include <nlist.h>
  37. #define DESTIP "127.0.0.1"
  38. #define DESTPORT 7
  39. struct nlist nl[2] = {
  40. { "_ifnet" },
  41. { NULL }
  42. };
  43. char opts[8];
  44. struct ifnet *ifp, ifn;
  45. kvm_t *k;
  46. int mtu;
  47. aclock()
  48. {
  49. fprintf(stderr, "<alarm>");
  50. return 0;
  51. }
  52. fixmtu()
  53. {
  54. ifn.if_mtu = mtu;
  55. kvm_write(k, ifp, &ifn, sizeof(ifn));
  56. exit(0);
  57. }
  58. main(argc, argv)
  59. int argc;
  60. char *argv[];
  61. {
  62. struct sockaddr_in sin, loc;
  63. struct protoent *pe;
  64. struct ifaddr ifa;
  65. char ifname[16], buf[32], *lif = "le0";
  66. int fd, i, opt;
  67. if (argc > 1)
  68. lif = argv[1];
  69. k = kvm_open(NULL, NULL, NULL, O_RDWR, "mtutest");
  70. kvm_nlist(k, nl);
  71. signal(SIGALRM, aclock);
  72. if (kvm_read(k, nl[0].n_value, &ifp, sizeof(ifp)) == -1)
  73. perror("read");
  74. while (ifp) {
  75. if (kvm_read(k, ifp, &ifn, sizeof(ifn)) == -1)
  76. perror("read");
  77. if (kvm_read(k, ifn.if_name, ifname, sizeof(ifname)) == -1)
  78. perror("read");
  79. sprintf(ifname + strlen(ifname), "%d", ifn.if_unit);
  80. if (!strcmp(ifname, lif))
  81. break;
  82. ifp = ifn.if_next;
  83. }
  84. if (!ifp) {
  85. fprintf(stderr, "couldn't find %sn", lif);
  86. exit(1);
  87. }
  88. kvm_read(k, ifn.if_addrlist, &ifa, sizeof(ifa));
  89. signal(SIGINT, fixmtu);
  90. signal(SIGQUIT, fixmtu);
  91. signal(SIGHUP, fixmtu);
  92. mtu = ifn.if_mtu;
  93. if ((pe = getprotobyname("ip")) == NULL) {
  94. fprintf(stderr, "ip: unknown protocoln");
  95. exit(1);
  96. }
  97. bcopy((char *)&ifa.ifa_addr, (char *)&loc, sizeof(loc));
  98. bzero((char *)loc.sin_zero, sizeof(loc.sin_zero));
  99. loc.sin_family = AF_INET;
  100. loc.sin_port = 0;
  101. opts[IPOPT_OPTVAL] = IPOPT_NOP;
  102. opts[IPOPT_OLEN] = 0;
  103. opts[IPOPT_OFFSET] = 0;
  104. printf("name %stip %stmetric %dn", ifname, inet_ntoa(loc.sin_addr),
  105. ifn.if_mtu);
  106. printf("minlen: ip %d + tcp %d = %dn", sizeof(struct ip),
  107. sizeof(struct tcphdr),
  108. sizeof(struct ip) + sizeof(struct tcphdr));
  109. for (i = 20; i < 128; i += 2) {
  110. ifn.if_mtu = i;
  111. kvm_write(k, ifp, &ifn, sizeof(ifn));
  112. printf("mtu %d - ", i);
  113. fflush(stdout);
  114. fd = socket(AF_INET, SOCK_STREAM, 0);
  115. opt = 1;
  116. if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt,
  117. sizeof(opt)) == -1)
  118. perror("setsockopt");
  119. /* if (setsockopt(fd, pe->p_proto, IP_OPTIONS, opts, 4) == -1)
  120. perror("setsockopt");*/
  121. loc.sin_port = htons(0);
  122. bind(fd, &loc, sizeof(loc));
  123. bzero((char *)&sin, sizeof(sin));
  124. sin.sin_family = AF_INET;
  125. sin.sin_port = htons(DESTPORT);
  126. sin.sin_addr.s_addr = inet_addr(DESTIP);
  127. alarm(5);
  128. if (connect(fd, &sin, sizeof(sin)) == -1) {
  129. if (errno != EINTR)
  130. perror("connect");
  131. else
  132. printf("n");
  133. } else
  134. printf("connectedn");
  135. alarm(0);
  136. close(fd);
  137. sleep(1);
  138. }
  139. fixmtu();
  140. /*NOT REACHED*/
  141. }