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>