Blame testprogs/findalldevstest.c

Packit 209cc3
#ifdef HAVE_CONFIG_H
Packit 209cc3
#include <config.h>
Packit 209cc3
#endif
Packit 209cc3
Packit 209cc3
#include <stdlib.h>
Packit 209cc3
#include <string.h>
Packit 209cc3
#include <sys/types.h>
Packit 209cc3
#ifdef _WIN32
Packit 209cc3
  #include <winsock2.h>
Packit 209cc3
  #include <ws2tcpip.h>
Packit 209cc3
  #include <windows.h>
Packit 209cc3
#else
Packit 209cc3
  #include <sys/socket.h>
Packit 209cc3
  #include <netinet/in.h>
Packit 209cc3
  #include <arpa/inet.h>
Packit 209cc3
  #include <netdb.h>
Packit 209cc3
  #include <unistd.h>
Packit 209cc3
#endif
Packit 209cc3
Packit 209cc3
#include <pcap.h>
Packit 209cc3
Packit 209cc3
#include "pcap/funcattrs.h"
Packit 209cc3
Packit 209cc3
static int ifprint(pcap_if_t *d);
Packit 209cc3
static char *iptos(bpf_u_int32 in);
Packit 209cc3
Packit 209cc3
#ifdef _WIN32
Packit 209cc3
#include "portability.h"
Packit 209cc3
Packit 209cc3
/*
Packit 209cc3
 * Generate a string for a Win32-specific error (i.e. an error generated when
Packit 209cc3
 * calling a Win32 API).
Packit 209cc3
 * For errors occurred during standard C calls, we still use pcap_strerror()
Packit 209cc3
 */
Packit 209cc3
#define ERRBUF_SIZE	1024
Packit 209cc3
static const char *
Packit 209cc3
win32_strerror(DWORD error)
Packit 209cc3
{
Packit 209cc3
  static char errbuf[ERRBUF_SIZE+1];
Packit 209cc3
  size_t errlen;
Packit 209cc3
Packit 209cc3
  FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
Packit 209cc3
                ERRBUF_SIZE, NULL);
Packit 209cc3
Packit 209cc3
  /*
Packit 209cc3
   * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
Packit 209cc3
   * message.  Get rid of it.
Packit 209cc3
   */
Packit 209cc3
  errlen = strlen(errbuf);
Packit 209cc3
  if (errlen >= 2) {
Packit 209cc3
    errbuf[errlen - 1] = '\0';
Packit 209cc3
    errbuf[errlen - 2] = '\0';
Packit 209cc3
    errlen -= 2;
Packit 209cc3
  }
Packit 209cc3
  return errbuf;
Packit 209cc3
}
Packit 209cc3
Packit 209cc3
static char *
Packit 209cc3
getpass(const char *prompt)
Packit 209cc3
{
Packit 209cc3
  HANDLE console_handle = GetStdHandle(STD_INPUT_HANDLE);
Packit 209cc3
  DWORD console_mode, save_console_mode;
Packit 209cc3
  static char password[128+1];
Packit 209cc3
  char *p;
Packit 209cc3
Packit 209cc3
  fprintf(stderr, "%s", prompt);
Packit 209cc3
Packit 209cc3
  /*
Packit 209cc3
   * Turn off echoing.
Packit 209cc3
   */
Packit 209cc3
  if (!GetConsoleMode(console_handle, &console_mode)) {
Packit 209cc3
    fprintf(stderr, "Can't get console mode: %s\n",
Packit 209cc3
            win32_strerror(GetLastError()));
Packit 209cc3
    exit(1);
Packit 209cc3
  }
Packit 209cc3
  save_console_mode = console_mode;
Packit 209cc3
  console_mode &= ~ENABLE_ECHO_INPUT;
Packit 209cc3
  if (!SetConsoleMode(console_handle, console_mode)) {
Packit 209cc3
    fprintf(stderr, "Can't set console mode: %s\n",
Packit 209cc3
            win32_strerror(GetLastError()));
Packit 209cc3
    exit(1);
Packit 209cc3
  }
Packit 209cc3
  if (fgets(password, sizeof password, stdin) == NULL) {
Packit 209cc3
    fprintf(stderr, "\n");
Packit 209cc3
    SetConsoleMode(console_handle, save_console_mode);
Packit 209cc3
    exit(1);
Packit 209cc3
  }
Packit 209cc3
  fprintf(stderr, "\n");
Packit 209cc3
  SetConsoleMode(console_handle, save_console_mode);
Packit 209cc3
  p = strchr(password, '\n');
Packit 209cc3
  if (p != NULL)
Packit 209cc3
    *p = '\0';
Packit 209cc3
 return password;
Packit 209cc3
}
Packit 209cc3
#endif
Packit 209cc3
Packit 209cc3
int main(int argc, char **argv)
Packit 209cc3
{
Packit 209cc3
  pcap_if_t *alldevs;
Packit 209cc3
  pcap_if_t *d;
Packit 209cc3
  bpf_u_int32 net, mask;
Packit 209cc3
  int exit_status = 0;
Packit 209cc3
  char errbuf[PCAP_ERRBUF_SIZE+1];
Packit 209cc3
#ifdef ENABLE_REMOTE
Packit 209cc3
  struct pcap_rmtauth auth;
Packit 209cc3
  char username[128+1];
Packit 209cc3
  char *p;
Packit 209cc3
  char *password;
Packit 209cc3
#endif
Packit 209cc3
Packit 209cc3
#ifdef ENABLE_REMOTE
Packit 209cc3
  if (argc >= 2)
Packit 209cc3
  {
Packit 209cc3
    if (pcap_findalldevs_ex(argv[1], NULL, &alldevs, errbuf) == -1)
Packit 209cc3
    {
Packit 209cc3
      /*
Packit 209cc3
       * OK, try it with a user name and password.
Packit 209cc3
       */
Packit 209cc3
      fprintf(stderr, "User name: ");
Packit 209cc3
      if (fgets(username, sizeof username, stdin) == NULL)
Packit 209cc3
        exit(1);
Packit 209cc3
      p = strchr(username, '\n');
Packit 209cc3
      if (p != NULL)
Packit 209cc3
        *p = '\0';
Packit 209cc3
      password = getpass("Password: ");
Packit 209cc3
      auth.type = RPCAP_RMTAUTH_PWD;
Packit 209cc3
      auth.username = username;
Packit 209cc3
      auth.password = password;
Packit 209cc3
      if (pcap_findalldevs_ex(argv[1], &auth, &alldevs, errbuf) == -1)
Packit 209cc3
      {
Packit 209cc3
        fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
Packit 209cc3
        exit(1);
Packit 209cc3
      }
Packit 209cc3
    }
Packit 209cc3
  }
Packit 209cc3
  else
Packit 209cc3
#endif
Packit 209cc3
  {
Packit 209cc3
    if (pcap_findalldevs(&alldevs, errbuf) == -1)
Packit 209cc3
    {
Packit 209cc3
      fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
Packit 209cc3
      exit(1);
Packit 209cc3
    }
Packit 209cc3
  }
Packit 209cc3
  for(d=alldevs;d;d=d->next)
Packit 209cc3
  {
Packit 209cc3
    if (!ifprint(d))
Packit 209cc3
      exit_status = 2;
Packit 209cc3
  }
Packit 209cc3
Packit 209cc3
  if (alldevs != NULL)
Packit 209cc3
  {
Packit 209cc3
    if (pcap_lookupnet(alldevs->name, &net, &mask, errbuf) < 0)
Packit 209cc3
    {
Packit 209cc3
      fprintf(stderr,"Error in pcap_lookupnet: %s\n",errbuf);
Packit 209cc3
      exit_status = 2;
Packit 209cc3
    }
Packit 209cc3
    else
Packit 209cc3
    {
Packit 209cc3
      printf("Preferred device is on network: %s/%s\n",iptos(net), iptos(mask));
Packit 209cc3
    }
Packit 209cc3
  }
Packit 209cc3
Packit 209cc3
  pcap_freealldevs(alldevs);
Packit 209cc3
  exit(exit_status);
Packit 209cc3
}
Packit 209cc3
Packit 209cc3
static int ifprint(pcap_if_t *d)
Packit 209cc3
{
Packit 209cc3
  pcap_addr_t *a;
Packit 209cc3
  char ipv4_buf[INET_ADDRSTRLEN];
Packit 209cc3
  char ipv6_buf[INET6_ADDRSTRLEN];
Packit 209cc3
  const char *sep;
Packit 209cc3
  int status = 1; /* success */
Packit 209cc3
Packit 209cc3
  printf("%s\n",d->name);
Packit 209cc3
  if (d->description)
Packit 209cc3
    printf("\tDescription: %s\n",d->description);
Packit 209cc3
  printf("\tFlags: ");
Packit 209cc3
  sep = "";
Packit 209cc3
  if (d->flags & PCAP_IF_UP) {
Packit 209cc3
    printf("%sUP", sep);
Packit 209cc3
    sep = ", ";
Packit 209cc3
  }
Packit 209cc3
  if (d->flags & PCAP_IF_RUNNING) {
Packit 209cc3
    printf("%sRUNNING", sep);
Packit 209cc3
    sep = ", ";
Packit 209cc3
  }
Packit 209cc3
  if (d->flags & PCAP_IF_LOOPBACK) {
Packit 209cc3
    printf("%sLOOPBACK", sep);
Packit 209cc3
    sep = ", ";
Packit 209cc3
  }
Packit 209cc3
  if (d->flags & PCAP_IF_WIRELESS) {
Packit 209cc3
    printf("%sWIRELESS", sep);
Packit 209cc3
    switch (d->flags & PCAP_IF_CONNECTION_STATUS) {
Packit 209cc3
Packit 209cc3
    case PCAP_IF_CONNECTION_STATUS_UNKNOWN:
Packit 209cc3
      printf(" (association status unknown)");
Packit 209cc3
      break;
Packit 209cc3
Packit 209cc3
    case PCAP_IF_CONNECTION_STATUS_CONNECTED:
Packit 209cc3
      printf(" (associated)");
Packit 209cc3
      break;
Packit 209cc3
Packit 209cc3
    case PCAP_IF_CONNECTION_STATUS_DISCONNECTED:
Packit 209cc3
      printf(" (not associated)");
Packit 209cc3
      break;
Packit 209cc3
Packit 209cc3
    case PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE:
Packit 209cc3
      break;
Packit 209cc3
    }
Packit 209cc3
  } else {
Packit 209cc3
    switch (d->flags & PCAP_IF_CONNECTION_STATUS) {
Packit 209cc3
Packit 209cc3
    case PCAP_IF_CONNECTION_STATUS_UNKNOWN:
Packit 209cc3
      printf(" (connection status unknown)");
Packit 209cc3
      break;
Packit 209cc3
Packit 209cc3
    case PCAP_IF_CONNECTION_STATUS_CONNECTED:
Packit 209cc3
      printf(" (connected)");
Packit 209cc3
      break;
Packit 209cc3
Packit 209cc3
    case PCAP_IF_CONNECTION_STATUS_DISCONNECTED:
Packit 209cc3
      printf(" (disconnected)");
Packit 209cc3
      break;
Packit 209cc3
Packit 209cc3
    case PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE:
Packit 209cc3
      break;
Packit 209cc3
    }
Packit 209cc3
  }
Packit 209cc3
  sep = ", ";
Packit 209cc3
  printf("\n");
Packit 209cc3
Packit 209cc3
  for(a=d->addresses;a;a=a->next) {
Packit 209cc3
    if (a->addr != NULL)
Packit 209cc3
      switch(a->addr->sa_family) {
Packit 209cc3
      case AF_INET:
Packit 209cc3
        printf("\tAddress Family: AF_INET\n");
Packit 209cc3
        if (a->addr)
Packit 209cc3
          printf("\t\tAddress: %s\n",
Packit 209cc3
            inet_ntop(AF_INET,
Packit 209cc3
               &((struct sockaddr_in *)(a->addr))->sin_addr,
Packit 209cc3
               ipv4_buf, sizeof ipv4_buf));
Packit 209cc3
        if (a->netmask)
Packit 209cc3
          printf("\t\tNetmask: %s\n",
Packit 209cc3
            inet_ntop(AF_INET,
Packit 209cc3
               &((struct sockaddr_in *)(a->netmask))->sin_addr,
Packit 209cc3
               ipv4_buf, sizeof ipv4_buf));
Packit 209cc3
        if (a->broadaddr)
Packit 209cc3
          printf("\t\tBroadcast Address: %s\n",
Packit 209cc3
            inet_ntop(AF_INET,
Packit 209cc3
               &((struct sockaddr_in *)(a->broadaddr))->sin_addr,
Packit 209cc3
               ipv4_buf, sizeof ipv4_buf));
Packit 209cc3
        if (a->dstaddr)
Packit 209cc3
          printf("\t\tDestination Address: %s\n",
Packit 209cc3
            inet_ntop(AF_INET,
Packit 209cc3
               &((struct sockaddr_in *)(a->dstaddr))->sin_addr,
Packit 209cc3
               ipv4_buf, sizeof ipv4_buf));
Packit 209cc3
        break;
Packit 209cc3
#ifdef INET6
Packit 209cc3
      case AF_INET6:
Packit 209cc3
        printf("\tAddress Family: AF_INET6\n");
Packit 209cc3
        if (a->addr)
Packit 209cc3
          printf("\t\tAddress: %s\n",
Packit 209cc3
            inet_ntop(AF_INET6,
Packit 209cc3
               ((struct sockaddr_in6 *)(a->addr))->sin6_addr.s6_addr,
Packit 209cc3
               ipv6_buf, sizeof ipv6_buf));
Packit 209cc3
        if (a->netmask)
Packit 209cc3
          printf("\t\tNetmask: %s\n",
Packit 209cc3
            inet_ntop(AF_INET6,
Packit 209cc3
              ((struct sockaddr_in6 *)(a->netmask))->sin6_addr.s6_addr,
Packit 209cc3
               ipv6_buf, sizeof ipv6_buf));
Packit 209cc3
        if (a->broadaddr)
Packit 209cc3
          printf("\t\tBroadcast Address: %s\n",
Packit 209cc3
            inet_ntop(AF_INET6,
Packit 209cc3
              ((struct sockaddr_in6 *)(a->broadaddr))->sin6_addr.s6_addr,
Packit 209cc3
               ipv6_buf, sizeof ipv6_buf));
Packit 209cc3
        if (a->dstaddr)
Packit 209cc3
          printf("\t\tDestination Address: %s\n",
Packit 209cc3
            inet_ntop(AF_INET6,
Packit 209cc3
              ((struct sockaddr_in6 *)(a->dstaddr))->sin6_addr.s6_addr,
Packit 209cc3
               ipv6_buf, sizeof ipv6_buf));
Packit 209cc3
        break;
Packit 209cc3
#endif
Packit 209cc3
      default:
Packit 209cc3
        printf("\tAddress Family: Unknown (%d)\n", a->addr->sa_family);
Packit 209cc3
        break;
Packit 209cc3
      }
Packit 209cc3
    else
Packit 209cc3
    {
Packit 209cc3
      fprintf(stderr, "\tWarning: a->addr is NULL, skipping this address.\n");
Packit 209cc3
      status = 0;
Packit 209cc3
    }
Packit 209cc3
  }
Packit 209cc3
  printf("\n");
Packit 209cc3
  return status;
Packit 209cc3
}
Packit 209cc3
Packit 209cc3
/* From tcptraceroute */
Packit 209cc3
#define IPTOSBUFFERS	12
Packit 209cc3
static char *iptos(bpf_u_int32 in)
Packit 209cc3
{
Packit 209cc3
	static char output[IPTOSBUFFERS][3*4+3+1];
Packit 209cc3
	static short which;
Packit 209cc3
	u_char *p;
Packit 209cc3
Packit 209cc3
	p = (u_char *)∈
Packit 209cc3
	which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
Packit 209cc3
	sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
Packit 209cc3
	return output[which];
Packit 209cc3
}