IPPOLib
 All Classes Files Functions Variables Typedefs Macros
probereply.cpp
Go to the documentation of this file.
1 /*
2  * ippo-lib - IP oPtion-based active PrObing
3  * An Active Probing Library for IP Options Equipped probes (http://traffic.comics.unina.it/ippolib)
4  *
5  * Copyright : (C) 2012 by Pietro Marchetta, Walter de Donato, Francesco Cesareo,
6  * Antonio Pescape' (PI)
7  * of the COMICS (COMputer for Interaction and
8  * CommunicationS) Group, Dipartimento di Informatica
9  * e Sistemistica of the University of Napoli "Federico II".
10  *
11  * email : pietro.marchetta@unina.it , walter.dedonato@unina.it , cesareo.francesco@gmail.com
12  * pescape@unina.it
13  *
14  * This program is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation, either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program. If not, see <http://www.gnu.org/licenses/>.
26  *
27  */
28 
29 #include "probereply.h"
30 #include "util.h"
31 
32 #include <iostream>
33 #include <string.h>
34 #include <stdlib.h>
35 
40 {
41  memset(_probe, 0, sizeof (_probe));
42  _scan_result = NO_RESPONSE;
43  _has_response = false;
44  _options = false;
45  _ihl = -1;
46  _code = -1;
47  _subcode = -1;
48 }
49 
54 {
55  delete []_probe;
56 }
57 
58 /********************/
60 /********************/
61 
65 void ProbeReply::_dissect()
66 {
67  _ip_buf = (struct iphdr *) &_probe;
68 
69  _src_addr_raw = _ip_buf->saddr;
70  _dst_addr_raw = _ip_buf->daddr;
71 
72  // dissect packet
73  if (ip_protocol() == 1)
74  {
75  _dissect_icmp(ihl());
76  _dissect_iperror(ihl()+ICMP_SIZE);
77  }
78  else if (ip_protocol() == 6)
79  {
80  _dissect_tcp(ihl());
81  }
82 
83  // analyse option
84  if (ihl() > 36)
85  _options = true;
86 
87 }
88 
93 void ProbeReply::_dissect_icmp(int offset)
94 {
95  _icmp_buf = (struct icmp*) &_probe[offset];
96 
97  _code = _icmp_buf->icmp_type;
98  _subcode = _icmp_buf->icmp_code;
99 
100  // analyse type of ICMP packet
101  if (_code == ICMP_ECHOREPLY && _subcode == ICMP_ECHOREPLY)
102  {
103  _scan_result = ICMP_ECHOREPLY;
104  //std::cout << "ICMP_ECHOREPLY" << std::endl;
105  }
106 
107  else if (_code == ICMP_DEST_UNREACH && _subcode == ICMP_PORT_UNREACH)
108  {
109  _scan_result = ICMP_PORT_UNREACH;
110  //std::cout << "ICMP_PORT_UNREACH" << std::endl;
111  }
112 
113  else if (_code == ICMP_TIME_EXCEEDED)
114  {
115  _scan_result = ICMP_TIME_EXCEEDED;
116  //std::cout << "ICMP_TIME_EXCEEDED" << std::endl;
117  }
118 
119  else if (_subcode == ICMP_UNREACH_HOST_PROHIB)
120  {
121  _scan_result = ICMP_UNREACH_HOST_PROHIB;
122  //std::cout << "ICMP_UNREACH_HOST_PROHIB" << std::endl;
123  }
124 
125  else if (_subcode == ICMP_PKT_FILTERED)
126  {
127  _scan_result = ICMP_PKT_FILTERED;
128  //std::cout << "ICMP_PKT_FILTERED" << std::endl;
129  }
130 
131  else if (_subcode == ICMP_PROT_UNREACH)
132  {
133  _scan_result = ICMP_PROT_UNREACH;
134  //std::cout << "ICMP_PROT_UNREACH" << std::endl;
135  }
136 
137  else
138  {
139  _scan_result = ICMP_DEST_UNREACH;
140  //std::cout << "ICMP_DEST_UNREACH" << std::endl;
141  }
142 }
143 
148 void ProbeReply::_dissect_iperror(int offset)
149 {
150  _iperror_buf = (struct iphdr *) &_probe[offset];
151  _dst_addr_raw = _iperror_buf->saddr;
152 }
153 
154 void ProbeReply::_dissect_tcp(int offset)
155 {
156  _tcp_buf = (struct tcphdr *) &_probe[offset];
157 
158  if (_tcp_buf->rst == 1)
159  {
160  _scan_result = TCP_RST_FLAG;
161  //std::cout << "TCP_RST_FLAG" << std::endl;
162  }
163  else if (_tcp_buf->ack == 1 && _tcp_buf->syn == 1)
164  {
165  _scan_result = TCP_SYN_ACK;
166  //std::cout << "TCP_SYN_ACK" << std::endl;
167  }
168  else
169  {
170  _scan_result = TCP_UNKNOWN;
171  //std::cout << "TCP_UNKNOWN" << std::endl;
172  }
173 
174 }
175 
176 /********************/
178 /********************/
179 
185 {
186  memcpy(_probe,probe,MAX_PACKET);
187  //_has_response = true;
188  _dissect();
189 }
190 
196 std::string ProbeReply::src_addr()
197 {
198  return Util::number2string(_src_addr_raw);
199 }
200 
207 {
208  return _src_addr_raw;
209 }
210 
216 std::string ProbeReply::dst_addr()
217 {
218  return Util::number2string(_dst_addr_raw);
219 }
220 
227 {
228  return _dst_addr_raw;
229 }
230 
237 {
238  return Util::number2string(_iperror_buf->daddr);
239 }
240 
247 {
248  return _iperror_buf->daddr;
249 }
250 
257 {
258  if (ip_protocol() == 6)
259  return _tcp_buf->dest;
260  else return -1;
261 }
262 
269 {
270  return _scan_result;
271 }
272 
277 void ProbeReply::set_scan_result(int result_scan)
278 {
279  _scan_result = result_scan;
280 }
281 
288 {
289  return (int)_ip_buf->protocol;
290 }
291 
298 {
299  return (int)_iperror_buf->protocol;
300 }
301 
308 {
309  return ((uint16_t)_ip_buf->ihl)*32/8;
310 }
311 
318 {
319  return _code;
320 }
321 
328 {
329  return _subcode;
330 }
331 
338 {
339  if (_scan_result < 0)
340  return false;
341  else
342  return true;
343 }
344 
351 {
352  return _options;
353 }
354 
361 {
362  return _probe;
363 }
364 
371 {
372  int offset = ihl();
373  return &_probe[offset];
374 }
375 
382 {
383  int offset = ihl() + ICMP_SIZE;
384  return &_probe[offset];
385 }
386 
393 {
394  if (ihl() > 36)
395  {
396  *opt = (TSOption*) &_probe[IP_SIZE];
397  return true;
398  }
399  else
400  return false;
401 }
402 
409 {
410  int offset;
411  if (ip_protocol() == 1 && _iperror_buf->ihl > 5)
412  {
413  offset = ihl() + ICMP_SIZE + IP_SIZE;
414  *opt = (TSOption*) &_probe[offset];
415  return true;
416  }
417  else
418  return false;
419 }
420 
426 {
427  if (has_response())
428  {
429  std::cout << "Printing details..." << std::endl;
430 
431  std::cout << "\t Source address " << src_addr() << std::endl;
432  std::cout << "\t Destination address " << dst_addr() << std::endl;
433  std::cout << "\t IP protocol " << ip_protocol() << std::endl;
434  if (ip_protocol() == 1)
435  {
436  std::cout << "\t IPError Destination address " << iperror_dst_addr() << std::endl;
437  std::cout << "\t ICMP type " << code() << std::endl;
438  std::cout << "\t ICMP code " << subcode() << std::endl;
439  }
440  else
441  std::cout << "\t Code " << code() << std::endl;
442 
443  TSOption* opt;
444  if (outer_options(&opt))
445  {
446  std::cout << "\t Outer Options:" << std::endl;
447  std::cout << "\t\t IP1 " << Util::number2string(opt->ip1) << " timestamp " << ntohl(opt->ts1) << std::endl;
448  std::cout << "\t\t IP2 " << Util::number2string(opt->ip2) << " timestamp " << ntohl(opt->ts2) << std::endl;
449  std::cout << "\t\t IP3 " << Util::number2string(opt->ip3) << " timestamp " << ntohl(opt->ts3) << std::endl;
450  std::cout << "\t\t IP4 " << Util::number2string(opt->ip4) << " timestamp " << ntohl(opt->ts4) << std::endl;
451  }
452  if (inner_options(&opt))
453  {
454  std::cout << "\t Inner Options:" << std::endl;
455  std::cout << "\t\t IP1 " << Util::number2string(opt->ip1) << " timestamp " << ntohl(opt->ts1) << std::endl;
456  std::cout << "\t\t IP2 " << Util::number2string(opt->ip2) << " timestamp " << ntohl(opt->ts2) << std::endl;
457  std::cout << "\t\t IP3 " << Util::number2string(opt->ip3) << " timestamp " << ntohl(opt->ts3) << std::endl;
458  std::cout << "\t\t IP4 " << Util::number2string(opt->ip4) << " timestamp " << ntohl(opt->ts4) << std::endl;
459  }
460  }
461  else
462  std::cout << "No response obtained" << std::endl;
463 }
464 
470 {
471  memset(_probe, 0, sizeof (_probe));
472  _scan_result = NO_RESPONSE;
473  _has_response = false;
474  _options = false;
475  _ihl = -1;
476  _code = -1;
477  _subcode = -1;
478 }