Annotation of embedaddon/hping2/sendicmp.c, revision 1.1.1.1
1.1 misho 1: /*
2: * $smu-mark$
3: * $name: sendicmp.c$
4: * $author: Salvatore Sanfilippo <antirez@invece.org>$
5: * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$
6: * $license: This software is under GPL version 2 of license$
7: * $date: Fri Nov 5 11:55:49 MET 1999$
8: * $rev: 8$
9: */
10:
11: /* $Id: sendicmp.c,v 1.9 2003/07/25 11:42:10 njombart Exp $ */
12:
13: #include <sys/types.h> /* this should be not needed, but ip_icmp.h lacks it */
14: #include <stdio.h>
15: #include <time.h>
16: #include <sys/time.h>
17: #include <stdlib.h>
18: #include <unistd.h>
19: #include <string.h>
20: #include <signal.h>
21: #include <errno.h>
22:
23: #include "hping2.h"
24: #include "globals.h"
25:
26: static int _icmp_seq = 0;
27:
28: void send_icmp_echo(void);
29: void send_icmp_other(void);
30: void send_icmp_timestamp(void);
31: void send_icmp_address(void);
32:
33: void send_icmp(void)
34: {
35: switch(opt_icmptype)
36: {
37: case ICMP_ECHO: /* type 8 */
38: case ICMP_ECHOREPLY: /* type 0 */
39: send_icmp_echo();
40: break;
41: case ICMP_DEST_UNREACH: /* type 3 */
42: case ICMP_SOURCE_QUENCH: /* type 4 */
43: case ICMP_REDIRECT: /* type 5 */
44: case ICMP_TIME_EXCEEDED: /* type 11 */
45: send_icmp_other();
46: break;
47: case ICMP_TIMESTAMP:
48: case ICMP_TIMESTAMPREPLY:
49: send_icmp_timestamp();
50: break;
51: case ICMP_ADDRESS:
52: case ICMP_ADDRESSREPLY:
53: send_icmp_address();
54: break;
55: default:
56: if (opt_force_icmp) {
57: send_icmp_other();
58: break;
59: } else {
60: printf("[send_icmp] Unsupported icmp type!\n");
61: exit(1);
62: }
63: }
64: }
65:
66: void send_icmp_echo(void)
67: {
68: char *packet, *data;
69: struct myicmphdr *icmp;
70:
71: packet = malloc(ICMPHDR_SIZE + data_size);
72: if (packet == NULL) {
73: perror("[send_icmp] malloc");
74: return;
75: }
76:
77: memset(packet, 0, ICMPHDR_SIZE + data_size);
78:
79: icmp = (struct myicmphdr*) packet;
80: data = packet + ICMPHDR_SIZE;
81:
82: /* fill icmp hdr */
83: icmp->type = opt_icmptype; /* echo replay or echo request */
84: icmp->code = opt_icmpcode; /* should be indifferent */
85: icmp->checksum = 0;
86: icmp->un.echo.id = getpid() & 0xffff;
87: icmp->un.echo.sequence = _icmp_seq;
88:
89: /* data */
90: data_handler(data, data_size);
91:
92: /* icmp checksum */
93: if (icmp_cksum == -1)
94: icmp->checksum = cksum((u_short*)packet, ICMPHDR_SIZE + data_size);
95: else
96: icmp->checksum = icmp_cksum;
97:
98: /* adds this pkt in delaytable */
99: if (opt_icmptype == ICMP_ECHO)
100: delaytable_add(_icmp_seq, 0, time(NULL), get_usec(), S_SENT);
101:
102: /* send packet */
103: send_ip_handler(packet, ICMPHDR_SIZE + data_size);
104: free (packet);
105:
106: _icmp_seq++;
107: }
108:
109: void send_icmp_timestamp(void)
110: {
111: char *packet;
112: struct myicmphdr *icmp;
113: struct icmp_tstamp_data *tstamp_data;
114:
115: packet = malloc(ICMPHDR_SIZE + sizeof(struct icmp_tstamp_data));
116: if (packet == NULL) {
117: perror("[send_icmp] malloc");
118: return;
119: }
120:
121: memset(packet, 0, ICMPHDR_SIZE + sizeof(struct icmp_tstamp_data));
122:
123: icmp = (struct myicmphdr*) packet;
124: tstamp_data = (struct icmp_tstamp_data*) (packet + ICMPHDR_SIZE);
125:
126: /* fill icmp hdr */
127: icmp->type = opt_icmptype; /* echo replay or echo request */
128: icmp->code = 0;
129: icmp->checksum = 0;
130: icmp->un.echo.id = getpid() & 0xffff;
131: icmp->un.echo.sequence = _icmp_seq;
132: tstamp_data->orig = htonl(get_midnight_ut_ms());
133: tstamp_data->recv = tstamp_data->tran = 0;
134:
135: /* icmp checksum */
136: if (icmp_cksum == -1)
137: icmp->checksum = cksum((u_short*)packet, ICMPHDR_SIZE +
138: sizeof(struct icmp_tstamp_data));
139: else
140: icmp->checksum = icmp_cksum;
141:
142: /* adds this pkt in delaytable */
143: if (opt_icmptype == ICMP_TIMESTAMP)
144: delaytable_add(_icmp_seq, 0, time(NULL), get_usec(), S_SENT);
145:
146: /* send packet */
147: send_ip_handler(packet, ICMPHDR_SIZE + sizeof(struct icmp_tstamp_data));
148: free (packet);
149:
150: _icmp_seq++;
151: }
152:
153: void send_icmp_address(void)
154: {
155: char *packet;
156: struct myicmphdr *icmp;
157:
158: packet = malloc(ICMPHDR_SIZE + 4);
159: if (packet == NULL) {
160: perror("[send_icmp] malloc");
161: return;
162: }
163:
164: memset(packet, 0, ICMPHDR_SIZE + 4);
165:
166: icmp = (struct myicmphdr*) packet;
167:
168: /* fill icmp hdr */
169: icmp->type = opt_icmptype; /* echo replay or echo request */
170: icmp->code = 0;
171: icmp->checksum = 0;
172: icmp->un.echo.id = getpid() & 0xffff;
173: icmp->un.echo.sequence = _icmp_seq;
174: memset(packet+ICMPHDR_SIZE, 0, 4);
175:
176: /* icmp checksum */
177: if (icmp_cksum == -1)
178: icmp->checksum = cksum((u_short*)packet, ICMPHDR_SIZE + 4);
179: else
180: icmp->checksum = icmp_cksum;
181:
182: /* adds this pkt in delaytable */
183: if (opt_icmptype == ICMP_TIMESTAMP)
184: delaytable_add(_icmp_seq, 0, time(NULL), get_usec(), S_SENT);
185:
186: /* send packet */
187: send_ip_handler(packet, ICMPHDR_SIZE + 4);
188: free (packet);
189:
190: _icmp_seq++;
191: }
192:
193: void send_icmp_other(void)
194: {
195: char *packet, *data, *ph_buf;
196: struct myicmphdr *icmp;
197: struct myiphdr icmp_ip;
198: struct myudphdr *icmp_udp;
199: int udp_data_len = 0;
200: struct pseudohdr *pseudoheader;
201: int left_space = IPHDR_SIZE + UDPHDR_SIZE + data_size;
202:
203: packet = malloc(ICMPHDR_SIZE + IPHDR_SIZE + UDPHDR_SIZE + data_size);
204: ph_buf = malloc(PSEUDOHDR_SIZE + UDPHDR_SIZE + udp_data_len);
205: if (packet == NULL || ph_buf == NULL) {
206: perror("[send_icmp] malloc");
207: return;
208: }
209:
210: memset(packet, 0, ICMPHDR_SIZE + IPHDR_SIZE + UDPHDR_SIZE + data_size);
211: memset(ph_buf, 0, PSEUDOHDR_SIZE + UDPHDR_SIZE + udp_data_len);
212:
213: icmp = (struct myicmphdr*) packet;
214: data = packet + ICMPHDR_SIZE;
215: pseudoheader = (struct pseudohdr *) ph_buf;
216: icmp_udp = (struct myudphdr *) (ph_buf + PSEUDOHDR_SIZE);
217:
218: /* fill icmp hdr */
219: icmp->type = opt_icmptype; /* ICMP_TIME_EXCEEDED */
220: icmp->code = opt_icmpcode; /* should be 0 (TTL) or 1 (FRAGTIME) */
221: icmp->checksum = 0;
222: if (opt_icmptype == ICMP_REDIRECT)
223: memcpy(&icmp->un.gateway, &icmp_gw.sin_addr.s_addr, 4);
224: else
225: icmp->un.gateway = 0; /* not used, MUST be 0 */
226:
227: /* concerned packet headers */
228: /* IP header */
229: icmp_ip.version = icmp_ip_version; /* 4 */
230: icmp_ip.ihl = icmp_ip_ihl; /* IPHDR_SIZE >> 2 */
231: icmp_ip.tos = icmp_ip_tos; /* 0 */
232: icmp_ip.tot_len = htons((icmp_ip_tot_len ? icmp_ip_tot_len : (icmp_ip_ihl<<2) + UDPHDR_SIZE + udp_data_len));
233: icmp_ip.id = htons(getpid() & 0xffff);
234: icmp_ip.frag_off = 0; /* 0 */
235: icmp_ip.ttl = 64; /* 64 */
236: icmp_ip.protocol = icmp_ip_protocol; /* 6 (TCP) */
237: icmp_ip.check = 0;
238: memcpy(&icmp_ip.saddr, &icmp_ip_src.sin_addr.s_addr, 4);
239: memcpy(&icmp_ip.daddr, &icmp_ip_dst.sin_addr.s_addr, 4);
240: icmp_ip.check = cksum((__u16 *) &icmp_ip, IPHDR_SIZE);
241:
242: /* UDP header */
243: memcpy(&pseudoheader->saddr, &icmp_ip_src.sin_addr.s_addr, 4);
244: memcpy(&pseudoheader->daddr, &icmp_ip_dst.sin_addr.s_addr, 4);
245: pseudoheader->protocol = icmp_ip.protocol;
246: pseudoheader->lenght = icmp_ip.tot_len;
247: icmp_udp->uh_sport = htons(icmp_ip_srcport);
248: icmp_udp->uh_dport = htons(icmp_ip_dstport);
249: icmp_udp->uh_ulen = htons(UDPHDR_SIZE + udp_data_len);
250: icmp_udp->uh_sum = cksum((__u16 *) ph_buf, PSEUDOHDR_SIZE + UDPHDR_SIZE + udp_data_len);
251:
252: /* filling icmp body with concerned packet header */
253:
254: /* fill IP */
255: if (left_space == 0) goto no_space_left;
256: memcpy(packet+ICMPHDR_SIZE, &icmp_ip, left_space);
257: left_space -= IPHDR_SIZE;
258: data += IPHDR_SIZE;
259: if (left_space <= 0) goto no_space_left;
260:
261: /* fill UDP */
262: memcpy(packet+ICMPHDR_SIZE+IPHDR_SIZE, icmp_udp, left_space);
263: left_space -= UDPHDR_SIZE;
264: data += UDPHDR_SIZE;
265: if (left_space <= 0) goto no_space_left;
266:
267: /* fill DATA */
268: data_handler(data, left_space);
269: no_space_left:
270:
271: /* icmp checksum */
272: if (icmp_cksum == -1)
273: icmp->checksum = cksum((u_short*)packet, ICMPHDR_SIZE + IPHDR_SIZE + UDPHDR_SIZE + data_size);
274: else
275: icmp->checksum = icmp_cksum;
276:
277: /* send packet */
278: send_ip_handler(packet, ICMPHDR_SIZE + IPHDR_SIZE + UDPHDR_SIZE + data_size);
279: free (packet);
280: free (ph_buf);
281: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>