Annotation of embedaddon/hping2/sendicmp.c, revision 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>