Example #1
0
void
gaa_parser (int argc, char **argv)
{
  if (gaa (argc, argv, &info) != -1)
    {
      fprintf (stderr,
	       "Error in the arguments. Use the --help or -h parameters to get more information.\n");
      exit (1);
    }

  verbose = info.verbose;
  disable_extensions = info.disable_extensions;
  print_cert = info.print_cert;
  starttls = info.starttls;
  resume = info.resume;
  rehandshake = info.rehandshake;
  insecure = info.insecure;
  service = info.port;
  record_max_size = info.record_size;
  fingerprint = info.fingerprint;

  if (info.fmtder == 0)
    x509ctype = GNUTLS_X509_FMT_PEM;
  else
    x509ctype = GNUTLS_X509_FMT_DER;

  srp_username = info.srp_username;
  srp_passwd = info.srp_passwd;
  x509_cafile = info.x509_cafile;
  x509_crlfile = info.x509_crlfile;
  x509_keyfile = info.x509_keyfile;
  x509_certfile = info.x509_certfile;
  pgp_keyfile = info.pgp_keyfile;
  pgp_certfile = info.pgp_certfile;

  psk_username = info.psk_username;
  psk_key.data = (unsigned char *) info.psk_key;
  if (info.psk_key != NULL)
    psk_key.size = strlen (info.psk_key);
  else
    psk_key.size = 0;

  pgp_keyring = info.pgp_keyring;

  crlf = info.crlf;

  if (info.rest_args == NULL)
    hostname = "localhost";
  else
    hostname = info.rest_args;

  parse_protocols (info.proto, info.nproto, protocol_priority);
  parse_ciphers (info.ciphers, info.nciphers, cipher_priority);
  parse_macs (info.macs, info.nmacs, mac_priority);
  parse_ctypes (info.ctype, info.nctype, cert_type_priority);
  parse_kx (info.kx, info.nkx, kx_priority);
  parse_comp (info.comp, info.ncomp, comp_priority);
}
Example #2
0
int gaa_file(const char *name, gaainfo *gaaval)
{
    gaa_str_node *first_str, **tmp_str, *tmp_str2;
    int rval, i;
    char **argv;
    int argc = 0;
    FILE *file;

    gaa_processing_file = 1;
    
    if((file = fopen(name, "r")) == NULL)
    {
        printf("Couldn't open '%s' configuration file for reading\n", name);
        return 1;
    }
    
    tmp_str = &first_str;
    do
    {
        argc++;
        *tmp_str = gaa_malloc(sizeof(gaa_str_node));

        (*tmp_str)->str = NULL;
        (*tmp_str)->next = NULL;

        rval = gaa_internal_get_next_str(file, *tmp_str, argc);
        tmp_str = &((*tmp_str)->next);
    }
    while(rval == -1);
    
    if(rval == 1)
        return 0;
    
    argv = gaa_malloc((1 + argc) * sizeof(char*));

    tmp_str2 = first_str;
    argv[0] = "cfg";
    for(i = 1; i < argc; i++)
    {
        argv[i] = tmp_str2->str;
        tmp_str2 = tmp_str2->next;
    }

    rval = gaa(argc, argv, gaaval);
    gaa_processing_file = 0;
    return rval;
}
Example #3
0
int main(int argc, char **argv)
{
    gaainfo info;
    int i, v;
    if((v = gaa_file("config", &info)) != -1) 
		/* gets options from file 'config' */
    {
        return 0;
    }
    if((v = gaa(argc, argv, &info)) != -1)
    {
        return 0;
    } 
    printf("n : %d\nm : %d\nfile nf : %s %d\nverbose : %d\n",
           info.n, info.m, info.file,info.nf , info.verbose);
    if(info.size > 0)
        for(i = 0; i < info.size; i++)
            printf("%s\n", info.input[i]);
    return 0;
}
Example #4
0
File: psk.c Project: bf4/pidgin-mac
int
main (int argc, char **argv)
{
  gaainfo info;
  int ret;
  struct passwd *pwd;
  unsigned char key[MAX_KEY_SIZE];
  char hex_key[MAX_KEY_SIZE * 2 + 1];
  gnutls_datum_t dkey;
  size_t hex_key_size = sizeof (hex_key);

  if ((ret = gnutls_global_init ()) < 0)
    {
      fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
      exit (1);
    }

  umask (066);

  if (gaa (argc, argv, &info) != -1)
    {
      fprintf (stderr, "Error in the arguments.\n");
      return -1;
    }

  if (info.passwd == NULL)
    info.passwd = KPASSWD;

  if (info.username == NULL)
    {
#ifndef _WIN32
      pwd = getpwuid (getuid ());

      if (pwd == NULL)
	{
	  fprintf (stderr, "No such user\n");
	  return -1;
	}

      info.username = pwd->pw_name;
#else
      fprintf (stderr, "Please specify a user\n");
      return -1;
#endif
    }

  if (info.key_size > MAX_KEY_SIZE)
    {
      fprintf (stderr, "Key size is too long\n");
      exit (1);
    }

  if (info.netconf_hint)
    {
      char *passwd;

      if (info.key_size != 0 && info.key_size != 20)
	{
	  fprintf (stderr, "For netconf, key size must always be 20.\n");
	  exit (1);
	}

      passwd = getpass ("Enter password: "******"Please specify a password\n");
	  exit (1);
	}

      ret = gnutls_psk_netconf_derive_key (passwd,
					   info.username,
					   info.netconf_hint, &dkey);
    }
  else
    {
      if (info.key_size < 1)
	info.key_size = 16;

      printf ("Generating a random key for user '%s'\n", info.username);

      ret = _gnutls_rnd (GNUTLS_RND_RANDOM, (char *) key, info.key_size);
      if (ret < 0)
	{
	  fprintf (stderr, "Not enough randomness\n");
	  exit (1);
	}

      dkey.data = key;
      dkey.size = info.key_size;
    }

  ret = gnutls_hex_encode (&dkey, hex_key, &hex_key_size);
  if (info.netconf_hint)
    gnutls_free (dkey.data);
  if (ret < 0)
    {
      fprintf (stderr, "HEX encoding error\n");
      exit (1);
    }

  ret = write_key (info.username, hex_key, hex_key_size, info.passwd);
  if (ret == 0)
    printf ("Key stored to %s\n", info.passwd);

  return ret;
}
Example #5
0
File: psk.c Project: ares89/vlc
int
main (int argc, char **argv)
{
  gaainfo info;
  int ret;
#ifndef _WIN32
  struct passwd *pwd;
#endif
  unsigned char key[MAX_KEY_SIZE];
  char hex_key[MAX_KEY_SIZE * 2 + 1];
  gnutls_datum_t dkey;
  size_t hex_key_size = sizeof (hex_key);

  set_program_name (argv[0]);

  if ((ret = gnutls_global_init ()) < 0)
    {
      fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
      exit (1);
    }

  umask (066);

  if (gaa (argc, argv, &info) != -1)
    {
      fprintf (stderr, "Error in the arguments.\n");
      return -1;
    }

  if (info.passwd == NULL)
    info.passwd = (char *) KPASSWD;

  if (info.username == NULL)
    {
#ifndef _WIN32
      pwd = getpwuid (getuid ());

      if (pwd == NULL)
        {
          fprintf (stderr, "No such user\n");
          return -1;
        }

      info.username = pwd->pw_name;
#else
      fprintf (stderr, "Please specify a user\n");
      return -1;
#endif
    }

  if (info.key_size > MAX_KEY_SIZE)
    {
      fprintf (stderr, "Key size is too long\n");
      exit (1);
    }

  if (info.key_size < 1)
    info.key_size = 16;

  printf ("Generating a random key for user '%s'\n", info.username);

  ret = gnutls_rnd (GNUTLS_RND_RANDOM, (char *) key, info.key_size);
  if (ret < 0)
    {
      fprintf (stderr, "Not enough randomness\n");
      exit (1);
    }

  dkey.data = key;
  dkey.size = info.key_size;

  ret = gnutls_hex_encode (&dkey, hex_key, &hex_key_size);
  if (ret < 0)
    {
      fprintf (stderr, "HEX encoding error\n");
      exit (1);
    }

  ret = write_key (info.username, hex_key, hex_key_size, info.passwd);
  if (ret == 0)
    printf ("Key stored to %s\n", info.passwd);

  return ret;
}
Example #6
0
DWORD get_interfaces_windows(Remote *remote, Packet *response) {
	DWORD result = ERROR_SUCCESS;
	DWORD tlv_cnt;
	// Most of the time we'll need:
	//   index, name (description), MAC addr, mtu, flags, IP addr, netmask, maybe scope id
	// In some cases, the interface will have multiple addresses, so we'll realloc
	// this when necessary, but this will cover the common case.
	DWORD allocd_entries = 20;
	Tlv *entries = (Tlv *)malloc(sizeof(Tlv) * 20);
	int prefixes[30];
	int prefixes_cnt = 0;

	DWORD mtu_bigendian;
	DWORD interface_index_bigendian;

	ULONG flags = GAA_FLAG_INCLUDE_PREFIX
		| GAA_FLAG_SKIP_DNS_SERVER
		| GAA_FLAG_SKIP_MULTICAST
		| GAA_FLAG_SKIP_ANYCAST;

	LPSOCKADDR sockaddr;

	ULONG family = AF_UNSPEC;
	IP_ADAPTER_ADDRESSES *pAdapters = NULL;
	IP_ADAPTER_ADDRESSES *pCurr = NULL;
	ULONG outBufLen = 0;
	DWORD (WINAPI *gaa)(DWORD, DWORD, void *, void *, void *);

	// Use the newer version so we're guaranteed to have a large enough struct.
	// Unfortunately, using these probably means it won't compile on older
	// versions of Visual Studio.  =(
	IP_ADAPTER_UNICAST_ADDRESS_LH *pAddr = NULL;
	IP_ADAPTER_UNICAST_ADDRESS_LH *pPref = NULL;
	// IP_ADAPTER_PREFIX is only defined if NTDDI_VERSION > NTDDI_WINXP
	// Since we request older versions of things, we have to be explicit
	// when using newer structs.
	IP_ADAPTER_PREFIX_XP *pPrefix = NULL;

	do
	{
		gaa = (DWORD (WINAPI *)(DWORD,DWORD,void*,void*,void*))GetProcAddress(
				GetModuleHandle("iphlpapi"), "GetAdaptersAddresses"
			);
		if (!gaa) {
			result = get_interfaces_windows_mib(remote, response);
			break;
		}

		gaa(family, flags, NULL, pAdapters, &outBufLen);
		if (!(pAdapters = (IP_ADAPTER_ADDRESSES *)malloc(outBufLen)))
		{
			result = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}
		if (gaa(family, flags, NULL, pAdapters, &outBufLen))
		{
			result = GetLastError();
			break;
		}

		// Enumerate the entries
		for (pCurr = pAdapters; pCurr; pCurr = pCurr->Next)
		{
			tlv_cnt = 0;

			interface_index_bigendian = htonl(pCurr->IfIndex);
			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type   = TLV_TYPE_INTERFACE_INDEX;
			entries[tlv_cnt].buffer        = (PUCHAR)&interface_index_bigendian;
			tlv_cnt++;

			entries[tlv_cnt].header.length = pCurr->PhysicalAddressLength;
			entries[tlv_cnt].header.type   = TLV_TYPE_MAC_ADDR;
			entries[tlv_cnt].buffer        = (PUCHAR)pCurr->PhysicalAddress;
			tlv_cnt++;

			entries[tlv_cnt].header.length = wcslen(pCurr->Description)*2 + 1;
			entries[tlv_cnt].header.type   = TLV_TYPE_MAC_NAME;
			entries[tlv_cnt].buffer        = (PUCHAR)pCurr->Description;
			tlv_cnt++;

			mtu_bigendian            = htonl(pCurr->Mtu);
			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type   = TLV_TYPE_INTERFACE_MTU;
			entries[tlv_cnt].buffer        = (PUCHAR)&mtu_bigendian;
			tlv_cnt++;

			if (pCurr->Length > 68) {
				// Then this is a Longhorn struct version and it contains the
				// FirstPrefix member, save it for later in case we don't have
				// an OnLinkPrefixLength
				pPrefix = pCurr->FirstPrefix;
			}

			for (pAddr = (void*)pCurr->FirstUnicastAddress; pAddr; pAddr = (void*)pAddr->Next)
			{
				sockaddr = pAddr->Address.lpSockaddr;
				if (AF_INET != sockaddr->sa_family && AF_INET6 != sockaddr->sa_family) {
					// Skip interfaces that aren't IP
					continue;
				}

				// This loop can add up to three Tlv's - one for address, one
				// for scope_id, one for netmask.  Go ahead and allocate enough
				// room for all of them.
				if (allocd_entries < tlv_cnt+3) {
					entries = realloc(entries, sizeof(Tlv) * (tlv_cnt+3));
					allocd_entries += 3;
				}

				if (pAddr->Length > 44) {
					// Then this is Vista+ and the OnLinkPrefixLength member
					// will be populated
					prefixes[prefixes_cnt] = htonl(pAddr->OnLinkPrefixLength);
				}
				if (pPrefix && 0 == prefixes[prefixes_cnt]) {
					// Otherwise, we have to walk the FirstPrefix linked list
					prefixes[prefixes_cnt] = htonl(pPrefix->PrefixLength);
					pPrefix = pPrefix->Next;
				} else {
					// This is XP SP0 and as far as I can tell, we have no way
					// of determining the netmask short of bailing on
					// this method and falling back to MIB, which doesn't
					// return IPv6 addresses. Older versions (e.g. NT4, 2k)
					// don't have GetAdapterAddresses, so they will have fallen
					// through earlier to the MIB implementation.
					free(entries);
					free(pAdapters);
					return get_interfaces_windows_mib(remote, response);
				}

				if (prefixes[prefixes_cnt]) {
					entries[tlv_cnt].header.length = 4;
					entries[tlv_cnt].header.type = TLV_TYPE_IP_PREFIX;
					entries[tlv_cnt].buffer = (PUCHAR)&prefixes[prefixes_cnt];
					tlv_cnt++;
					prefixes_cnt++;
				}

				if (sockaddr->sa_family == AF_INET) {
					entries[tlv_cnt].header.length = 4;
					entries[tlv_cnt].header.type = TLV_TYPE_IP;
					entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in *)sockaddr)->sin_addr);
					tlv_cnt++;

				} else {
					entries[tlv_cnt].header.length = 16;
					entries[tlv_cnt].header.type = TLV_TYPE_IP;
					entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_addr);
					tlv_cnt++;

					entries[tlv_cnt].header.length = sizeof(DWORD);
					entries[tlv_cnt].header.type = TLV_TYPE_IP6_SCOPE;
					entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_scope_id);
					tlv_cnt++;
				}

			}
			// Add the interface group
			packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE,
					entries, tlv_cnt);
		}
	} while (0);

	if (entries)
		free(entries);
	if (pAdapters)
		free(pAdapters);

	return result;
}
Example #7
0
File: crypt.c Project: ares89/vlc
int main (int argc, char **argv)
{
  gaainfo info;
  const char *passwd;
  int salt_size, ret;
#ifndef _WIN32
   struct passwd *pwd;
#endif

  set_program_name (argv[0]);

  if ((ret = gnutls_global_init ()) < 0)
    {
      fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
      exit (1);
    }

  umask (066);

  if (gaa (argc, argv, &info) != -1)
    {
      fprintf (stderr, "Error in the arguments.\n");
      return -1;
    }

  gnutls_global_set_log_function (tls_log_func);
  gnutls_global_set_log_level (info.debug);

  if (info.create_conf != NULL)
    {
      return generate_create_conf (info.create_conf);
    }

  if (info.passwd == NULL)
    info.passwd = (char *) KPASSWD;
  if (info.passwd_conf == NULL)
    info.passwd_conf = (char *) KPASSWD_CONF;

  if (info.username == NULL)
    {
#ifndef _WIN32
      pwd = getpwuid (getuid ());

      if (pwd == NULL)
        {
          fprintf (stderr, "No such user\n");
          return -1;
        }

      info.username = pwd->pw_name;
#else
      fprintf (stderr, "Please specify a user\n");
      return -1;
#endif
    }

  salt_size = 16;

  passwd = getpass ("Enter password: "******"Please specify a password\n");
      return -1;
    }

/* not ready yet */
  if (info.verify != 0)
    {
      return verify_passwd (info.passwd_conf, info.passwd,
                            info.username, passwd);
    }


  return crypt_int (info.username, passwd, salt_size,
                    info.passwd_conf, info.passwd, info.index);

}
Example #8
0
File: p11tool.c Project: sqs/gnutls
static void
gaa_parser (int argc, char **argv)
{
  int ret;
  common_info_st cinfo;

  if (gaa (argc, argv, &info) != -1)
    {
      fprintf (stderr, "Try `%s --help' for more information.\n",
               program_name);
      exit (1);
    }

  gnutls_global_set_log_function (tls_log_func);
  gnutls_global_set_log_level (info.debug);
  if (info.debug > 1)
    printf ("Setting log level to %d\n", info.debug);

  if ((ret = gnutls_global_init ()) < 0)
    error (EXIT_FAILURE, 0, "global_init: %s", gnutls_strerror (ret));

  if (info.pkcs11_provider != NULL)
    {
      ret = gnutls_pkcs11_init (GNUTLS_PKCS11_FLAG_MANUAL, NULL);
      if (ret < 0)
        fprintf (stderr, "pkcs11_init: %s", gnutls_strerror (ret));
      else
        {
          ret = gnutls_pkcs11_add_provider (info.pkcs11_provider, NULL);
          if (ret < 0)
            error (EXIT_FAILURE, 0, "pkcs11_add_provider: %s",
                   gnutls_strerror (ret));
        }
    }
  else
    {
      ret = gnutls_pkcs11_init (GNUTLS_PKCS11_FLAG_AUTO, NULL);
      if (ret < 0)
        fprintf (stderr, "pkcs11_init: %s", gnutls_strerror (ret));
    }

  if (info.outfile)
    {
      outfile = safe_open_rw (info.outfile, 0);
      if (outfile == NULL)
        error (EXIT_FAILURE, errno, "%s", info.outfile);
    }
  else
    outfile = stdout;

  memset (&cinfo, 0, sizeof (cinfo));
  cinfo.secret_key = info.secret_key;
  cinfo.privkey = info.privkey;
  cinfo.pkcs8 = info.pkcs8;
  cinfo.incert_format = info.incert_format;
  cinfo.cert = info.cert;

  switch (info.action)
    {
    case ACTION_PKCS11_LIST:
      pkcs11_list (outfile, info.pkcs11_url, info.pkcs11_type,
                   info.pkcs11_login, info.pkcs11_detailed_url, &cinfo);
      break;
    case ACTION_PKCS11_TOKENS:
      pkcs11_token_list (outfile, info.pkcs11_detailed_url, &cinfo);
      break;
    case ACTION_PKCS11_MECHANISMS:
      pkcs11_mechanism_list (outfile, info.pkcs11_url, info.pkcs11_login,
                             &cinfo);
      break;
    case ACTION_PKCS11_EXPORT_URL:
      pkcs11_export (outfile, info.pkcs11_url, info.pkcs11_login, &cinfo);
      break;
    case ACTION_PKCS11_WRITE_URL:
      pkcs11_write (outfile, info.pkcs11_url, info.pkcs11_label,
                    info.pkcs11_trusted, info.pkcs11_login, &cinfo);
      break;
    case ACTION_PKCS11_TOKEN_INIT:
      pkcs11_init (outfile, info.pkcs11_url, info.pkcs11_label, &cinfo);
      break;
    case ACTION_PKCS11_DELETE_URL:
      pkcs11_delete (outfile, info.pkcs11_url, 0, info.pkcs11_login, &cinfo);
      break;
    default:
      gaa_help ();
      exit (0);
    }
  fclose (outfile);

  gnutls_pkcs11_deinit ();
  gnutls_global_deinit ();
}
Example #9
0
int
main (int argc, char **argv)
{
  gaainfo info;
  const char *passwd;
  int salt, ret;
  struct passwd *pwd;

  if ((ret = gnutls_global_init ()) < 0)
    {
      fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
      exit (1);
    }

#ifdef HAVE_UMASK
  umask (066);
#endif

  if (gaa (argc, argv, &info) != -1)
    {
      fprintf (stderr, "Error in the arguments.\n");
      return -1;
    }

  salt = info.salt;

  if (info.create_conf != NULL)
    {
      return generate_create_conf (info.create_conf);
    }

  if (info.passwd == NULL)
    info.passwd = KPASSWD;
  if (info.passwd_conf == NULL)
    info.passwd_conf = KPASSWD_CONF;

  if (info.username == NULL)
    {
#ifndef _WIN32
      pwd = getpwuid (getuid ());

      if (pwd == NULL)
	{
	  fprintf (stderr, "No such user\n");
	  return -1;
	}

      info.username = pwd->pw_name;
#else
      fprintf (stderr, "Please specify a user\n");
      return -1;
#endif
    }

  salt = 16;

  passwd = getpass ("Enter password: "******"Please specify a password\n");
      return -1;
    }

/* not ready yet */
  if (info.verify != 0)
    {
      return verify_passwd (info.passwd_conf, info.passwd,
			    info.username, passwd);
    }


  return crypt_int (info.username, passwd, salt,
		    info.passwd_conf, info.passwd, info.index);

}
DWORD get_interfaces(Remote *remote, Packet *response)
{
	DWORD result = ERROR_SUCCESS;

	ULONG flags = GAA_FLAG_INCLUDE_PREFIX
		| GAA_FLAG_SKIP_DNS_SERVER
		| GAA_FLAG_SKIP_MULTICAST
		| GAA_FLAG_SKIP_ANYCAST;

	LPSOCKADDR sockaddr;

	ULONG family = AF_UNSPEC;
	IP_ADAPTER_ADDRESSES *pAdapters = NULL;
	IP_ADAPTER_ADDRESSES *pCurr = NULL;
	ULONG outBufLen = 0;
	DWORD(WINAPI *gaa)(DWORD, DWORD, void *, void *, void *);

	// Use the newer version so we're guaranteed to have a large enough struct.
	// Unfortunately, using these probably means it won't compile on older
	// versions of Visual Studio.  =(
	IP_ADAPTER_UNICAST_ADDRESS_LH *pAddr = NULL;
	IP_ADAPTER_UNICAST_ADDRESS_LH *pPref = NULL;
	// IP_ADAPTER_PREFIX is only defined if NTDDI_VERSION > NTDDI_WINXP
	// Since we request older versions of things, we have to be explicit
	// when using newer structs.
	IP_ADAPTER_PREFIX_XP *pPrefix = NULL;

	// We can't rely on the `Length` parameter of the IP_ADAPTER_PREFIX_XP struct
	// to tell us if we're on Vista or not because it always comes out at 48 bytes
	// so we have to check the version manually.
	OSVERSIONINFOEX v;

	gaa = (DWORD(WINAPI *)(DWORD, DWORD, void*, void*, void*))GetProcAddress(
		GetModuleHandle("iphlpapi"), "GetAdaptersAddresses");
	if (!gaa)
	{
		dprintf("[INTERFACE] No 'GetAdaptersAddresses'. Falling back on get_interfaces_mib");
		return get_interfaces_mib(remote, response);
	}

	gaa(family, flags, NULL, pAdapters, &outBufLen);
	if (!(pAdapters = malloc(outBufLen)))
	{
		return ERROR_NOT_ENOUGH_MEMORY;
	}

	if (gaa(family, flags, NULL, pAdapters, &outBufLen))
	{
		result = GetLastError();
		goto out;
	}

	dprintf("[INTERFACE] pAdapters->Length = %d", pAdapters->Length);
	// According to http://msdn.microsoft.com/en-us/library/windows/desktop/aa366058(v=vs.85).aspx
	// the PIP_ADAPTER_PREFIX doesn't exist prior to XP SP1. We check for this via the `Length`
	// value, which is 72 in XP without an SP, but 144 in later versions.
	if (pAdapters->Length <= 72)
	{
		dprintf("[INTERFACE] PIP_ADAPTER_PREFIX is missing");
		result = get_interfaces_mib(remote, response);
		goto out;
	}

	// we'll need to know the version later on
	memset(&v, 0, sizeof(v));
	v.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
	GetVersionEx((LPOSVERSIONINFO)&v);

	// Enumerate the entries
	for (pCurr = pAdapters; pCurr; pCurr = pCurr->Next)
	{
		// Save the first prefix for later in case we don't have an OnLinkPrefixLength
		pPrefix = pCurr->FirstPrefix;

		Packet* group = packet_create_group();

		dprintf("[INTERFACE] Adding index: %u", pCurr->IfIndex);
		packet_add_tlv_uint(group, TLV_TYPE_INTERFACE_INDEX, pCurr->IfIndex);

		dprintf("[INTERFACE] Adding MAC");
		packet_add_tlv_raw(group, TLV_TYPE_MAC_ADDR, (PUCHAR)pCurr->PhysicalAddress, pCurr->PhysicalAddressLength);

		dprintf("[INTERFACE] Adding Description");
		packet_add_tlv_wstring(group, TLV_TYPE_MAC_NAME, pCurr->Description);

		dprintf("[INTERFACE] Adding MTU: %u", pCurr->Mtu);
		packet_add_tlv_uint(group, TLV_TYPE_INTERFACE_MTU, pCurr->Mtu);

		for (pAddr = (IP_ADAPTER_UNICAST_ADDRESS_LH*)pCurr->FirstUnicastAddress;
			pAddr; pAddr = pAddr->Next)
		{
			sockaddr = pAddr->Address.lpSockaddr;
			if (AF_INET != sockaddr->sa_family && AF_INET6 != sockaddr->sa_family)
			{
				// Skip interfaces that aren't IP
				continue;
			}

			DWORD prefix = 0;
			if (v.dwMajorVersion >= 6) {
				// Then this is Vista+ and the OnLinkPrefixLength member
				// will be populated
				dprintf("[INTERFACES] >= Vista, using prefix: %x", pAddr->OnLinkPrefixLength);
				prefix = htonl(pAddr->OnLinkPrefixLength);
			}
			else if (pPrefix)
			{
				dprintf("[INTERFACES] < Vista, using prefix: %x", pPrefix->PrefixLength);
				prefix = htonl(pPrefix->PrefixLength);
			}
			else
			{
				dprintf("[INTERFACES] < Vista, no prefix");
				prefix = 0;
			}

			if (prefix)
			{
				dprintf("[INTERFACE] Adding Prefix: %x", prefix);
				// the UINT value is already byte-swapped, so we add it as a raw instead of
				// swizzling the bytes twice.
				packet_add_tlv_raw(group, TLV_TYPE_IP_PREFIX, (PUCHAR)&prefix, sizeof(prefix));
			}

			if (sockaddr->sa_family == AF_INET)
			{
				dprintf("[INTERFACE] Adding IPv4 Address: %x", ((struct sockaddr_in *)sockaddr)->sin_addr);
				packet_add_tlv_raw(group, TLV_TYPE_IP, (PUCHAR)&(((struct sockaddr_in *)sockaddr)->sin_addr), 4);
			}
			else
			{
				dprintf("[INTERFACE] Adding IPv6 Address");
				packet_add_tlv_raw(group, TLV_TYPE_IP, (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_addr), 16);
				packet_add_tlv_raw(group, TLV_TYPE_IP6_SCOPE, (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_scope_id), sizeof(DWORD));
			}

		}
		// Add the interface group
		packet_add_group(response, TLV_TYPE_NETWORK_INTERFACE, group);
	}

out:
	free(pAdapters);

	return result;
}