Advertisement
Guest User

Untitled

a guest
Jun 19th, 2017
484
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.47 KB | None | 0 0
  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. #include <sys/time.h>
  4.  
  5. #include <netinet/in.h>
  6. #include <netinet/in_systm.h>
  7. #include <netinet/ip.h>
  8. #include <machine/in_cksum.h>
  9. #include <netinet/tcp.h>
  10. #include <netinet/udp.h>
  11. #include <netinet/ip_icmp.h>
  12. #include <sys/ioctl.h>
  13. #include <net/if.h>
  14. #include <net/route.h>
  15. #include <arpa/inet.h>
  16.  
  17. #include <sys/types.h>
  18. #include <sys/socket.h>
  19. #include <sys/time.h>
  20.  
  21. #include <netinet/in.h>
  22. #include <netinet/in_systm.h>
  23. #include <netinet/ip.h>
  24. #include <machine/in_cksum.h>
  25. #include <netinet/tcp.h>
  26. #include <netinet/udp.h>
  27. #include <netinet/ip_icmp.h>
  28. #include <sys/ioctl.h>
  29. #include <net/if.h>
  30. #include <net/route.h>
  31. #include <arpa/inet.h>
  32.  
  33. #include <alias.h>
  34. #include <ctype.h>
  35. #include <err.h>
  36. #include <errno.h>
  37. #include <netdb.h>
  38. #include <signal.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include <syslog.h>
  43. #include <unistd.h>
  44. #include <ctype.h>
  45. #include <err.h>
  46. #include <errno.h>
  47. #include <netdb.h>
  48. #include <signal.h>
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #include <string.h>
  52. #include <syslog.h>
  53. #include <unistd.h>
  54.  
  55. #define DIVERT_PORT 7000
  56. #define FALSE 0
  57. #define TRUE 1
  58.  
  59. #define CKSUM_CARRY(x) \
  60. (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff))
  61.  
  62. typedef unsigned char Boolean;
  63.  
  64. static unsigned char pbuf[IP_MAXPACKET];
  65. static unsigned long plen = 0;
  66. static int psock = -1;
  67. static struct sockaddr_in paddr;
  68.  
  69. /*
  70. * These are stolen from libnet.
  71. */
  72. int in_cksum(u_short *addr, int len)
  73. {
  74. int sum;
  75. int nleft;
  76. u_short ans;
  77. u_short *w;
  78.  
  79. sum = 0;
  80. ans = 0;
  81. nleft = len;
  82. w = addr;
  83.  
  84. while (nleft > 1) {
  85. sum += *w++;
  86. nleft -= 2;
  87. }
  88. if (nleft == 1) {
  89. *(u_char *)(&ans) = *(u_char *)w;
  90. sum += ans;
  91. }
  92. return (sum);
  93. }
  94.  
  95. void do_cksum(unsigned char *buf, int protocol, int len)
  96. {
  97. struct ip *ip;
  98. unsigned long ip_hl = 0;
  99. unsigned long sum = 0;
  100.  
  101. ip = (struct ip *)buf;
  102. ip_hl = ip->ip_hl << 2;
  103.  
  104. switch(protocol) {
  105. case IPPROTO_TCP: {
  106. struct tcphdr *tcp;
  107.  
  108. tcp = (struct tcphdr *)(buf + ip_hl);
  109. tcp->th_sum = 0;
  110. sum = in_cksum((u_short *)&(ip->ip_src), 8);
  111. sum += ntohs(IPPROTO_TCP + len);
  112. sum += in_cksum((u_short *)tcp, len);
  113. tcp->th_sum = CKSUM_CARRY(sum);
  114. break;
  115. }
  116. default:
  117. return;
  118. }
  119. return;
  120. }
  121.  
  122. void flushpacket(int fd)
  123. {
  124. int nR;
  125.  
  126. nR = sendto(fd,
  127. pbuf,
  128. plen,
  129. 0,
  130. (struct sockaddr*) &paddr,
  131. sizeof(paddr));
  132.  
  133. if (nR != plen) {
  134. if (errno == ENOBUFS)
  135. return;
  136. if (errno == EMSGSIZE) {
  137. fprintf(stderr, "Need to implement frag.\n");
  138. return;
  139. }
  140. else {
  141. fprintf(stderr, "Failed to write packet.\n");
  142. return;
  143. }
  144. }
  145.  
  146. psock = -1;
  147. }
  148.  
  149. void handle_input(int sock)
  150. {
  151. int nR = 0;
  152. int addrsize = 0;
  153. struct ip *ip;
  154. Boolean fIsOutput = FALSE;
  155. unsigned int ip_hl = 0, tcp_hl = 0;
  156. unsigned int ip_data_len = 0;
  157. struct tcphdr *tcp = NULL;
  158.  
  159.  
  160. addrsize = sizeof(struct sockaddr_in);
  161. nR = recvfrom(sock,
  162. pbuf, sizeof(pbuf), 0,
  163. (struct sockaddr *)&paddr,
  164. &addrsize);
  165. if (nR == -1) {
  166. if (errno != EINTR)
  167. fprintf(stderr, "Warning : recvfrom() failed.\n");
  168. goto over;
  169. }
  170. ip = (struct ip *)pbuf;
  171. ip_hl = ip->ip_hl << 2;
  172.  
  173. /* Check if this is input or output */
  174. if (paddr.sin_addr.s_addr == INADDR_ANY)
  175. fIsOutput = TRUE;
  176. else
  177. fIsOutput = FALSE;
  178.  
  179. /* We are only handling TCP packets */
  180. if (ip->ip_p != IPPROTO_TCP)
  181. goto over;
  182.  
  183. /* Get the TCP header */
  184. tcp = (struct tcphdr *) (pbuf + ip_hl);
  185. tcp_hl = tcp->th_off << 2;
  186. ip_data_len = ntohs(ip->ip_len) - ip_hl;
  187. /* Sanity check packet length */
  188. if (ip_data_len <= 0)
  189. goto over;
  190.  
  191. /* Add ECE and CWR flags to TCP header */
  192. tcp->th_flags |= (0x40 | 0x80);
  193. /* Compute new checksum */
  194. do_cksum(pbuf, IPPROTO_TCP, ip_data_len);
  195.  
  196.  
  197. /* Write packet back */
  198. plen = nR;
  199. psock = sock;
  200. flushpacket(sock);
  201.  
  202. over:
  203. return;
  204. }
  205.  
  206. int main(int argc, char **argv)
  207. {
  208. int inoutsock = -1;
  209. fd_set rfs, wfs;
  210. int fdmax = -1;
  211. struct sockaddr_in addr;
  212. int rc;
  213.  
  214. /* Create divert sockets */
  215. if ((inoutsock = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT)) == -1) {
  216. fprintf(stderr, "socket() failed, exiting\n");
  217. exit(1);
  218. }
  219. /* Bind socket */
  220. addr.sin_family = AF_INET;
  221. addr.sin_addr.s_addr = INADDR_ANY;
  222. addr.sin_port = ntohs(DIVERT_PORT);
  223.  
  224. if (bind(inoutsock,
  225. (struct sockaddr*) &addr,
  226. sizeof(struct sockaddr_in)) == -1) {
  227. fprintf(stderr, "Unable to bind socket, exiting\n");
  228. exit(1);
  229. }
  230.  
  231. while (1) {
  232. FD_ZERO(&rfs);
  233. FD_ZERO(&wfs);
  234.  
  235. if (psock != -1)
  236. FD_SET(psock, &wfs);
  237. FD_SET(inoutsock, &rfs);
  238.  
  239. if (inoutsock > psock)
  240. fdmax = inoutsock;
  241. else
  242. fdmax = psock;
  243.  
  244. /* Select loop */
  245. rc = select(fdmax + 1, &rfs, &wfs, NULL, NULL);
  246. if (rc == -1) {
  247. if (errno == EINTR)
  248. continue;
  249. fprintf(stderr, "select() failed, exiting\n");
  250. exit(1);
  251. }
  252. /* Check for flush from previous packet */
  253. if (psock != -1) {
  254. if (FD_ISSET(psock, &wfs))
  255. flushpacket(psock);
  256. }
  257. /* Do we have input available ? */
  258. if (FD_ISSET(inoutsock, &rfs)) {
  259. /* Yip, handle it */
  260. handle_input(inoutsock);
  261. }
  262. }
  263. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement