diff --git a/.gitignore b/.gitignore index f7c9909..2bfc289 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ build # CLion .idea +cmake-build-debug/ # Visual Studio Code .vscode diff --git a/CMakeLists.txt b/CMakeLists.txt index 9fb0d76..47a9f3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5) -project(traceroute VERSION 0.4.190618) +project(Traceroute VERSION 0.5.190624) # COMPILER set(CMAKE_CXX_STANDARD 14) diff --git a/README.md b/README.md index 7c5a9d1..696a2e5 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,10 @@ Simple ICMP traceroute Traceroute shows a path through the Internet from your computer to a specified address. This implementation uses ICMP packages and raw sockets. ### Output format -When there are replies for *all* of the sent requests, then reply addresses are displayed with average reply time. +When there are replies for *any* of the sent requests, then reply addresses are displayed with +average reply time with count of responses. ``` -. [] -``` - -When there are replies for *some* of the sent requests, then reply addresses are displayed with question marks indicating unknown reply time. -``` -. ??? +. [ ( #include @@ -29,7 +29,7 @@ class ICMPController } void echo_request(const IPAddress & addr, uint16_t id, uint16_t ttl); - std::tuple, ssize_t> echo_reply(uint16_t id, uint16_t ttl); + std::tuple, size_t, size_t> echo_reply(uint16_t id, uint16_t ttl); private: IPAddress recv_echo(uint16_t id, uint16_t ttl); diff --git a/include/ICMPReceiver.hpp b/include/ICMPReceiver.hpp index 0992392..33b85f3 100644 --- a/include/ICMPReceiver.hpp +++ b/include/ICMPReceiver.hpp @@ -1,5 +1,5 @@ -#ifndef _ICMP_RECEIVER_HPP_ -#define _ICMP_RECEIVER_HPP_ +#ifndef ICMP_RECEIVER_HPP_ +#define ICMP_RECEIVER_HPP_ #include #include diff --git a/include/ICMPSender.hpp b/include/ICMPSender.hpp index d53353d..6a877b3 100644 --- a/include/ICMPSender.hpp +++ b/include/ICMPSender.hpp @@ -1,5 +1,5 @@ -#ifndef _ICMP_SENDER_HPP_ -#define _ICMP_SENDER_HPP_ +#ifndef ICMP_SENDER_HPP_ +#define ICMP_SENDER_HPP_ #include #include diff --git a/include/IPAddress.hpp b/include/IPAddress.hpp index 7eb0055..040fb96 100644 --- a/include/IPAddress.hpp +++ b/include/IPAddress.hpp @@ -1,5 +1,5 @@ -#ifndef _IP_ADDRESS_HPP_ -#define _IP_ADDRESS_HPP_ +#ifndef IP_ADDRESS_HPP_ +#define IP_ADDRESS_HPP_ #include #include diff --git a/include/RawSocket.hpp b/include/RawSocket.hpp index 8718f94..b169a68 100644 --- a/include/RawSocket.hpp +++ b/include/RawSocket.hpp @@ -1,5 +1,5 @@ -#ifndef _RAW_SOCKET_HPP_ -#define _RAW_SOCKET_HPP_ +#ifndef RAW_SOCKET_HPP_ +#define RAW_SOCKET_HPP_ #include #include diff --git a/src/ICMPController.cpp b/src/ICMPController.cpp index 020d572..9fba859 100644 --- a/src/ICMPController.cpp +++ b/src/ICMPController.cpp @@ -11,13 +11,14 @@ void ICMPController::echo_request(const IPAddress & addr, uint16_t id, uint16_t } } -std::tuple, ssize_t> ICMPController::echo_reply(uint16_t id, uint16_t ttl) +std::tuple, size_t, size_t> ICMPController::echo_reply(uint16_t id, + uint16_t ttl) { - std::set recvaddr; + std::set recv_addr; fd_set fd; timeval timer; - ssize_t avg_time = 0; - int recvnum = 0; + size_t avg_time = 0; + size_t recv_num = 0; FD_ZERO(&fd); FD_SET(socket.descriptor(), &fd); @@ -32,19 +33,19 @@ std::tuple, ssize_t> ICMPController::echo_reply(uint16_t id, throw SocketException(strerror(errno)); if(ready == 0) - return std::make_tuple(recvaddr, -1); + break; IPAddress address = recv_echo(id, ttl); if(address == IPAddress(0)) continue; - recvaddr.insert(address); + recv_addr.insert(address); avg_time = (avg_time + 1000000 - timer.tv_usec) / 2; - ++recvnum; - } while(recvnum < 3); + ++recv_num; + } while(recv_num < 3); - return std::make_tuple(recvaddr, avg_time); + return std::make_tuple(recv_addr, avg_time, recv_num); } IPAddress ICMPController::recv_echo(uint16_t id, uint16_t ttl) diff --git a/src/traceroute.cpp b/src/traceroute.cpp index 1810ae5..22f0456 100644 --- a/src/traceroute.cpp +++ b/src/traceroute.cpp @@ -9,25 +9,19 @@ #include "IPAddress.hpp" #include "RawSocket.hpp" -void print_results(uint16_t ttl, const std::set & recvaddr, ssize_t avg_time) +void print_results(uint16_t ttl, const std::set & recv_addr, size_t avg_time, + size_t recv_num) { std::cout << static_cast(ttl) << ". "; - if(avg_time < 0 && recvaddr.size() == 0) + if(recv_addr.empty()) std::cout << "*\n"; - else if(avg_time < 0) - { - for(auto addr : recvaddr) - std::cout << addr << " "; - - std::cout << "???\n"; - } else { - for(auto addr : recvaddr) + for(auto addr : recv_addr) std::cout << addr << " "; - std::cout << "[" << avg_time / 1000 << " ms]\n"; + std::cout << "[" << avg_time / 1000 << " ms (" << recv_num << ")]\n"; } } @@ -45,17 +39,20 @@ int main(int argc, char * argv[]) IPAddress addr(argv[1]); uint16_t pid = getpid(); + int steps = 30; + + std::cout << "traceroute :: destination " << addr << " :: max " << steps << " steps\n"; - for(int i = 1; i <= 30; ++i) + for(int i = 1; i <= steps; ++i) { - std::set recvaddr; - ssize_t avg_time; + std::set recv_addr; + size_t avg_time, recv_num; socket_ctrl.echo_request(addr, pid, i); - std::tie(recvaddr, avg_time) = socket_ctrl.echo_reply(pid, i); - print_results(i, recvaddr, avg_time); + std::tie(recv_addr, avg_time, recv_num) = socket_ctrl.echo_reply(pid, i); + print_results(i, recv_addr, avg_time, recv_num); - if(std::any_of(recvaddr.begin(), recvaddr.end(), + if(std::any_of(recv_addr.begin(), recv_addr.end(), [addr](const IPAddress & a) { return a == addr; })) break; }