File: implementation6d.c

package info (click to toggle)
thc-ipv6 3.6-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 2,116 kB
  • sloc: ansic: 52,618; sh: 529; makefile: 77; perl: 34
file content (170 lines) | stat: -rw-r--r-- 5,123 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
 * Test:
 *       1. next header = hopbyhop, but no header
 *       2. next header = hopbyhop, but invalid length in hopbyhop header
 *       3. next header = hophyhop + no_next, but ip6 length longer than claimed
 *       4. next header = hophyhop + no_next, but ip6 length shorter than claimed
 *       5. 90 extension ignored headers
 *       6. 65535 byte packet (fragmented) with 3850 extension ignored headers
 *       7. jumbo packet (fragmented) with 7700 extension ignored headers
 *       8-10: same as 5-9 but final length larger than real packet
 *       11. 180 hop-by-bop headers
 *       12. forwarding header with 255 segements lefts (but only 1 defined)
 *
 *
 *       misc:
 *         - toobig6 with mtu = 600 on target
 *         - alive6 with target ff02::1 and router = target
 *         - alive6 with target = target and router = target (1shot frag + forward)
 *         - rsmurf on target
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <time.h>
#include <pcap.h>
#include "thc-ipv6.h"

int rawmode = 0;
int cont = 0;

void help(char *prg) {
  printf("%s %s (c) 2019 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE);
  printf("Syntax: %s interface\n\n", prg);
  printf("Identifies test packets by the implementation6 tool, useful to check what\n");
  printf("packets passed a firewall\n");
//  printf("Use -r to use raw mode.\n\n");
  exit(-1);
}

void check_packet(u_char *foo, const struct pcap_pkthdr *header, const unsigned char *data) {
  unsigned char *ipv6hdr;
  unsigned char buf[20];
  int add = 0, len = header->caplen;

  if (debug) {
    printf("DEBUG: packet received\n");
    thc_dump_data((unsigned char *) data, header->caplen, "Received Packet");
  }

  if (rawmode == 0) {
    if (do_hdr_size) {
      ipv6hdr = (unsigned char *) (data + do_hdr_size);
      len -= do_hdr_size;
      if ((ipv6hdr[0] & 240) != 0x60)
        return;
    } else {
      ipv6hdr = (unsigned char *) (data + 14);
      len -= 14;
    }
  } else
    ipv6hdr = (unsigned char *) data;

  if (ipv6hdr[0] >> 4 != 6)
    return;                     // not an ipv6 packet

  if (ipv6hdr[6] == NXT_ICMP6 && (ipv6hdr[40] == ICMP6_NEIGHBORSOL || ipv6hdr[40] == ICMP6_NEIGHBORADV || ipv6hdr[40] == ICMP6_PARAMPROB || ipv6hdr[40] == ICMP6_TTLEXEED))
    return;

  if (len >= 136) {
    if (ipv6hdr[6] == 0 && ipv6hdr[40] == 0 && ipv6hdr[48] == 0) {
      printf("   Detected (potential) implementation6 test case #%d %s\n", 3, cont == 3 ? "(cont'd)" : "");
      cont = 3;
      return;
    }
    buf[0] = ipv6hdr[124];
    memset(buf + 1, buf[0], sizeof(buf) - 1);
    if (memcmp(ipv6hdr + 128, buf, sizeof(buf)) == 0) {
      printf("   Detected (potential) implementation6 test case #%d %s\n", buf[0], cont == buf[0] ? "(cont'd)" : "");
      cont = buf[0];
      return;
    }
  }

  if (len >= 46) {
    switch (ipv6hdr[6]) {
    case NXT_ICMP6:
      if (1 == 1) {
        switch (ipv6hdr[40]) {
        case ICMP6_PINGREQUEST:
          if (ipv6hdr[44] == 0x34 && ipv6hdr[45] == 0x56 && ipv6hdr[46] == 0x78 && ipv6hdr[47] == 0x90 && ipv6hdr[52] == 'A') {
            printf("   Detected (potential) implementation6 standard thc-ipv6 ping request%s\n", cont == -1 ? " (cont'd)" : "");
            cont = -1;
          }
          return;
          break;
        case ICMP6_INFOREQUEST:
          if (ipv6hdr[48] == 20 + add) {
            printf("   Detected (potential) implementation6 test case #%d\n", 20 + add);
            cont = 0;
          }
          return;
          break;
        case ICMP6_INVNEIGHBORSOL:
          printf("   Detected (potential) implementation6 test case #%d\n", 21 + add);
          cont = 0;
          return;
          break;
        case ICMP6_CERTPATHSOL:
          if (ipv6hdr[45] == 23 + add) {
            printf("   Detected (potential) implementation6 test case #%d\n", 23 + add);
            cont = 0;
          }
          return;
          break;
        default:
          break;
        }
      }
      return;
      break;
    case NXT_OPTS:
      if (ipv6hdr[64] == ICMP6_MOBILE_PREFIXSOL) {
        if (ipv6hdr[69] == 22 + add) {
          printf("   Detected (potential) implementation6 test case #%d\n", 22 + add);
          cont = 0;
        }
        return;
      }
      break;
    default:
      break;
    }
  }

  return;
}


int main(int argc, char *argv[]) {
  unsigned char string[64] = "ip6";
  char *interface;

  if (argv[1] != NULL && strcmp(argv[1], "-r") == 0) {
    thc_ipv6_rawmode(1);
    rawmode = 1;
    argv++;
    argc--;
  }

  if (argc != 2 || strncmp(argv[1], "-h", 2) == 0)
    help(argv[0]);
  interface = argv[1];

  setvbuf(stdout, NULL, _IONBF, 0);

  printf("Waiting for implementation check packets on %s, press Control-C to end.\n", interface);
  if (thc_pcap_function(interface, string, (char *) check_packet, 0, NULL) < 0) {
    fprintf(stderr, "Error: could not capture on interface %s with string %s\n", interface, string);
    exit(-1);
  }
  // never returns

  return 0;
}