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>