aboutsummaryrefslogtreecommitdiff
path: root/sys/i386/linux/linux_ioctl.c
diff options
context:
space:
mode:
authorMike Smith <msmith@FreeBSD.org>1997-06-02 06:31:49 +0000
committerMike Smith <msmith@FreeBSD.org>1997-06-02 06:31:49 +0000
commit3713cbff7595a492b498a7f061cd563ce05b5d49 (patch)
tree39479d26fd96afdd49654dbdb2c6743410fa0e91 /sys/i386/linux/linux_ioctl.c
parent877155d0f5389f7f63e01cfd68d59789a96db9a0 (diff)
downloadsrc-3713cbff7595a492b498a7f061cd563ce05b5d49.tar.gz
src-3713cbff7595a492b498a7f061cd563ce05b5d49.zip
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".
Notes
Notes: svn path=/head/; revision=26364
Diffstat (limited to 'sys/i386/linux/linux_ioctl.c')
-rw-r--r--sys/i386/linux/linux_ioctl.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/sys/i386/linux/linux_ioctl.c b/sys/i386/linux/linux_ioctl.c
index e748a88cffe3..c138945e1b67 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);