forked from Neirth/FreeNOS
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added netping application for sending and receiving ping/pong packets…
… with libnet.
- Loading branch information
1 parent
e30de74
commit f199b94
Showing
4 changed files
with
347 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,33 @@ | ||
/* | ||
* Copyright (C) 2015 Niek Linnenbank | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* 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, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include <Log.h> | ||
#include <KernelLog.h> | ||
#include "NetPing.h" | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
/* | ||
* TODO: StdioLog does not work yet for libipc because inside ChannelClient() | ||
* there may also be a call to DEBUG() or ERROR(). | ||
*/ | ||
KernelLog log; | ||
log.setMinimumLogLevel(Log::Debug); | ||
|
||
NetPing app(argc, argv); | ||
return app.run(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,223 @@ | ||
/* | ||
* Copyright (C) 2015 Niek Linnenbank | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* 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, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include <FreeNOS/System.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <fcntl.h> | ||
#include <unistd.h> | ||
#include <errno.h> | ||
#include <string.h> | ||
#include <MemoryBlock.h> | ||
#include <NetworkClient.h> | ||
#include <NetworkSocket.h> | ||
#include <IPV4.h> | ||
#include <ICMP.h> | ||
#include "NetPing.h" | ||
|
||
// | ||
// Send manual formatted network packets: | ||
// | ||
// $ NetPing smsc --arp --dest=192.168.1.123 | ||
// | ||
// Receive and dump network packets: | ||
// | ||
// $ netrecv smsc | ||
// | ||
// Change device parameters: | ||
// | ||
// $ devctl smsc ip_address=192.168.1.2 ether_address=00:11:22:33:44:55 | ||
// $ devctl serial0 baudrate=9600 | ||
// | ||
// Show device status and statistics: | ||
// | ||
// $ devstat smsc | ||
// $ devstat serial0 | ||
// | ||
|
||
NetPing::NetPing(int argc, char **argv) | ||
: POSIXApplication(argc, argv) | ||
{ | ||
m_socket = 0; | ||
|
||
m_parser.setDescription("send network pings"); | ||
m_parser.registerPositional("DEVICE", "device name of network adapter"); | ||
m_parser.registerPositional("HOST", "host address to ping"); | ||
m_parser.registerPositional("ARGS", "optional key=value arguments", 0); | ||
m_parser.registerFlag('a', "arp", "send ARP pings"); | ||
m_parser.registerFlag('i', "icmp", "send ICMP pings"); | ||
} | ||
|
||
NetPing::~NetPing() | ||
{ | ||
} | ||
|
||
NetPing::Result NetPing::initialize() | ||
{ | ||
DEBUG(""); | ||
|
||
const char *dev = m_arguments.get("DEVICE"); | ||
const char *host = m_arguments.get("HOST"); | ||
const char *icmp = m_arguments.get("icmp"); | ||
const char *arp = m_arguments.get("arp"); | ||
|
||
if (dev) | ||
DEBUG("sending on device: " << dev); | ||
|
||
if (icmp) | ||
{ | ||
DEBUG("sending ICMP packets"); | ||
icmpPing(dev, host); | ||
} | ||
else if (dev && host) | ||
{ | ||
DEBUG("sending ARP packets"); | ||
arpPing(dev, host); | ||
} | ||
else usage(); | ||
|
||
return Success; | ||
} | ||
|
||
NetPing::Result NetPing::exec() | ||
{ | ||
DEBUG(""); | ||
return Success; | ||
} | ||
|
||
NetPing::Result NetPing::arpPing(const char *dev, | ||
const char *host) | ||
{ | ||
DEBUG(""); | ||
|
||
NetworkClient client(dev); | ||
Ethernet::Address ethAddr; | ||
IPV4::Address ipAddr; | ||
Size bytes; | ||
int sock, r; | ||
|
||
// Initialize networking client | ||
if (client.initialize() != NetworkClient::Success) | ||
{ | ||
ERROR("failed to initialize network client for device: " << dev); | ||
return IOError; | ||
} | ||
|
||
// Create an ARP socket | ||
if (client.createSocket(NetworkClient::ARP, &sock) != NetworkClient::Success) | ||
{ | ||
ERROR("failed to create ARP socket"); | ||
return IOError; | ||
} | ||
|
||
// Convert to IPV4 address | ||
if (!(ipAddr = IPV4::toAddress(host))) | ||
{ | ||
ERROR("failed to convert to IPV4 address: " << host); | ||
return IOError; | ||
} | ||
|
||
// Send ARP request | ||
if (::write(sock, &ipAddr, sizeof(ipAddr)) < 0) | ||
{ | ||
ERROR("failed to send ARP request: " << strerror(errno)); | ||
return IOError; | ||
} | ||
// Receive ARP reply, if any | ||
// TODO: set a timeout on this call | ||
if (::read(sock, ðAddr, sizeof(ethAddr)) < 0) | ||
{ | ||
ERROR("failed to receive ARP response: " << strerror(errno)); | ||
return IOError; | ||
} | ||
// Print the MAC address received | ||
printf("Received reply for: "); | ||
|
||
for (Size i = 0; i < sizeof(Ethernet::Address); i ) | ||
printf("%x:", ethAddr.addr[i]); | ||
printf("\n"); | ||
|
||
// Finished | ||
client.close(sock); | ||
return Success; | ||
} | ||
|
||
NetPing::Result NetPing::icmpPing(const char *dev, const char *host) | ||
{ | ||
DEBUG(""); | ||
|
||
NetworkClient client(dev); | ||
Ethernet::Address ethAddr; | ||
int sock; | ||
Size bytes; | ||
|
||
// Initialize networking client | ||
if (client.initialize() != NetworkClient::Success) | ||
{ | ||
ERROR("failed to initialize network client for device: " << dev); | ||
return IOError; | ||
} | ||
|
||
// Create an ICMP socket | ||
if (client.createSocket(NetworkClient::ICMP, &sock) != NetworkClient::Success) | ||
{ | ||
ERROR("failed to create ARP socket"); | ||
return IOError; | ||
} | ||
// Connect socket to the given host | ||
if (client.connectSocket(sock, IPV4::toAddress(host)) != NetworkClient::Success) | ||
{ | ||
ERROR("failed to connect ICMP socket"); | ||
return IOError; | ||
} | ||
// Send an echo request | ||
ICMP::Header msg; | ||
msg.type = ICMP::EchoRequest; | ||
msg.code = 0; | ||
msg.checksum = 0; | ||
msg.id = 1; | ||
msg.sequence = 1; | ||
|
||
// Generate checksum | ||
msg.checksum = ICMP::checksum(&msg); | ||
|
||
// Send the packet | ||
if (::write(sock, &msg, sizeof(msg)) <= 0) | ||
{ | ||
ERROR("failed to send ICMP request"); | ||
return IOError; | ||
} | ||
// Receive echo reply | ||
if (::read(sock, &msg, sizeof(msg)) <= 0) | ||
{ | ||
ERROR("failed to receive ICMP response"); | ||
return IOError; | ||
} | ||
// Check message type | ||
if (msg.type != ICMP::EchoReply) | ||
{ | ||
ERROR("invalid ICMP code in response: " << (int) msg.type); | ||
return IOError; | ||
} | ||
// Print the ICMP address received | ||
printf("Received ICMP response with id=%d sequence=%d\n", | ||
msg.id, msg.sequence); | ||
|
||
// Finished | ||
::close(sock); | ||
return Success; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,68 @@ | ||
/* | ||
* Copyright (C) 2015 Niek Linnenbank | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* 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, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#ifndef __BIN_NETPING_H | ||
#define __BIN_NETPING_H | ||
|
||
#include <IPV4.h> | ||
#include <Ethernet.h> | ||
#include <POSIXApplication.h> | ||
|
||
/** | ||
* Network ping/pong application. | ||
*/ | ||
class NetPing : public POSIXApplication | ||
{ | ||
public: | ||
|
||
/** | ||
* Class constructor. | ||
*/ | ||
NetPing(int argc, char **argv); | ||
|
||
/** | ||
* Class destructor. | ||
*/ | ||
virtual ~NetPing(); | ||
|
||
/** | ||
* Initialize the application. | ||
*/ | ||
virtual Result initialize(); | ||
|
||
/** | ||
* Execute the application event loop. | ||
*/ | ||
virtual Result exec(); | ||
|
||
private: | ||
|
||
/** | ||
* Send ARP ping/pong. | ||
*/ | ||
Result arpPing(const char *dev, const char *host); | ||
|
||
/** | ||
* Send ICMP ping/pong. | ||
*/ | ||
Result icmpPing(const char *dev, const char *host); | ||
|
||
/** Socket */ | ||
int m_socket; | ||
}; | ||
|
||
#endif /* __BIN_NETPING_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,23 @@ | ||
# | ||
# Copyright (C) 2010 Niek Linnenbank | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 3 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# 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, see <http://www.gnu.org/licenses/>. | ||
# | ||
|
||
Import('build_env') | ||
|
||
env = build_env.Clone() | ||
env.UseLibraries([ 'libposix', 'liballoc', 'libstd', 'libexec', 'libarch', 'libnet', 'libipc', 'libfs' ]) | ||
env.UseServers(['core']) | ||
env.TargetProgram('netping', Glob('*.cpp'), env['bin']) |