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
|
/*
* traceroute.c - TCP/IPv6 traceroute tool
* $Id: trace-udp.c 332 2006-09-30 19:21:21Z remi $
*/
/***********************************************************************
* Copyright (C) 2005-2006 RĂ©mi Denis-Courmont. *
* This program is free software; you can redistribute and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation; version 2 of the license. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, you can get it from: *
* http://www.gnu.org/copyleft/gpl.html *
***********************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#undef _GNU_SOURCE
#define _BSD_SOURCE 1
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/socket.h> // SOCK_DGRAM
#include <netinet/in.h>
#include <netinet/udp.h>
#include "traceroute.h"
/* UDP probes (traditional traceroute) */
static ssize_t
send_udp_probe (int fd, unsigned ttl, unsigned n, size_t plen, uint16_t port)
{
if (plen < sizeof (struct udphdr))
plen = sizeof (struct udphdr);
struct
{
struct udphdr uh;
uint8_t payload[plen - sizeof (struct udphdr)];
} packet;
memset (&packet, 0, plen);
(void)n;
packet.uh.uh_sport = sport;
packet.uh.uh_dport = htons (ntohs (port) + ttl);
packet.uh.uh_ulen = htons (plen);
/*if (plen > sizeof (struct udphdr))
packet.payload[0] = (uint8_t)ttl;*/
return send_payload (fd, &packet, plen);
}
static ssize_t
parse_udp_error (const void *data, size_t len, unsigned *ttl, unsigned *n,
uint16_t port)
{
const struct udphdr *puh = (const struct udphdr *)data;
uint16_t rport;
if ((len < 4) || (puh->uh_sport != sport ))
return -1;
rport = ntohs (puh->uh_dport);
port = ntohs (port);
if ((rport < port) || (rport > port + 255))
return -1;
*ttl = rport - port;
*n = (unsigned)(-1);
return 0;
}
const tracetype udp_type =
{ SOCK_DGRAM, IPPROTO_UDP, 6,
send_udp_probe, NULL, parse_udp_error };
|