diff options
author | msmith <msmith@FreeBSD.org> | 1997-06-02 06:31:49 +0000 |
---|---|---|
committer | msmith <msmith@FreeBSD.org> | 1997-06-02 06:31:49 +0000 |
commit | 2daa25f3facca5df62b6c9926fa9d9ef46ffdb89 (patch) | |
tree | 52a0df961d1dd5b5986e2280fd3104de70be6649 | |
parent | 961f5b3e1abdffe530b197a07b82f42848ee24fe (diff) | |
download | FreeBSD-src-2daa25f3facca5df62b6c9926fa9d9ef46ffdb89.zip FreeBSD-src-2daa25f3facca5df62b6c9926fa9d9ef46ffdb89.tar.gz |
Add support for the SIOCGIFHWADDR ioctl, commonly used by
license managers to obtain the host's ethernet address as
a key.
Note that this implementation takes the first hardware address for
the first ethernet interface found, and disregards the interface name
that may be passed in, as linux ethernet devices are all "ethX".
-rw-r--r-- | sys/alpha/linux/linux.h | 72 | ||||
-rw-r--r-- | sys/compat/linux/linux_ioctl.c | 45 | ||||
-rw-r--r-- | sys/i386/linux/linux.h | 72 | ||||
-rw-r--r-- | sys/i386/linux/linux_ioctl.c | 45 |
4 files changed, 230 insertions, 4 deletions
diff --git a/sys/alpha/linux/linux.h b/sys/alpha/linux/linux.h index ca72447..11ca2ad 100644 --- a/sys/alpha/linux/linux.h +++ b/sys/alpha/linux/linux.h @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id$ + * $Id: linux.h,v 1.14 1997/02/22 09:38:19 peter Exp $ */ #ifndef _I386_LINUX_LINUX_H_ @@ -517,9 +517,54 @@ struct trapframe; #define LINUX_SIOCGIFDSTADDR 0x8917 #define LINUX_SIOCGIFBRDADDR 0x8919 #define LINUX_SIOCGIFNETMASK 0x891b +#define LINUX_SIOCGIFHWADDR 0x8927 #define LINUX_SIOCADDMULTI 0x8931 #define LINUX_SIOCDELMULTI 0x8932 +struct linux_sockaddr +{ + unsigned short sa_family; + char sa_data[14]; +}; + +struct linux_ifmap +{ + unsigned long mem_start; + unsigned long mem_end; + unsigned short base_addr; + unsigned char irq; + unsigned char dma; + unsigned char port; +}; + +struct linux_ifreq +{ +#define LINUX_IFHWADDRLEN 6 +#define LINUX_IFNAMSIZ 16 + union + { + char ifrn_name[LINUX_IFNAMSIZ]; /* if name, e.g. "en0" */ + } ifr_ifrn; + + union { + struct linux_sockaddr ifru_addr; + struct linux_sockaddr ifru_dstaddr; + struct linux_sockaddr ifru_broadaddr; + struct linux_sockaddr ifru_netmask; + struct linux_sockaddr ifru_hwaddr; + short ifru_flags; + int ifru_metric; + int ifru_mtu; + struct linux_ifmap ifru_map; + char ifru_slave[LINUX_IFNAMSIZ]; /* Just fits the size */ + caddr_t ifru_data; + } ifr_ifru; +}; + +#define ifr_name ifr_ifrn.ifrn_name /* interface name */ +#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ + + /* serial_struct values for TIOC[GS]SERIAL ioctls */ #define LINUX_ASYNC_CLOSING_WAIT_INF 0 #define LINUX_ASYNC_CLOSING_WAIT_NONE 65535 @@ -548,4 +593,29 @@ struct trapframe; #define LINUX_ASYNC_CALLOUT_NOHUP 0x0400 #define LINUX_ASYNC_FLAGS 0x0FFF +/* structure and defines for i386_modify_ldt */ + +/* Maximum number of LDT entries supported. */ +#define LDT_ENTRIES 8192 +/* The size of each LDT entry. */ +#define LDT_ENTRY_SIZE 8 + +struct modify_ldt_ldt_s { + unsigned int entry_number; + unsigned long base_addr; + unsigned int limit; + unsigned int seg_32bit:1; + unsigned int contents:2; + unsigned int read_exec_only:1; + unsigned int limit_in_pages:1; + unsigned int seg_not_present:1; +}; + +#define MODIFY_LDT_CONTENTS_DATA 0 +#define MODIFY_LDT_CONTENTS_STACK 1 +#define MODIFY_LDT_CONTENTS_CODE 2 + +#define LINUX_MODIFY_LDT_GET 0 +#define LINUX_MODIFY_LDT_SET 1 + #endif /* !_I386_LINUX_LINUX_H_ */ diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index e748a88..c138945 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_ioctl.c,v 1.15 1997/03/23 03:36:01 bde Exp $ + * $Id: linux_ioctl.c,v 1.16 1997/03/24 11:37:50 bde Exp $ */ #include <sys/param.h> @@ -41,6 +41,8 @@ #include <sys/termios.h> #include <sys/socket.h> #include <net/if.h> +#include <net/if_dl.h> +#include <net/if_types.h> #include <sys/sockio.h> #include <machine/soundcard.h> @@ -587,6 +589,47 @@ linux_ioctl(struct proc *p, struct linux_ioctl_args *args, int *retval) args->cmd = OSIOCGIFNETMASK; return ioctl(p, (struct ioctl_args *)args, retval); + /* get hardware address */ + case LINUX_SIOCGIFHWADDR: + { + int ifn; + struct ifnet *ifp; + struct ifaddr *ifa; + struct sockaddr_dl *sdl; + struct linux_ifreq *ifr = (struct linux_ifreq *)args->arg; + + /* + * Note that we don't actually respect the name in the ifreq structure, as + * Linux interface names are all different + */ +#ifdef DEBUG + { + char ifname[LINUX_IFNAMSIZ]; + + if (!copyin(ifname, (caddr_t)ifr->ifr_name, LINUX_IFNAMSIZ)) { + printf("linux_ioctl: get HW address for '%s'\n", ifname); + } + } +#endif + + for (ifn = 0; ifn < if_index; ifn++) { + + ifp = ifnet_addrs[ifn]->ifa_ifp; /* pointer to interface */ + if (ifp->if_type == IFT_ETHER) { /* looks good */ + /* walk the address list */ + for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { + if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) && /* we have an address structure */ + (sdl->sdl_family == AF_LINK) && /* it's a link address */ + (sdl->sdl_type == IFT_ETHER)) { /* for an ethernet link */ + + return(copyout(LLADDR(sdl), (caddr_t)&ifr->ifr_hwaddr.sa_data, LINUX_IFHWADDRLEN)); + } + } + } + } + return(ENOENT); /* ??? */ + } + case LINUX_SIOCADDMULTI: args->cmd = SIOCADDMULTI; return ioctl(p, (struct ioctl_args *)args, retval); diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h index ca72447..11ca2ad 100644 --- a/sys/i386/linux/linux.h +++ b/sys/i386/linux/linux.h @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id$ + * $Id: linux.h,v 1.14 1997/02/22 09:38:19 peter Exp $ */ #ifndef _I386_LINUX_LINUX_H_ @@ -517,9 +517,54 @@ struct trapframe; #define LINUX_SIOCGIFDSTADDR 0x8917 #define LINUX_SIOCGIFBRDADDR 0x8919 #define LINUX_SIOCGIFNETMASK 0x891b +#define LINUX_SIOCGIFHWADDR 0x8927 #define LINUX_SIOCADDMULTI 0x8931 #define LINUX_SIOCDELMULTI 0x8932 +struct linux_sockaddr +{ + unsigned short sa_family; + char sa_data[14]; +}; + +struct linux_ifmap +{ + unsigned long mem_start; + unsigned long mem_end; + unsigned short base_addr; + unsigned char irq; + unsigned char dma; + unsigned char port; +}; + +struct linux_ifreq +{ +#define LINUX_IFHWADDRLEN 6 +#define LINUX_IFNAMSIZ 16 + union + { + char ifrn_name[LINUX_IFNAMSIZ]; /* if name, e.g. "en0" */ + } ifr_ifrn; + + union { + struct linux_sockaddr ifru_addr; + struct linux_sockaddr ifru_dstaddr; + struct linux_sockaddr ifru_broadaddr; + struct linux_sockaddr ifru_netmask; + struct linux_sockaddr ifru_hwaddr; + short ifru_flags; + int ifru_metric; + int ifru_mtu; + struct linux_ifmap ifru_map; + char ifru_slave[LINUX_IFNAMSIZ]; /* Just fits the size */ + caddr_t ifru_data; + } ifr_ifru; +}; + +#define ifr_name ifr_ifrn.ifrn_name /* interface name */ +#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ + + /* serial_struct values for TIOC[GS]SERIAL ioctls */ #define LINUX_ASYNC_CLOSING_WAIT_INF 0 #define LINUX_ASYNC_CLOSING_WAIT_NONE 65535 @@ -548,4 +593,29 @@ struct trapframe; #define LINUX_ASYNC_CALLOUT_NOHUP 0x0400 #define LINUX_ASYNC_FLAGS 0x0FFF +/* structure and defines for i386_modify_ldt */ + +/* Maximum number of LDT entries supported. */ +#define LDT_ENTRIES 8192 +/* The size of each LDT entry. */ +#define LDT_ENTRY_SIZE 8 + +struct modify_ldt_ldt_s { + unsigned int entry_number; + unsigned long base_addr; + unsigned int limit; + unsigned int seg_32bit:1; + unsigned int contents:2; + unsigned int read_exec_only:1; + unsigned int limit_in_pages:1; + unsigned int seg_not_present:1; +}; + +#define MODIFY_LDT_CONTENTS_DATA 0 +#define MODIFY_LDT_CONTENTS_STACK 1 +#define MODIFY_LDT_CONTENTS_CODE 2 + +#define LINUX_MODIFY_LDT_GET 0 +#define LINUX_MODIFY_LDT_SET 1 + #endif /* !_I386_LINUX_LINUX_H_ */ diff --git a/sys/i386/linux/linux_ioctl.c b/sys/i386/linux/linux_ioctl.c index e748a88..c138945 100644 --- a/sys/i386/linux/linux_ioctl.c +++ b/sys/i386/linux/linux_ioctl.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_ioctl.c,v 1.15 1997/03/23 03:36:01 bde Exp $ + * $Id: linux_ioctl.c,v 1.16 1997/03/24 11:37:50 bde Exp $ */ #include <sys/param.h> @@ -41,6 +41,8 @@ #include <sys/termios.h> #include <sys/socket.h> #include <net/if.h> +#include <net/if_dl.h> +#include <net/if_types.h> #include <sys/sockio.h> #include <machine/soundcard.h> @@ -587,6 +589,47 @@ linux_ioctl(struct proc *p, struct linux_ioctl_args *args, int *retval) args->cmd = OSIOCGIFNETMASK; return ioctl(p, (struct ioctl_args *)args, retval); + /* get hardware address */ + case LINUX_SIOCGIFHWADDR: + { + int ifn; + struct ifnet *ifp; + struct ifaddr *ifa; + struct sockaddr_dl *sdl; + struct linux_ifreq *ifr = (struct linux_ifreq *)args->arg; + + /* + * Note that we don't actually respect the name in the ifreq structure, as + * Linux interface names are all different + */ +#ifdef DEBUG + { + char ifname[LINUX_IFNAMSIZ]; + + if (!copyin(ifname, (caddr_t)ifr->ifr_name, LINUX_IFNAMSIZ)) { + printf("linux_ioctl: get HW address for '%s'\n", ifname); + } + } +#endif + + for (ifn = 0; ifn < if_index; ifn++) { + + ifp = ifnet_addrs[ifn]->ifa_ifp; /* pointer to interface */ + if (ifp->if_type == IFT_ETHER) { /* looks good */ + /* walk the address list */ + for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { + if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) && /* we have an address structure */ + (sdl->sdl_family == AF_LINK) && /* it's a link address */ + (sdl->sdl_type == IFT_ETHER)) { /* for an ethernet link */ + + return(copyout(LLADDR(sdl), (caddr_t)&ifr->ifr_hwaddr.sa_data, LINUX_IFHWADDRLEN)); + } + } + } + } + return(ENOENT); /* ??? */ + } + case LINUX_SIOCADDMULTI: args->cmd = SIOCADDMULTI; return ioctl(p, (struct ioctl_args *)args, retval); |