
#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>

static int snoop = 1;

static SOCKET getsock (void *clientp,
                       curlsocktype purpose,
                       struct curl_sockaddr *ca)
{
  const struct sockaddr_in  *a4 = (const struct sockaddr_in*) &ca->addr;
  const struct sockaddr_in6 *a6 = (const struct sockaddr_in6*) &ca->addr;
  char  buf [200];

  switch (ca->family)
  {
   case AF_INET:
        printf ("AF_INET:  %s\n", inet_ntop(ca->family, &a4->sin_addr, buf, sizeof(buf)));
        break;
   case AF_INET6:
        printf ("AF_INET6: %s\n", inet_ntop(ca->family, &a6->sin6_addr, buf, sizeof(buf)));
        break;
  }
  if (snoop)
     return 0;
  return socket (ca->family, ca->protocol, 0);
}

int main (int argc, char **argv)
{
  CURL *curl = NULL;
  char  scheme [200+1];
  char  url [200+1];
  int   verbose = 0;

  if (argc > 1 && !strcmp(argv[1],"-v"))
  {
    verbose = 1;
    argc--;
    argv++;
  }

  if (argc < 2 || sscanf(argv[1],"%20[^/:]://%s",scheme,url) != 2)
  {
    printf ("Usage: sock_snoop [-v] <scheme://URL>\n");
    return (-1);
  }

  curl = curl_easy_init();

  curl_easy_setopt (curl, CURLOPT_CONNECT_ONLY, 1);
  curl_easy_setopt (curl, CURLOPT_URL, url);
  curl_easy_setopt (curl, CURLOPT_OPENSOCKETFUNCTION, getsock);
  curl_easy_setopt (curl, CURLOPT_VERBOSE, verbose);
  curl_easy_perform (curl);
  curl_easy_cleanup (curl);
  return (0);
}
