⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioctl.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      /* ifr->ifr_addr.sa_family = ?? */
         memset (&ifr->ifr_addr.sa_data, 0, sizeof(ifr->ifr_addr.sa_data));
         *(DWORD*) &ifr->ifr_addr.sa_data = htonl (sin_mask);
         get_ifname (ifr->ifr_name);
         break;

    case SIOCSIFNETMASK:             /* set interface net-mask */
         sin_mask = ntohl (*(DWORD*)&ifr->ifr_addr.sa_data);
         break;

    case SIOCGIFCONF:                /* get interfaces config */
    case OSIOCGIFCONF:
         ifc->ifc_len = min (ifc->ifc_len, NUM_IFACES*sizeof(*ifc));
         ifc = (struct ifconf*) ifc->ifc_buf; /* user's buffer */
         ifr = (struct ifreq*) ifc;
         get_ifname (ifr->ifr_name);
         break;

    case SIOCGIFHWADDR:
         switch (_pktdevclass)
         {
           case PD_ETHER:
                ifr->ifr_hwaddr.sa_family = ARPHRD_ETHER;
                memcpy (&ifr->ifr_hwaddr.sa_data, &_eth_addr,
                        sizeof(ifr->ifr_hwaddr.sa_data));
                break;
           case PD_TOKEN:
                ifr->ifr_hwaddr.sa_family = ARPHRD_TOKEN;
                memcpy (&ifr->ifr_hwaddr.sa_data, &_eth_addr,
                        sizeof(ifr->ifr_hwaddr.sa_data));
                break;
           case PD_SLIP:
                ifr->ifr_hwaddr.sa_family = 0;
                memset (&ifr->ifr_hwaddr.sa_data, 0,
                        sizeof(ifr->ifr_hwaddr.sa_data));
                break;
           case PD_PPP:
                ifr->ifr_hwaddr.sa_family = 0;
                memset (&ifr->ifr_hwaddr.sa_data, 0,
                        sizeof(ifr->ifr_hwaddr.sa_data));
                break;
           default:
                return (-1);
         }
         break;

    default:
         NO_CMD (cmd);
         SOCK_ERR (ESOCKTNOSUPPORT);
         return (-1);
  }
  return (0);
}


/*
 * Handler for buffer hi/lo watermark and urgent data (OOB)
 */
static int waterm_ioctrl (Socket *socket, long cmd, char *argp)
{
  VERIFY_RW (argp, sizeof(*argp));

  switch ((DWORD)cmd)
  {
    case SIOCSHIWAT:      /* set high watermark */
         /* to-do !! */
         break;

    case SIOCGHIWAT:      /* get high watermark */
         /* to-do !! */
         break;

    case SIOCSLOWAT:      /* set low watermark */
         /* to-do !! */
         break;

    case SIOCGLOWAT:      /* get low watermark */
         /* to-do !! */
         break;

    case SIOCATMARK:      /* OOB data available? */
         /* to-do !! */
         break;

    default:
         NO_CMD (cmd);
         SOCK_ERR (ESOCKTNOSUPPORT);
         return (-1);
  }
  ARGSUSED (argp);
  return (0);
}


/*
 * Handler for ARP-cache interface commands
 */
static int arp_ioctrl (Socket *socket, long cmd, char *argp)
{
  struct arpreq    *arp = (struct arpreq*) argp;
  struct arp_table *tab;
  DWORD             ip;

  switch ((DWORD)cmd)
  {
    case SIOCSARP:      /* add given IP/MAC-addr pair to ARP cache */
         ip = intel (*(DWORD*) &arp->arp_pa.sa_data);
         _arp_add_cache (ip, (eth_address*)&arp->arp_ha.sa_data, TRUE);
         break;

    case SIOCGARP:      /* return ARP entry for given ip */
    case OSIOCGARP:
         tab = _arp_search (*(DWORD*)&arp->arp_pa.sa_data, FALSE);
         if (tab)
         {
           if (tab->flags >= ARP_FLAG_FOUND)
               arp->arp_flags |= (ATF_INUSE | ATF_COM);

           if (tab->flags == ARP_FLAG_FIXED)
               arp->arp_flags |= ATF_PERM;
           memcpy (&arp->arp_ha.sa_data, &tab->hardware, sizeof(eth_address));
         }
         else
         {
           arp->arp_flags = 0;
           memset (&arp->arp_ha.sa_data, 0, sizeof(arp->arp_ha.sa_data));
           SOCK_ERR (ENOENT);  /* correct errno? */
           return (-1);
         }
         break;

    case SIOCDARP:      /* delete ARP-entry for given ip */
         tab = _arp_search (*(DWORD*)&arp->arp_pa.sa_data, FALSE);
         if (tab)
         {
           tab->ip = tab->flags = 0;
           memset (&tab->hardware, 0, sizeof(tab->hardware));
         }
         else
         {
           SOCK_ERR (ENOENT);  /* correct errno? */
           return (-1);
         }
         break;

    default:
         NO_CMD (cmd);
         SOCK_ERR (ESOCKTNOSUPPORT);
         return (-1);
  }
  return (0);
}

/*
 * Return string for ioctlsocket() command
 */
#if defined (USE_DEBUG)
struct cmd_list {
       long        cmd_val;
       const char *cmd_name;
     };

struct cmd_list commands[] = {
                { FIOCLEX,         "FIOCLEX"         },
                { FIONCLEX,        "FIONCLEX"        },
                { FIONREAD,        "FIONREAD"        },
                { FIONBIO,         "FIONBIO"         },
                { FIOASYNC,        "FIOASYNC"        },
                { FIOSETOWN,       "FIOSETOWN"       },
                { FIOGETOWN,       "FIOGETOWN"       },
                { SIOCSPGRP,       "SIOCSPGRP"       },
                { SIOCGPGRP,       "SIOCGPGRP"       },
                { SIOCADDRT,       "SIOCADDRT"       },
                { SIOCDELRT,       "SIOCDELRT"       },
                { SIOCSIFADDR,     "SIOCSIFADDR"     },
                { OSIOCGIFADDR,    "OSIOCGIFADDR"    },
                { SIOCGIFADDR,     "SIOCGIFADDR"     },
                { SIOCSIFDSTADDR,  "SIOCSIFDSTADDR"  },
                { OSIOCGIFDSTADDR, "OSIOCGIFDSTADDR" },
                { SIOCGIFDSTADDR,  "SIOCGIFDSTADDR"  },
                { SIOCSIFFLAGS,    "SIOCSIFFLAGS"    },
                { SIOCGIFFLAGS,    "SIOCGIFFLAGS"    },
                { OSIOCGIFBRDADDR, "OSIOCGIFBRDADDR" },
                { SIOCGIFBRDADDR,  "SIOCGIFBRDADDR"  },
                { SIOCSIFBRDADDR,  "SIOCSIFBRDADDR"  },
                { OSIOCGIFCONF,    "OSIOCGIFCONF"    },
                { SIOCGIFCONF,     "SIOCGIFCONF"     },
                { OSIOCGIFNETMASK, "OSIOCGIFNETMASK" },
                { SIOCGIFNETMASK,  "SIOCGIFNETMASK"  },
                { SIOCSIFNETMASK,  "SIOCSIFNETMASK"  },
                { SIOCGIFMETRIC,   "SIOCGIFMETRIC"   },
                { SIOCSIFMETRIC,   "SIOCSIFMETRIC"   },
                { SIOCDIFADDR,     "SIOCDIFADDR"     },
                { SIOCAIFADDR,     "SIOCAIFADDR"     },
                { SIOCGIFMTU,      "SIOCGIFMTU"      },
                { SIOCSARP,        "SIOCSARP"        },
                { OSIOCGARP,       "OSIOCGARP"       },
                { SIOCGARP,        "SIOCGARP"        },
                { SIOCDARP,        "SIOCDARP"        },
                { SIOCSHIWAT,      "SIOCSHIWAT"      },
                { SIOCGHIWAT,      "SIOCGHIWAT"      },
                { SIOCSLOWAT,      "SIOCSLOWAT"      },
                { SIOCGLOWAT,      "SIOCGLOWAT"      },
                { SIOCATMARK,      "SIOCATMARK"      },
                { SIOCGIFHWADDR,   "SIOCGIFHWADDR"   }
              };

static __inline const char *lookup (long cmd, const struct cmd_list *list,
                                    int num)
{
  while (num)
  {
    if (list->cmd_val == cmd)
       return (list->cmd_name);
    num--;
    list++;
  }
  return (NULL);
}

static const char *get_ioctl_cmd (long cmd)
{
  static char buf[50];
  const  char *str;

  switch (IOCGROUP(cmd))
  {
    case 'f':
         strcpy (buf, "file: ");
         break;
    case 'I':
         strcpy (buf, "iface: ");
         break;

    case 's':
         strcpy (buf, "waterm: ");
         break;

    default:
         return ("??unknown");
  }
  str = lookup (cmd, commands, DIM(commands));
  if (str)
     strcat (buf, str);
  return (buf);
}
#endif


/*
 * A small test program for above functions.
 */
#if defined(TEST_PROG)

#undef  assert
#define assert(x) ((x) ? (void)0 : assert_fail(__LINE__))

void assert_fail (unsigned line)
{
  fprintf (stderr, "\nAssert failed at line %d, errno = %d (%s)\n",
           line, errno, strerror (errno));
  exit (-1);
}

char *eth_addr_string (struct ether_addr *eth)
{
  static char buf[20];

  sprintf (buf, "%02X:%02X:%02X:%02X:%02X:%02X",
           eth->ether_addr_octet[0],
           eth->ether_addr_octet[1],
           eth->ether_addr_octet[2],
           eth->ether_addr_octet[3],
           eth->ether_addr_octet[4],
           eth->ether_addr_octet[5]);
  return (buf);
}

int main (void)
{
  struct ifreq ifr;
  struct sockaddr_in *sin;
  int    sock, on = 1;

  dbug_init();

  sock = socket (AF_INET, SOCK_DGRAM, 0);
  assert (sock);
  assert (setsockopt(sock, SOL_SOCKET, SO_DEBUG, &on,sizeof(on)) == 0);

  ifr.ifr_addr.sa_family = AF_UNSPEC;  /* get MAC-address */

  assert (ioctlsocket (sock, SIOCGIFADDR, (char*)&ifr) == 0);
  printf ("Interface `%s':\n\t ether-addr: %s\n",
          ifr.ifr_name,
          eth_addr_string ((struct ether_addr*)&ifr.ifr_addr.sa_data));

  assert (ioctlsocket (sock, SIOCGIFBRDADDR, (char*)&ifr) == 0);
  printf ("\t bcast-addr: %s\n",
          eth_addr_string ((struct ether_addr*)&ifr.ifr_addr.sa_data));

  ifr.ifr_addr.sa_family = AF_INET;

  assert (ioctlsocket (sock, SIOCGIFADDR, (char*)&ifr) == 0);
  sin = (struct sockaddr_in*) &ifr.ifr_addr;
  printf ("\t inet-addr:  %s\n", inet_ntoa (sin->sin_addr));

  assert (close_s(sock) >= 0);
  return (0);
}

#endif  /* TEST_PROG */
#endif  /* USE_BSD_FUNC */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -