📄 ioctl.c
字号:
/* 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 + -