1 #include <errno.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <unistd.h> 6 #include <fcntl.h> 7 #include <poller.h> 8 #include <time.h> 9 #include <sys/types.h> 10 #include <sys/socket.h> 11 #include <sys/ioctl.h> 12 #include <netinet/in.h> 13 #include <netinet/ip.h> 14 #include <netinet/ip_icmp.h> 15 #include <netinet/tcp.h> 16 #include <netinet/udp.h> 17 #include <arpa/inet.h> 18 #include <linux/if.h> 19 #include <linux/if_tun.h> 20 #include <inttypes.h> 21 22 int tunfd, poller; 23 struct sockaddr_in socks_server; 24 25 struct connection 26 { 27 int fd; 28 #define TCPCON 0 29 #define UDPCON 1 30 unsigned int type : 1; 31 int status : 4; 32 unsigned int fin : 2; 33 unsigned int reserved : 1; 34 35 uint32_t seq, ack_seq, echo; 36 uint16_t id, mss; 37 char * buffer; 38 size_t buflen; 39 char orig[68]; 40 struct sockaddr_in local, remote; 41 struct connection * prev, * next; 42 } * first_connection = NULL; 43 44 struct connection * 45 find_connection (struct in_addr src, uint16_t srcport, 46 struct in_addr dst, uint16_t dstport, int type) 47 { 48 struct connection * now; 49 50 for (now = first_connection; now != NULL; now = now->next) 51 { 52 if (((now->local.sin_addr.s_addr == src.s_addr 53 && now->local.sin_port == srcport 54 && now->remote.sin_addr.s_addr == dst.s_addr 55 && now->remote.sin_port == dstport) 56 || (now->remote.sin_addr.s_addr == src.s_addr 57 && now->remote.sin_port == srcport 58 && now->local.sin_addr.s_addr == dst.s_addr 59 && now->local.sin_port == dstport)) 60 && (!type || type == now->type)) 61 return now; 62 } 63 return NULL; 64 } 65 66 void 67 remove_connection (struct connection * conn) 68 { 69 if (conn->buffer != NULL) 70 free (conn->buffer); 71 if (conn->next != NULL) 72 conn->next->prev = conn->prev; 73 if (conn->prev != NULL) 74 conn->prev->next = conn->next; 75 if (conn == first_connection) 76 first_connection = conn->next; 77 free (conn); 78 } 79 80 #define Econnrefused -1 81 #define Enetunreach -2 82 #define Ehostunreach -3 83 #define Ettlexpired -4 84 85 int 86 socks_connect () 87 { 88 int sock; 89 unsigned char buf[280]; 90 91 sock = socket (AF_INET, SOCK_STREAM, 0); 92 if (sock < 0) 93 return Enetunreach; 94 95 if (connect (sock, (struct sockaddr *) &socks_server, sizeof (socks_server))) 96 goto close_netunreach; 97 98 buf[0] = 5; 99 buf[1] = 1; 100 buf[2] = 0; 101 102 if (write (sock, buf, 3) < 3) 103 goto close_netunreach; 104 105 return sock; 106 107 close_netunreach: 108 close (sock); 109 return Enetunreach; 110 } 111 112 int 113 socks_connect2 (struct connection * conn) 114 { 115 unsigned char buf[280]; 116 size_t toread; 117 int err; 118 119 if (conn->status == 0) 120 { 121 if (read (conn->fd, buf, 2) < 2) 122 goto close_netunreach; 123 124 if (buf[0] != 0x05 && buf[1] != 0x00) 125 goto close_netunreach; 126 127 buf[0] = 5; 128 buf[1] = conn->type == TCPCON ? 1 : 3; 129 buf[2] = 0; 130 buf[3] = 1; 131 if (conn->type == TCPCON) 132 { 133 memcpy (buf+4, &conn->remote.sin_addr, 4); 134 memcpy (buf+8, &conn->remote.sin_port, 2); 135 } 136 else 137 memset (buf+4, 0, 6); 138 if (write (conn->fd, buf, 10) < 10) 139 goto close_netunreach; 140 141 return 1; 142 } 143 else if (conn->status == 1) 144 { 145 if (read (conn->fd, buf, 5) < 5) 146 goto close_netunreach; 147 148 if (buf[0] != 5 || buf[2] != 0) 149 goto close_netunreach; 150 151 switch (buf[1]) 152 { 153 case 0: 154 err = 0; 155 break; 156 case 4: 157 err = Ehostunreach; 158 break; 159 case 5: 160 err = Econnrefused; 161 break; 162 case 6: 163 err = Ettlexpired; 164 break; 165 default: 166 err = Enetunreach; 167 } 168 169 if (err) 170 { 171 close (conn->fd); 172 return err; 173 } 174 175 if (buf[3] == 1) 176 toread = 6-1; 177 else if (buf[3] == 3) 178 toread = buf[4] + 2; 179 else if (buf[3] == 4) 180 toread = 18-1; 181 else 182 goto close_netunreach; 183 184 if (read (conn->fd, buf, toread) < toread) 185 goto close_netunreach; 186 187 return 2; 188 } 189 190 close_netunreach: 191 close (conn->fd); 192 return Enetunreach; 193 } 194 195 int 196 tun_alloc (char * dev) 197 { 198 struct ifreq ifr; 199 int fd, err; 200 201 if ((fd = open ("/dev/net/tun", O_RDWR)) < 0) 202 return (-1); 203 204 memset (&ifr, 0, sizeof (ifr)); 205 ifr.ifr_flags = IFF_TUN | IFF_NO_PI; 206 if (*dev) 207 strncpy (ifr.ifr_name, dev, IFNAMSIZ); 208 209 if ((err = ioctl (fd, TUNSETIFF, (void *) &ifr)) < 0) 210 { 211 close (fd); 212 return err; 213 } 214 strcpy (dev, ifr.ifr_name); 215 216 return fd; 217 } 218 219 static inline int16_t 220 csum_add (int16_t sum, int16_t addend) 221 { 222 uint32_t res = (uint32_t) sum; 223 res += (uint32_t) addend; 224 return (int16_t) (res + (res < (uint32_t) addend)); 225 } 226 227 static inline int16_t 228 ip_tcpudp_csum (struct in_addr * src, struct in_addr * dst) 229 { 230 int16_t csum = 0; 231 csum = csum_add (csum, ntohs (*((int16_t *) src))); 232 csum = csum_add (csum, ntohs (*(((int16_t *) src)+1))); 233 csum = csum_add (csum, ntohs (*((int16_t *) dst))); 234 csum = csum_add (csum, ntohs (*(((int16_t *) dst)+1))); 235 return csum; 236 } 237 238 void 239 parse_tcp_opts (char * buf, size_t len, uint16_t * mss, uint8_t * wscale, 240 int * sack, uint32_t * timestamp, uint32_t * echo) 241 { 242 size_t now = 0; 243 244 if (mss != NULL) 245 *mss = 0; 246 if (wscale != NULL) 247 *wscale = 0; 248 if (sack != NULL) 249 *sack = 0; 250 if (timestamp != NULL && echo != NULL) 251 *timestamp = *echo = 0; 252 253 while (now < len) 254 { 255 if (buf[now] == 0) 256 break; 257 else if (buf[now] == 1) 258 now ++; 259 else if (buf[now] == 2 && buf[now+1] == 4) 260 { 261 if (mss != NULL) 262 *mss = (buf[now+2] << 8) | (buf[now+3] & 0xff); 263 now += 4; 264 } 265 else if (buf[now] == 3 && buf[now+1] == 3) 266 { 267 if (wscale != NULL) 268 *wscale = buf[now+2]; 269 now += 3; 270 } 271 else if (buf[now] == 4 && buf[now+1] == 2) 272 { 273 if (sack != NULL) 274 *sack = 1; 275 now += 2; 276 } 277 else if (buf[now] == 8 && buf[now+1] == 10) 278 { 279 if (timestamp != NULL && echo != NULL) 280 { 281 *timestamp = ntohl (*((uint32_t *) (buf + now + 2))); 282 *echo = ntohl (*((uint32_t *) (buf + now + 6))); 283 } 284 now += 10; 285 } 286 } 287 } 288 289 size_t 290 build_tcp (char * buf, int16_t csum, uint16_t source, uint16_t dest, 291 uint32_t seq, uint32_t ack_seq, int syn, int ack, int psh, int rst, 292 int fin, uint16_t window, uint16_t mss, uint8_t wscale, int sack, 293 uint32_t timestamp, uint32_t echo, char * data, size_t len) 294 { 295 struct tcphdr * h = (struct tcphdr *) buf; 296 size_t hlen = 20; 297 int i; 298 299 memset (buf, 0, hlen); 300 301 h->source = htons (source); 302 h->dest = htons (dest); 303 h->seq = htonl (seq); 304 h->ack_seq = htonl (ack_seq); 305 if (syn) 306 h->syn = 1; 307 if (ack) 308 h->ack = 1; 309 if (psh) 310 h->psh = 1; 311 if (rst) 312 h->rst = 1; 313 if (fin) 314 h->fin = 1; 315 h->window = htons (window); 316 h->urg_ptr = 0; 317 if (mss) 318 { 319 buf[hlen++] = 2; 320 buf[hlen++] = 4; 321 buf[hlen++] = (mss >> 8) & 0xff; 322 buf[hlen++] = mss & 0xff; 323 } 324 if (sack) 325 { 326 buf[hlen++] = 4; 327 buf[hlen++] = 2; 328 } 329 if (timestamp) 330 { 331 buf[hlen++] = 8; 332 buf[hlen++] = 10; 333 *((uint32_t *) (buf + hlen)) = htonl (timestamp); 334 *((uint32_t *) (buf + hlen + 4)) = htonl (echo); 335 hlen += 8; 336 } 337 if (wscale) 338 { 339 if ((hlen >> 1) & 1) 340 { 341 buf[hlen++] = 1; 342 buf[hlen++] = 1; 343 } 344 buf[hlen++] = 1; 345 buf[hlen++] = 3; 346 buf[hlen++] = 3; 347 buf[hlen++] = wscale; 348 } 349 while (hlen % 4) 350 buf[hlen++] = 1; 351 h->doff = hlen/4; 352 if (data != NULL && len > 0) 353 memcpy (buf + hlen, data, len); 354 csum = csum_add (csum, IPPROTO_TCP); 355 csum = csum_add (csum, hlen+len); 356 for (i = 0; i < hlen+len; i += 2) 357 csum = csum_add (csum, ntohs (*(int16_t *) (buf + i))); 358 if (len & 1) 359 csum = csum_add (csum, buf[hlen+len-1] << 8); 360 h->check = htons (~csum); 361 return (hlen+len); 362 } 363 364 size_t 365 build_udp (char * buf, int16_t csum, uint16_t source, uint16_t dest, 366 char * data, size_t len) 367 { 368 struct udphdr * h = (struct udphdr *) buf; 369 int i; 370 371 h->source = htons (source); 372 h->dest = htons (dest); 373 h->len = htons (8+len); 374 h->check = 0; 375 csum = csum_add (csum, IPPROTO_UDP); 376 csum = csum_add (csum, 8+len); 377 for (i = 0; i < 8+len; i += 2) 378 csum = csum_add (csum, ntohs (*(int16_t *) (buf + i))); 379 if (len & 1) 380 csum = csum_add (csum, buf[8+len-1] << 8); 381 h->check = htons (~csum); 382 return (8+len); 383 } 384 385 size_t 386 build_icmp (char * buf, uint8_t type, uint8_t code, struct ip * orig) 387 { 388 struct icmphdr * h = (struct icmphdr *) buf; 389 int16_t csum = 0; 390 size_t origlen; 391 int i; 392 393 memset (buf, 0, 8); 394 395 h->type = type; 396 h->code = code; 397 for (i = 0; i < 8; i += 2) 398 csum = csum_add (csum, ntohs (*(int16_t *) (buf + i))); 399 h->checksum = htons (~csum); 400 401 #define MIN(a,b) ((a)<(b)?(a):(b)) 402 origlen = MIN(orig->ip_hl*4 + 8, orig->ip_len); 403 404 if (orig != NULL) 405 memcpy (buf+8, orig, origlen); 406 407 return (8+origlen); 408 } 409 410 void 411 build_ip (char * buf, uint16_t len, uint16_t id, uint16_t off, uint8_t ttl, 412 uint8_t prot, struct in_addr src, struct in_addr dst) 413 { 414 struct ip * h = (struct ip *) buf; 415 uint16_t csum = 0; 416 int i; 417 418 memset (buf, 0, 20); 419 420 h->ip_v = 4; 421 h->ip_hl = 5; 422 h->ip_len = htons (len); 423 h->ip_id = htons (id); 424 h->ip_off = htons (off); 425 h->ip_ttl = ttl; 426 h->ip_p = prot; 427 h->ip_src = src; 428 h->ip_dst = dst; 429 for (i = 0; i < 20; i += 2) 430 csum = csum_add (csum, ntohs (*(int16_t *) (buf + i))); 431 h->ip_sum = htons (~csum); 432 } 433 434 void 435 polled (pollerdata_t data, pollerev_t events) 436 { 437 if (data.ptr == NULL) 438 { 439 unsigned char buf[65536]; 440 struct ip * iph; 441 442 read (tunfd, buf, 65536); 443 iph = (struct ip *) buf; 444 if (iph->ip_v == 4) 445 { 446 struct connection * conn; 447 char reply[100]; 448 int16_t csum; 449 size_t datalen; 450 451 if (iph->ip_p == IPPROTO_TCP) 452 { 453 struct tcphdr * tcph; 454 uint32_t nullecho; 455 size_t tcplen; 456 457 tcph = (struct tcphdr *) (buf + iph->ip_hl*4); 458 459 conn = find_connection (iph->ip_src, tcph->source, 460 iph->ip_dst, tcph->dest, TCPCON); 461 462 if (tcph->syn && !tcph->ack && !tcph->ack_seq && conn == NULL) 463 { 464 int connfd; 465 466 connfd = socks_connect (); 467 if (connfd == Econnrefused) 468 { 469 csum = ip_tcpudp_csum (&iph->ip_src, &iph->ip_dst); 470 471 tcplen = build_tcp (reply + 20, csum, ntohs (tcph->dest), 472 ntohs (tcph->source), 0, ntohl (tcph->seq) + 1, 0, 1, 473 0, 1, 0, 0, 0, 0, 0, 0, 0, NULL, 0); 474 475 build_ip (reply, 20 + tcplen, 0, IP_DF, 64, IPPROTO_TCP, 476 iph->ip_dst, iph->ip_src); 477 478 write (tunfd, reply, 20 + tcplen); 479 } 480 else if (connfd < 0) 481 { 482 uint8_t _type, _code; 483 size_t icmplen; 484 485 if (connfd == Ettlexpired) 486 _type = 11, _code = 0; 487 else if (connfd == Ehostunreach) 488 _type = 3, _code = 1; 489 else 490 _type = 3, _code = 0; 491 492 icmplen = build_icmp (reply + 20, _type, _code, 493 (struct ip *) buf); 494 495 build_ip (reply, 20 + icmplen, 0, 0, 64, IPPROTO_ICMP, 496 iph->ip_dst, iph->ip_src); 497 498 write (tunfd, reply, 20 + icmplen); 499 } 500 else 501 { 502 conn = malloc (sizeof (struct connection)); 503 504 conn->local.sin_family = AF_INET; 505 conn->local.sin_addr = iph->ip_src; 506 conn->local.sin_port = tcph->source; 507 conn->remote.sin_family = AF_INET; 508 conn->remote.sin_addr = iph->ip_dst; 509 conn->remote.sin_port = tcph->dest; 510 511 conn->type = TCPCON; 512 conn->fd = connfd; 513 conn->status = 0; 514 515 conn->prev = NULL; 516 if (first_connection) 517 first_connection->prev = conn; 518 conn->next = first_connection; 519 first_connection = conn; 520 521 conn->buffer = NULL; 522 conn->buflen = 0; 523 524 parse_tcp_opts (buf + 40, (tcph->doff-5)*4, &conn->mss, 525 NULL, NULL, &conn->echo, &nullecho); 526 conn->seq = rand (); 527 conn->ack_seq = ntohl (tcph->seq) + 1; 528 conn->fin = 0; 529 530 conn->id = rand (); 531 532 memcpy (conn->orig, buf, 68); 533 534 data.ptr = (void *) conn; 535 poller_add (poller, connfd, POLLERIN, data); 536 } 537 } 538 else if (conn != NULL && conn->status == 2) 539 { 540 if (tcph->rst) 541 goto connterm; 542 543 parse_tcp_opts (buf + 40, (tcph->doff-5)*4, NULL, NULL, NULL, 544 &conn->echo, &nullecho); 545 546 datalen = ntohs (iph->ip_len) - 20 - tcph->doff*4; 547 if (datalen > 0 && !(conn->fin & 1)) 548 { 549 conn->buffer = realloc (conn->buffer, 550 conn->buflen + datalen); 551 memcpy (conn->buffer + conn->buflen, 552 ((char *) tcph) + tcph->doff*4, datalen); 553 conn->buflen += datalen; 554 conn->ack_seq += datalen; 555 } 556 557 if (tcph->psh && !(conn->fin & 1)) 558 { 559 if (write (conn->fd, conn->buffer, conn->buflen) < conn->buflen) 560 fprintf (stderr, "Could not write everything!\n"); 561 562 free (conn->buffer); 563 conn->buffer = NULL; 564 conn->buflen = 0; 565 } 566 567 if (tcph->fin) 568 { 569 conn->fin |= 1; 570 if (conn->fin < 3) 571 shutdown (conn->fd, SHUT_WR); 572 conn->ack_seq ++; 573 } 574 575 if (tcph->ack && ((!tcph->fin && datalen > 0) 576 || (tcph->fin && conn->fin == 3))) 577 { 578 csum = ip_tcpudp_csum (&iph->ip_src, &iph->ip_dst); 579 580 tcplen = build_tcp (reply + 20, csum, ntohs (tcph->dest), 581 ntohs (tcph->source), conn->seq, conn->ack_seq, 0, 1, 582 0, 0, 0, 65535, 0, 0, 0, time (NULL), conn->echo, 583 NULL, 0); 584 585 build_ip (reply, 20 + tcplen, conn->id++, IP_DF, 64, 586 IPPROTO_TCP, iph->ip_dst, iph->ip_src); 587 588 write (tunfd, reply, 20 + tcplen); 589 } 590 591 if (conn->fin == 3) 592 { 593 connterm: 594 close (conn->fd); 595 poller_remove (poller, conn->fd); 596 remove_connection (conn); 597 } 598 } 599 } 600 else if (iph->ip_p == IPPROTO_UDP) 601 { 602 struct udphdr * udph; 603 size_t udplen; 604 605 udph = (struct udphdr *) (buf + iph->ip_hl*4); 606 607 conn = find_connection (iph->ip_src, udph->source, 608 (struct in_addr) {INADDR_ANY}, 0, 609 UDPCON); 610 611 if (conn == NULL) 612 { 613 int connfd; 614 615 connfd = socks_connect (); 616 if (connfd < 0) 617 { 618 uint8_t _type, _code; 619 size_t icmplen; 620 621 if (connfd == Ettlexpired) 622 _type = 11, _code = 0; 623 else if (connfd == Econnrefused) 624 _type = 3, _code = 3; 625 else if (connfd == Ehostunreach) 626 _type = 3, _code = 1; 627 else 628 _type = 3, _code = 0; 629 630 icmplen = build_icmp (reply + 20, _type, _code, 631 (struct ip *) buf); 632 633 build_ip (reply, 20 + icmplen, 0, 0, 64, IPPROTO_ICMP, 634 iph->ip_dst, iph->ip_src); 635 636 write (tunfd, reply, 20 + icmplen); 637 } 638 else 639 { 640 conn = malloc (sizeof (struct connection)); 641 642 conn->local.sin_family = AF_INET; 643 conn->local.sin_addr = iph->ip_src; 644 conn->local.sin_port = udph->source; 645 conn->remote.sin_family = AF_INET; 646 conn->remote.sin_addr.s_addr = INADDR_ANY; 647 conn->remote.sin_port = 0; 648 649 conn->type = UDPCON; 650 conn->fd = connfd; 651 conn->status = 0; 652 653 conn->prev = NULL; 654 if (first_connection) 655 first_connection->prev = conn; 656 conn->next = first_connection; 657 first_connection = conn; 658 659 datalen = ntohs (udph->len) - 8; 660 conn->buffer = malloc (datalen + 10); 661 conn->buflen = datalen + 10; 662 memcpy (conn->buffer + 10, buf + iph->ip_hl*4 + 8, 663 conn->buflen - 10); 664 665 conn->buffer[0] = 0; 666 conn->buffer[1] = 0; 667 conn->buffer[2] = 0; 668 conn->buffer[3] = 1; 669 memcpy (conn->buffer + 4, &iph->ip_dst, 4); 670 memcpy (conn->buffer + 8, &udph->dest, 2); 671 672 conn->id = rand (); 673 674 memcpy (conn->orig, buf, 68); 675 676 data.ptr = (void *) conn; 677 poller_add (poller, connfd, POLLERIN, data); 678 } 679 } 680 else 681 { 682 datalen = ntohs (udph->len) - 8; 683 684 if (datalen) 685 { 686 conn->buffer = realloc (conn->buffer, 687 conn->buflen + datalen); 688 memcpy (conn->buffer + conn->buflen, ((char *) udph) + 8, 689 datalen); 690 conn->buflen += datalen; 691 } 692 693 if (conn->status == 2 && conn->buffer != NULL 694 && conn->buflen > 0) 695 { 696 memcpy (conn->buffer + 4, &iph->ip_dst, 4); 697 memcpy (conn->buffer + 8, &udph->dest, 2); 698 699 if (write (conn->fd, conn->buffer, conn->buflen) < conn->buflen) 700 { 701 fprintf (stderr, "Could not write everything!\n"); 702 } 703 704 conn->buffer = realloc (conn->buffer, 10); 705 conn->buflen = 10; 706 } 707 } 708 } 709 } 710 else if (iph->ip_v == 6) 711 { 712 /* IPv6 zatial nepodporujeme */ 713 struct ip6_hdr * ip6h; 714 } 715 } 716 else 717 { 718 struct connection * conn = (struct connection *) data.ptr; 719 char buf[65536], reply[65536]; 720 size_t plen, icmplen; 721 int16_t csum; 722 ssize_t nr; 723 724 if (conn->status < 2) 725 { 726 conn->status = socks_connect2 (conn); 727 if (conn->status == Econnrefused && conn->type == TCPCON) 728 { 729 csum = ip_tcpudp_csum (&conn->local.sin_addr, &conn->remote.sin_addr); 730 731 plen = build_tcp (reply + 20, csum, ntohs (conn->remote.sin_port), 732 ntohs (conn->local.sin_port), 0, conn->ack_seq, 0, 1, 733 0, 1, 0, 0, 0, 0, 0, 0, 0, NULL, 0); 734 735 build_ip (reply, 20 + plen, 0, IP_DF, 64, IPPROTO_TCP, 736 conn->remote.sin_addr, conn->local.sin_addr); 737 738 write (tunfd, reply, 20 + plen); 739 } 740 else if (conn->status < 0) 741 { 742 uint8_t _type, _code; 743 size_t icmplen; 744 745 if (conn->status == Ettlexpired) 746 _type = 11, _code = 0; 747 else if (conn->status == Econnrefused) 748 _type = 3, _code = 3; 749 else if (conn->status == Ehostunreach) 750 _type = 3, _code = 1; 751 else 752 _type = 3, _code = 0; 753 754 icmplen = build_icmp (reply + 20, _type, _code, 755 (struct ip *) conn->orig); 756 757 build_ip (reply, 20 + icmplen, 0, 0, 64, IPPROTO_ICMP, 758 conn->remote.sin_addr, conn->local.sin_addr); 759 760 write (tunfd, reply, 20 + icmplen); 761 } 762 else if (conn->status == 2 && conn->type == TCPCON) 763 { 764 csum = ip_tcpudp_csum (&conn->local.sin_addr, 765 &conn->remote.sin_addr); 766 767 plen = build_tcp (reply + 20, csum, ntohs (conn->remote.sin_port), 768 ntohs (conn->local.sin_port), conn->seq - 1, conn->ack_seq, 1, 769 1, 0, 0, 0, 65535, conn->mss, 0, 1, time (NULL), conn->echo, 770 NULL, 0); 771 772 build_ip (reply, 20 + plen, 0, IP_DF, 64, IPPROTO_TCP, 773 conn->remote.sin_addr, conn->local.sin_addr); 774 775 write (tunfd, reply, 20 + plen); 776 return; 777 } 778 else if (conn->status == 2 && conn->type == UDPCON && conn->buflen) 779 { 780 if (write (conn->fd, conn->buffer, conn->buflen) < conn->buflen) 781 fprintf (stderr, "Could not write everything!\n"); 782 783 conn->buffer = realloc (conn->buffer, 10); 784 conn->buflen = 10; 785 return; 786 } 787 else 788 return; 789 790 poller_remove (poller, conn->fd); 791 remove_connection (conn); 792 return; 793 } 794 795 nr = read (conn->fd, buf, 65536); 796 if (nr < 1) 797 { 798 close (conn->fd); 799 poller_remove (poller, conn->fd); 800 801 if (conn->type == UDPCON) 802 { 803 remove_connection (conn); 804 return; 805 } 806 807 conn->fin |= 2; 808 809 csum = ip_tcpudp_csum (&conn->local.sin_addr, &conn->remote.sin_addr); 810 811 plen = build_tcp (reply + 20, csum, ntohs (conn->remote.sin_port), 812 ntohs (conn->local.sin_port), conn->seq, conn->ack_seq, 813 0, 1, 0, 0, 1, 65535, 0, 0, 0, time (NULL), conn->echo, NULL, 0); 814 815 build_ip (reply, 20 + plen, conn->id++, IP_DF, 64, IPPROTO_TCP, 816 conn->remote.sin_addr, conn->local.sin_addr); 817 818 write (tunfd, reply, 20 + plen); 819 820 conn->seq ++; 821 822 if (conn->fin == 3) 823 remove_connection (conn); 824 } 825 else if (conn->type == TCPCON || (conn->type == UDPCON && conn->buflen > 10 826 && !memcmp (conn->buffer, (char[]) {0, 0, 0, 1}, 4))) 827 { 828 csum = ip_tcpudp_csum (&conn->local.sin_addr, &conn->remote.sin_addr); 829 830 if (conn->type == TCPCON) 831 plen = build_tcp (reply + 20, csum, ntohs (conn->remote.sin_port), 832 ntohs (conn->local.sin_port), conn->seq, conn->ack_seq, 833 0, 1, 1, 0, 0, 65535, 0, 0, 0, time (NULL), conn->echo, buf, nr); 834 else 835 plen = build_udp (reply + 20, csum, ntohs (*(uint16_t *) (conn->buffer + 8)), 836 ntohs (conn->local.sin_port), buf + 10, nr - 10); 837 838 build_ip (reply, 20 + plen, conn->id++, IP_DF, 64, 839 conn->type == TCPCON ? IPPROTO_TCP : IPPROTO_UDP, 840 conn->type == TCPCON ? conn->remote.sin_addr 841 : (*(struct in_addr *) (conn->buffer + 4)), conn->local.sin_addr); 842 843 conn->seq += nr; 844 845 write (tunfd, reply, 20 + plen); 846 } 847 } 848 } 849 850 int 851 main (int argc, char ** argv) 852 { 853 char ifnam[IFNAMSIZ], * tmp; 854 long int port; 855 pollerdata_t data; 856 struct connection * conn, * nextconn; 857 858 srand (time (NULL) ^ getpid ()); 859 860 if (argc < 4) 861 { 862 fprintf (stderr, "usage: %s <tun_interface> <socks_server_ip> " 863 "<socks_server_port>\n\n", argv[0]); 864 exit (EXIT_FAILURE); 865 } 866 867 socks_server.sin_family = AF_INET; 868 869 if (!inet_pton (AF_INET, argv[2], &socks_server.sin_addr.s_addr)) 870 { 871 fprintf (stderr, "Invalid SOCKS server IP address!\n\n"); 872 exit (EXIT_FAILURE); 873 } 874 875 port = strtol (argv[3], &tmp, 10); 876 if (*tmp != '\0' || port < 1 || port > 65535) 877 { 878 fprintf (stderr, "Invalid SOCKS server port!\n\n"); 879 exit (EXIT_FAILURE); 880 } 881 882 socks_server.sin_port = htons (port); 883 884 strcpy (ifnam, argv[1]); 885 tunfd = tun_alloc (ifnam); 886 if (tunfd < 0) 887 { 888 fprintf (stderr, "Cannot allocate tun interface %s!\n\n", ifnam); 889 exit (EXIT_FAILURE); 890 } 891 892 poller = poller_create (); 893 if (poller < 0) 894 { 895 fprintf (stderr, "Cannot create poller!\n\n"); 896 close (tunfd); 897 exit (EXIT_FAILURE); 898 } 899 900 data.ptr = NULL; 901 poller_add (poller, tunfd, POLLERIN, data); 902 903 while (poller_poll (poller, -1, polled) > 0) 904 ; 905 906 for (conn = first_connection; conn != NULL; conn = nextconn) 907 { 908 nextconn = conn->next; 909 poller_remove (poller, conn->fd); 910 close (conn->fd); 911 free (conn); 912 } 913 914 poller_destroy (poller); 915 close (tunfd); 916 exit (0); 917 } 918