diff options
Diffstat (limited to 'sys')
-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); |