it.c
上传用户:lylmjq
上传日期:2020-10-14
资源大小:4k
文件大小:5k
- /*
- * itunnel - an ICMP tunnel by edi / teso
- * usage: it [-i id] [-s packetsize] host
- * establishes a bidirectional ICMP
- * 'connection' with 'host' by listening
- * to ICMP packets with a specific id
- * (default: 7530). uses stdin and stdout
- * and needs to run as root.
- *
- */
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <sys/socket.h>
- #include <netinet/in_systm.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <netinet/ip_icmp.h>
- #include <netinet/icmp6.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- /* struct icmp
- {
- uint8_t type;
- uint8_t code;
- uint16_t cksum;
- uint16_t id;
- uint16_t seq;
- }; */
- typedef uint16_t u_int16_t
- struct icmp {
- u_char type; /* type of message, see below */
- u_char code; /* type sub code */
- u_short cksum; /* ones complement cksum of struct */
- union {
- u_char ih_pptr; /* ICMP_PARAMPROB */
- struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
- struct ih_idseq {
- n_short icd_id;
- n_short icd_seq;
- } ih_idseq;
- struct ih_pmtu {
- u_short ih_unused;
- u_short ih_next_hop_mtu;
- }ih_mtu;
- int ih_void;
- } icmp_hun;
- /* u_short in_cksum(u_short *, int); */
- /* u_short in_cksum(u_short , int); */
- /* icmp_tunnel - does the ICMP tunneling :-)
- int sock - ICMP socket used to communicate
- struct sockaddr_in *target - other side
- int infd - input
- int outfd - output
- int packetsize - ...
- uint16_t id - ...
- */
- int icmp_tunnel(int sock, struct sockaddr_in *target, int infd, int outfd, int packetsize, uint16 id) {
- char* packet;
- struct icmp *icmp, *icmpr;
- int len;
- int result;
- fd_set fs;
- struct sockaddr_in from;
- int fromlen;
- int num;
- len = sizeof (struct icmp);
- packet = malloc (len+packetsize);
- memset (packet, 0, len+packetsize);
- icmp = (struct icmp*)(packet);
- icmpr = (struct icmp*)(packet+sizeof(struct ip));
- while (1) {
- FD_ZERO (&fs);
- FD_SET (infd, &fs);
- FD_SET (sock, &fs);
- select (infd>sock?infd+1:sock+1, &fs, NULL, NULL, NULL);
- if (FD_ISSET (infd, &fs)) {
- result = read (infd, packet+len, packetsize);
- if (!result) {
- return 0;
- } else if (result==-1) {
- perror ("read");
- return -1;
- }
- icmp->type = 0;
- icmp->code = 0;
- icmp->id = id;
- icmp->seq = 0;
- icmp->cksum = 0;
- icmp->cksum = in_cksum((u_short*)packet, len+result);
- result = sendto (sock, (char*)packet, len+result, 0, (struct sockaddr*)target, sizeof (struct sockaddr_in));
- if (result==-1) {
- perror ("sendto");
- return -1;
- }
- }
- if (FD_ISSET (sock, &fs)) {
- fromlen = sizeof (struct sockaddr_in);
- num = recvfrom (sock, packet, len+packetsize, 0, (struct sockaddr*)&from, &fromlen);
- if (icmpr->id == id) {
- write (outfd, packet+sizeof(struct ip)+sizeof(struct icmp), num-sizeof(struct ip)-sizeof(struct icmp));
- }
- }
- }
- return 0;
- }
- int main (int argc, char** argv) {
- struct sockaddr_in target;
- int s;
- int packetsize = 100;
- char* desthost = NULL;
- uint16_t id = 7530;
- argv++;
- argc--;
- while (argc--) {
- if (!strcmp(*argv, "-i")) {
- if (!argc--) {
- fprintf (stderr, "need argumentn");
- return -1;
- }
- argv++;
- id = atoi(*argv++);
- } else if (!strcmp(*argv, "-s")) {
- if (!argc--) {
- fprintf (stderr, "need argumentn");
- return -1;
- }
- argv++;
- packetsize = atoi(*argv++);
- } else desthost = *argv++;
- }
- if (!desthost) {
- fprintf (stderr, "no destinationn");
- return -1;
- }
- if ((target.sin_addr.s_addr = inet_addr (desthost)) == -1) {
- struct hostent* he;
- if (!(he = gethostbyname (desthost))) {
- herror ("gethostbyname");
- return -1;
- }
- memcpy (&target.sin_addr.s_addr, he->h_addr, he->h_length);
- }
- target.sin_family = AF_INET;
- if ( (s = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1) {
- perror ("socket");
- return -1;
- }
- icmp_tunnel(s, &target, STDIN_FILENO, STDOUT_FILENO, packetsize, id);
- close(s);
- return 0;
- }
- unsigned short
- /* u_short in_cksum(u_short , int); */
- in_cksum (u_short *addr, int len)
- u_short *addr;
- int len;
- {
- register int nleft = len;
- register u_short *w = addr;
- register int sum = 0;
- u_short answer = 0;
- while (nleft > 1) { sum += *w++; nleft -= 2; }
- if (nleft == 1) { *(u_char *) (&answer) = *(u_char *) w; sum += answer; }
- sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
- sum += (sum >> 16); /* add carry */
- answer = ~sum; /* truncate to 16 bits */
- return (answer);
- }