summaryrefslogtreecommitdiff
path: root/other/itunnel
diff options
context:
space:
mode:
Diffstat (limited to 'other/itunnel')
-rw-r--r--other/itunnel/Makefile10
-rw-r--r--other/itunnel/it.c176
2 files changed, 186 insertions, 0 deletions
diff --git a/other/itunnel/Makefile b/other/itunnel/Makefile
new file mode 100644
index 0000000..72ba728
--- /dev/null
+++ b/other/itunnel/Makefile
@@ -0,0 +1,10 @@
1CC=gcc
2CFLAGS=-Wall
3
4all: it
5
6clean:
7 rm -f it
8
9%: %.c
10 $(CC) $(CFLAGS) -o $@ $<
diff --git a/other/itunnel/it.c b/other/itunnel/it.c
new file mode 100644
index 0000000..a1741c1
--- /dev/null
+++ b/other/itunnel/it.c
@@ -0,0 +1,176 @@
1/*
2 * itunnel - an ICMP tunnel by edi / teso
3 * usage: it [-i id] [-s packetsize] host
4 * establishes a bidirectional ICMP
5 * 'connection' with 'host' by listening
6 * to ICMP packets with a specific id
7 * (default: 7530). uses stdin and stdout
8 * and needs to run as root.
9 *
10 */
11
12#include <stdio.h>
13#include <unistd.h>
14#include <stdlib.h>
15#include <string.h>
16#include <sys/types.h>
17#include <sys/time.h>
18#include <sys/socket.h>
19#include <netinet/in_systm.h>
20#include <netinet/in.h>
21#include <netinet/ip.h>
22#include <arpa/inet.h>
23#include <netdb.h>
24
25struct icmp
26{
27 u_int8_t type;
28 u_int8_t code;
29 u_int16_t cksum;
30 u_int16_t id;
31 u_int16_t seq;
32};
33
34u_short in_cksum(u_short *, int);
35
36/* icmp_tunnel - does the ICMP tunneling :-)
37int sock - ICMP socket used to communicate
38struct sockaddr_in *target - other side
39int infd - input
40int outfd - output
41int packetsize - ...
42u_int16_t id - ...
43*/
44
45int icmp_tunnel(int sock, struct sockaddr_in *target, int infd, int outfd, int packetsize, u_int16_t id) {
46
47 char* packet;
48 struct icmp *icmp, *icmpr;
49 int len;
50 int result;
51 fd_set fs;
52
53 struct sockaddr_in from;
54 int fromlen;
55 int num;
56
57 len = sizeof (struct icmp);
58
59 packet = malloc (len+packetsize);
60 memset (packet, 0, len+packetsize);
61
62 icmp = (struct icmp*)(packet);
63 icmpr = (struct icmp*)(packet+sizeof(struct ip));
64
65 while (1) {
66 FD_ZERO (&fs);
67 FD_SET (infd, &fs);
68 FD_SET (sock, &fs);
69
70 select (infd>sock?infd+1:sock+1, &fs, NULL, NULL, NULL);
71
72 if (FD_ISSET (infd, &fs)) {
73 result = read (infd, packet+len, packetsize);
74 if (!result) {
75 return 0;
76 } else if (result==-1) {
77 perror ("read");
78 return -1;
79 }
80 icmp->type = 0;
81 icmp->code = 0;
82 icmp->id = id;
83 icmp->seq = 0;
84 icmp->cksum = 0;
85 icmp->cksum = in_cksum((u_short*)packet, len+result);
86 result = sendto (sock, (char*)packet, len+result, 0, (struct sockaddr*)target, sizeof (struct sockaddr_in));
87 if (result==-1) {
88 perror ("sendto");
89 return -1;
90 }
91 }
92 if (FD_ISSET (sock, &fs)) {
93 fromlen = sizeof (struct sockaddr_in);
94 num = recvfrom (sock, packet, len+packetsize, 0, (struct sockaddr*)&from, &fromlen);
95 if (icmpr->id == id) {
96 write (outfd, packet+sizeof(struct ip)+sizeof(struct icmp), num-sizeof(struct ip)-sizeof(struct icmp));
97 }
98 }
99 }
100
101
102 return 0;
103}
104
105int main (int argc, char** argv) {
106 struct sockaddr_in target;
107 int s;
108
109 int packetsize = 100;
110 char* desthost = NULL;
111 u_int16_t id = 7530;
112
113 argv++;
114 argc--;
115
116 while (argc--) {
117 if (!strcmp(*argv, "-i")) {
118 if (!argc--) {
119 fprintf (stderr, "need argument\n");
120 return -1;
121 }
122 argv++;
123 id = atoi(*argv++);
124 } else if (!strcmp(*argv, "-s")) {
125 if (!argc--) {
126 fprintf (stderr, "need argument\n");
127 return -1;
128 }
129 argv++;
130 packetsize = atoi(*argv++);
131 } else desthost = *argv++;
132 }
133
134 if (!desthost) {
135 fprintf (stderr, "no destination\n");
136 return -1;
137 }
138
139 if ((target.sin_addr.s_addr = inet_addr (desthost)) == -1) {
140 struct hostent* he;
141 if (!(he = gethostbyname (desthost))) {
142 herror ("gethostbyname");
143 return -1;
144 }
145 memcpy (&target.sin_addr.s_addr, he->h_addr, he->h_length);
146 }
147 target.sin_family = AF_INET;
148
149 if ( (s = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1) {
150 perror ("socket");
151 return -1;
152 }
153
154 icmp_tunnel(s, &target, STDIN_FILENO, STDOUT_FILENO, packetsize, id);
155
156 close(s);
157
158 return 0;
159}
160
161unsigned short
162in_cksum (addr, len)
163 u_short *addr;
164 int len;
165{
166 register int nleft = len;
167 register u_short *w = addr;
168 register int sum = 0;
169 u_short answer = 0;
170 while (nleft > 1) { sum += *w++; nleft -= 2; }
171 if (nleft == 1) { *(u_char *) (&answer) = *(u_char *) w; sum += answer; }
172 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
173 sum += (sum >> 16); /* add carry */
174 answer = ~sum; /* truncate to 16 bits */
175 return (answer);
176}