00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
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)
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)
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