-
Notifications
You must be signed in to change notification settings - Fork 335
/
sendip.c
127 lines (108 loc) · 3.11 KB
/
sendip.c
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
/*
* $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.2 2004/04/09 23:38:56 antirez 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_DARWIN || 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_DARWIN || 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 (close_pcap() == -1)
printf("[ipsender] close_pcap failed\n");
exit(1);
}
free(packet);
/* inc packet id for safe protocol */
if (opt_safe && !eof_reached)
src_id++;
}