简体   繁体   中英

What is the Windows XP equivalent of inet_pton or InetPton?

I need to determine whether a particular string is a valid IPv4 or IPv6 address literal. If I understand correctly, the correct way to do this on POSIX systems is to use inet_pton to convert it into a network address structure and see if it succeeds. Windows Vista and later have InetPton which does essentially the same thing. But as far as I can tell, Windows XP doesn't declare either of those, and I need to be able to do this correctly on XP. So, the question is what system function to use to do this?

Worst case, I can write a function to parse it myself, but I'd prefer a standard, system function which has therefore been thoroughly tested and properly handles all corner cases and whatnot. It's already bad enough that Microsoft couldn't just declare inet_pton like everyone else and went with InetPton for their newer OSes.

In windows XP you can use these functions:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include <winsock2.h>
#include <ws2tcpip.h>


int inet_pton(int af, const char *src, void *dst)
{
  struct sockaddr_storage ss;
  int size = sizeof(ss);
  char src_copy[INET6_ADDRSTRLEN+1];

  ZeroMemory(&ss, sizeof(ss));
  /* stupid non-const API */
  strncpy (src_copy, src, INET6_ADDRSTRLEN+1);
  src_copy[INET6_ADDRSTRLEN] = 0;

  if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0) {
    switch(af) {
      case AF_INET:
    *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
    return 1;
      case AF_INET6:
    *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
    return 1;
    }
  }
  return 0;
}

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
{
  struct sockaddr_storage ss;
  unsigned long s = size;

  ZeroMemory(&ss, sizeof(ss));
  ss.ss_family = af;

  switch(af) {
    case AF_INET:
      ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src;
      break;
    case AF_INET6:
      ((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src;
      break;
    default:
      return NULL;
  }
  /* cannot direclty use &size because of strict aliasing rules */
  return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0)?
          dst : NULL;
}

That's it. Link with ws2_32 library.

But as far as I can tell, Windows XP doesn't declare either of those, and I need to be able to do this correctly on XP.

InetPton documentation states the following requirements:

  • Minimum supported client: Windows Vista [desktop apps only]
  • Minimum supported server: Windows Server 2008 [desktop apps only]

Worst case, I can write a function to parse it myself, but I'd prefer a standard, system function which has therefore been thoroughly tested and properly handles all corner cases and whatnot.

How about relying of a portion of code from the OSS network tool Wireshark ?

You can find their reimplementation of inet_pton in their source code repository .

The licence (see below) is very permissive, so that may be a good alternative.

Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

Looking through the SDK header files I find inet_pton() declared in "c:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Include\\WS2tcpip.h". InetPton is only a #define to that.

So, it seems MS is providing the proper interface after all, but only starting with Vista. But XP has no IPv6 support that is worth mentioning, if I recall correctly.

The other choice is to wrap it yourself with two calls to WSAAddressToString() , one with AF_INET , one with AF_INET6 . I'm guessing here from the docs, haven't tried it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM