File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / hping2 / sendicmp.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:11:37 2012 UTC (12 years, 3 months ago) by misho
Branches: hping2, MAIN
CVS tags: v2_0_0rc3p7, v2_0_0rc3p5, v2_0_0rc3p4, v2_0_0rc3p0, v2_0_0rc3, HEAD
hping2

    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.1.1.1 2012/02/21 22:11:37 misho 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>