Logo
~Sockets~
~Examples~
~Contact~


ICMPTwistSocket.cpp

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2004  Anders Hedstrom
00008 Parts Copyright (c) Vergil of Ragestorm.net, 2003
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00023 */
00024 #include <ISocketHandler.h>
00025 #include <stdint.h>
00026 #include <linux/types.h>
00027 #include <linux/icmp.h>
00028 #include <errno.h>
00029 #include <Utility.h>
00030 #include "ICMPTwistSocket.h"
00031 
00032 
00033 
00034 
00035 ICMPTwistSocket::ICMPTwistSocket(ISocketHandler& h) : Socket(h)
00036 ,m_seq_no(0)
00037 {
00038         SOCKET s = CreateSocket(AF_INET, SOCK_RAW, "icmp");
00039         if (s != INVALID_SOCKET)
00040         {
00041                 // socket to filter out irrelevant ICMP, and make IO non-blocking
00042                 static uint32_t flags = ~(1 << ICMP_INFO_REQUEST);
00043                 if (setsockopt(s, SOL_RAW, ICMP_FILTER, &flags, sizeof(uint32_t)) == -1)
00044                 {
00045                         Handler().LogError(this, "setsockopt", errno, strerror(errno));
00046                 }
00047                 Attach(s);
00048                 Set(true, false, false);
00049         }
00050         memset(&m_info, 0, sizeof(m_info));
00051         m_info.type = ICMP_INFO_REQUEST;
00052 }
00053 
00054 
00055 ICMPTwistSocket::~ICMPTwistSocket()
00056 {
00057 }
00058 
00059 
00060 void ICMPTwistSocket::OnRead()
00061 {
00062         int len;
00063         int hsize;
00064         uint8_t incoming[1000];
00065 
00066         if (recv(GetSocket(), m_info.buffer, 4, MSG_PEEK) != -1)
00067         {
00068                 len = ntohs(*(uint16_t *)(m_info.buffer + 2));
00069                 if (len < 1000)
00070                 {
00071                         if (recv(GetSocket(), incoming, len, 0) == -1)
00072                         {
00073                                 Handler().LogError(this, "recv", errno, strerror(errno), LOG_LEVEL_WARNING);
00074                         }
00075                         else
00076                         {
00077                                 // IP Header length + ICMP header length
00078                                 hsize = (m_info.buffer[0] & 0xf) << 2;
00079                                 uint16_t crc;
00080                                 memcpy(&crc, incoming + hsize + 2, 2);
00081                                 if (calc_crc(incoming + hsize, len - hsize) != crc) //*(uint16_t *)(incoming + hsize + 2))
00082                                 {
00083                                         printf("(Bad crc)\n");
00084                                 }
00085                                 else
00086                                 {
00087                                         printf("Received: %s\n", incoming + hsize + 8);
00088                                 }
00089                         }
00090                 }
00091         }
00092 }
00093 
00094 
00095 void ICMPTwistSocket::Connect(const std::string& host)
00096 {
00097         struct sockaddr_in dest;
00098         ipaddr_t a;
00099 
00100         if (Utility::u2ip(host, a))
00101         {
00102                 memset(&dest, 0, sizeof(dest));
00103                 dest.sin_port = htons(IPPROTO_ICMP);
00104                 dest.sin_family = AF_INET;
00105                 memcpy(&dest.sin_addr, &a, 4);
00106                 if (connect(GetSocket(), (struct sockaddr *)&dest, sizeof(struct sockaddr)) == -1)
00107                 {
00108                         Handler().LogError(this, "Connect", errno, strerror(errno), LOG_LEVEL_FATAL);
00109                         SetCloseAndDelete();
00110                 }
00111         }
00112         else
00113         {
00114                 printf("u2ip failed\n");
00115         }
00116 }
00117 
00118 
00119 void ICMPTwistSocket::Send(const std::string& line)
00120 {
00121         strcpy(m_info.buffer, line.c_str());
00122         int len = line.size() + 9;
00123         m_info.checksum = calc_crc((uint8_t *)&m_info, len);
00124         int n;
00125         if ((n = send(GetSocket(), (void *)&m_info, len, 0)) == -1)
00126         {
00127                 Handler().LogError(this, "Send", errno, strerror(errno));
00128         }
00129         m_info.seq_no = htons(m_seq_no++);
00130 }
00131 
00132 
00133 uint16_t ICMPTwistSocket::calc_crc(uint8_t * packet, size_t len)
00134 {
00135         uint16_t r;
00136         uint16_t i;
00137         uint32_t s;
00138 
00139         s = (packet[0] << 8) + packet[1];
00140         for (i = 4; i < len - 1; i += 2)
00141         {
00142                 s += (packet[i] << 8) + packet[i + 1];
00143         }
00144         if (len % 2)    // an extra member
00145         {
00146                 s += packet[len - 1] << 8;
00147         }
00148         s = (s & 0xffff) + (s >> 16);
00149         r = s + (s >> 16);
00150         return htons(~r);
00151 }
00152 
00153 
Page, code, and content Copyright (C) 2006 by Anders Hedström
Generated on Mon Aug 29 20:21:47 2005 for C++ Sockets by  doxygen 1.4.4