1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
/*
* $smu-mark$
* $name: sendip.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$
* $license: This software is under GPL version 2 of license$
* $date: Fri Nov 5 11:55:49 MET 1999$
* $rev: 8$
*/
/* $Id: sendip.c,v 1.7 2003/08/01 13:28:07 njombart Exp $ */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include "hping2.h"
#include "globals.h"
void send_ip (char* src, char *dst, char *data, unsigned int datalen,
int more_fragments, unsigned short fragoff, char *options,
char optlen)
{
char *packet;
int result,
packetsize;
struct myiphdr *ip;
packetsize = IPHDR_SIZE + optlen + datalen;
if ( (packet = malloc(packetsize)) == NULL) {
perror("[send_ip] malloc()");
return;
}
memset(packet, 0, packetsize);
ip = (struct myiphdr*) packet;
/* copy src and dst address */
memcpy(&ip->saddr, src, sizeof(ip->saddr));
memcpy(&ip->daddr, dst, sizeof(ip->daddr));
/* build ip header */
ip->version = 4;
ip->ihl = (IPHDR_SIZE + optlen + 3) >> 2;
ip->tos = ip_tos;
#if defined OSTYPE_FREEBSD || defined OSTYPE_NETBSD || defined OSTYPE_BSDI
/* FreeBSD */
/* NetBSD */
ip->tot_len = packetsize;
#else
/* Linux */
/* OpenBSD */
ip->tot_len = htons(packetsize);
#endif
if (!opt_fragment)
{
ip->id = (src_id == -1) ?
htons((unsigned short) rand()) :
htons((unsigned short) src_id);
}
else /* if you need fragmentation id must not be randomic */
{
/* FIXME: when frag. enabled sendip_handler shold inc. ip->id */
/* for every frame sent */
ip->id = (src_id == -1) ?
htons(getpid() & 255) :
htons((unsigned short) src_id);
}
#if defined OSTYPE_FREEBSD || defined OSTYPE_NETBSD | defined OSTYPE_BSDI
/* FreeBSD */
/* NetBSD */
ip->frag_off |= more_fragments;
ip->frag_off |= fragoff >> 3;
#else
/* Linux */
/* OpenBSD */
ip->frag_off |= htons(more_fragments);
ip->frag_off |= htons(fragoff >> 3); /* shift three flags bit */
#endif
ip->ttl = src_ttl;
if (opt_rawipmode) ip->protocol = raw_ip_protocol;
else if (opt_icmpmode) ip->protocol = 1; /* icmp */
else if (opt_udpmode) ip->protocol = 17; /* udp */
else ip->protocol = 6; /* tcp */
ip->check = 0; /* always computed by the kernel */
/* copies options */
if (options != NULL)
memcpy(packet+IPHDR_SIZE, options, optlen);
/* copies data */
memcpy(packet + IPHDR_SIZE + optlen, data, datalen);
if (opt_debug == TRUE)
{
unsigned int i;
for (i=0; i<packetsize; i++)
printf("%.2X ", packet[i]&255);
printf("\n");
}
result = sendto(sockraw, packet, packetsize, 0,
(struct sockaddr*)&remote, sizeof(remote));
if (result == -1 && errno != EINTR && !opt_rand_dest && !opt_rand_source) {
perror("[send_ip] sendto");
if (close(sockraw) == -1)
perror("[ipsender] close(sockraw)");
#if (!defined OSTYPE_LINUX) || (defined FORCE_LIBPCAP)
if (close_pcap() == -1)
printf("[ipsender] close_pcap failed\n");
#else
if (close_sockpacket(sockpacket) == -1)
perror("[ipsender] close(sockpacket)");
#endif /* ! OSTYPE_LINUX || FORCE_LIBPCAP */
exit(1);
}
free(packet);
/* inc packet id for safe protocol */
if (opt_safe && !eof_reached)
src_id++;
}
|