-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
117 lines (107 loc) · 3.11 KB
/
main.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
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: ttshivhu <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2018/10/10 13:32:14 by ttshivhu #+# #+# */
/* Updated: 2018/10/11 08:38:55 by ttshivhu ### ########.fr */
/* */
/* ************************************************************************** */
#include <traceroute.h>
void *create_msg(int hop, char *ip, char *buff)
{
struct ip *ip_hdr;
struct icmphdr *icmphd;
ip_hdr = (struct ip *)buff;
ip_hdr->ip_hl = 5;
ip_hdr->ip_v = 4;
ip_hdr->ip_tos = 0;
ip_hdr->ip_len = sizeof(struct ip) + sizeof(struct icmphdr);
ip_hdr->ip_id = 10000;
ip_hdr->ip_off = 0;
ip_hdr->ip_ttl = hop;
ip_hdr->ip_p = IPPROTO_ICMP;
inet_pton(AF_INET, ip, &(ip_hdr->ip_dst));
ip_hdr->ip_sum = checksum(buff, 9);
icmphd = (struct icmphdr *)(buff + sizeof(struct ip));
icmphd->type = ICMP_ECHO;
icmphd->code = 0;
icmphd->checksum = 0;
icmphd->un.echo.id = 0;
icmphd->un.echo.sequence = hop + 1;
icmphd->checksum = checksum((buff + 20), 4);
return (buff);
}
void init_trace(t_traceroute *trace)
{
int one;
int *val;
one = 1;
val = &one;
trace->hop = 1;
trace->tv_out.tv_sec = RECV_TIMEOUT;
trace->tv_out.tv_usec = 0;
trace->len = sizeof(struct sockaddr_in);
trace->buffer = malloc(4096);
trace->sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (setsockopt(trace->sockfd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0)
exit_err("error setsockopt\n");
setsockopt(trace->sockfd, SOL_SOCKET, SO_RCVTIMEO,
(const char *)&trace->tv_out, sizeof(trace->tv_out));
}
void print_results(int type, t_traceroute *p, int n)
{
struct ip *ip;
struct hostent *c;
char *ipa;
ipa = inet_ntoa(p->addr2.sin_addr);
ip = (struct ip *)p->buff;
c = gethostbyaddr((void*)&(ip->ip_src.s_addr),
sizeof(ip->ip_src.s_addr), AF_INET);
if (type == 1)
{
if (n == 0)
{
printf("%2d %s (%s) %.3f ms ", p->hop, c ? c->h_name : ipa,
ipa, p->total);
}
else
printf("%.3f ms%c", p->total, (n == 2) ? '\n' : ' ');
}
else
{
if (n == 0)
printf("%2d * ", p->hop);
else
printf("*%c", (n == 2) ? '\n' : ' ');
}
}
void ft_traceroute(t_traceroute *p)
{
while (42 && (!(p->hop == 31)))
{
p->i = -1;
if (per_hop(p))
break ;
p->hop++;
}
}
int main(int c, char **v)
{
t_traceroute trace;
(void)c;
init_trace(&trace);
help(c, v);
trace.ip = dns_lookup(v[1], &trace.addr);
if (trace.ip)
{
printf("traceroute to %s (%s), 30 hops max,", v[1], trace.ip);
printf(" %d byte packets\n", (int)(sizeof(struct ip) +
sizeof(struct icmphdr)));
ft_traceroute(&trace);
free(trace.buffer);
}
return (0);
}