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

📄 ioctl32.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
                struct  sockaddr ifru_hwaddr;                short   ifru_flags;                int     ifru_ivalue;                int     ifru_mtu;                struct  ifmap32 ifru_map;                char    ifru_slave[IFNAMSIZ];   /* Just fits the size */		char	ifru_newname[IFNAMSIZ];                __kernel_caddr_t32 ifru_data;        } ifr_ifru;};struct ifconf32 {        int     ifc_len;                        /* size of buffer       */        __kernel_caddr_t32  ifcbuf;};#ifdef CONFIG_NETstatic int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg){	struct net_device *dev;	struct ifreq32 ifr32;	int err;	if (copy_from_user(&ifr32, (struct ifreq32 *)arg, sizeof(struct ifreq32)))		return -EFAULT;	dev = dev_get_by_index(ifr32.ifr_ifindex);	if (!dev)		return -ENODEV;	strcpy(ifr32.ifr_name, dev->name);	dev_put(dev);	err = copy_to_user((struct ifreq32 *)arg, &ifr32, sizeof(struct ifreq32));	return (err ? -EFAULT : 0);}#endifstatic inline int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg){	struct ifconf32 ifc32;	struct ifconf ifc;	struct ifreq32 *ifr32;	struct ifreq *ifr;	mm_segment_t old_fs;	unsigned int i, j;	int err;	if (copy_from_user(&ifc32, (struct ifconf32 *)arg, sizeof(struct ifconf32)))		return -EFAULT;	if(ifc32.ifcbuf == 0) {		ifc32.ifc_len = 0;		ifc.ifc_len = 0;		ifc.ifc_buf = NULL;	} else {		ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) *			sizeof (struct ifreq);		ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL);		if (!ifc.ifc_buf)			return -ENOMEM;	}	ifr = ifc.ifc_req;	ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);	for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) {		if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) {			kfree (ifc.ifc_buf);			return -EFAULT;		}	}	old_fs = get_fs(); set_fs (KERNEL_DS);	err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);		set_fs (old_fs);	if (!err) {		ifr = ifc.ifc_req;		ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);		for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len;		     i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) {			if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) {				err = -EFAULT;				break;			}		}		if (!err) {			if (ifc32.ifcbuf == 0) {				/* Translate from 64-bit structure multiple to				 * a 32-bit one.				 */				i = ifc.ifc_len;				i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32));				ifc32.ifc_len = i;			} else {				if (i <= ifc32.ifc_len)					ifc32.ifc_len = i;				else					ifc32.ifc_len = i - sizeof (struct ifreq32);			}			if (copy_to_user((struct ifconf32 *)arg, &ifc32, sizeof(struct ifconf32)))				err = -EFAULT;		}	}	if(ifc.ifc_buf != NULL)		kfree (ifc.ifc_buf);	return err;}static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){	struct ifreq ifr;	mm_segment_t old_fs;	int err, len;	u32 data, ethcmd;		if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))		return -EFAULT;	ifr.ifr_data = (__kernel_caddr_t)get_free_page(GFP_KERNEL);	if (!ifr.ifr_data)		return -EAGAIN;	__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));	if (get_user(ethcmd, (u32 *)A(data))) {		err = -EFAULT;		goto out;	}	switch (ethcmd) {	case ETHTOOL_GDRVINFO:	len = sizeof(struct ethtool_drvinfo); break;	case ETHTOOL_GMSGLVL:	case ETHTOOL_SMSGLVL:	case ETHTOOL_GLINK:	case ETHTOOL_NWAY_RST:	len = sizeof(struct ethtool_value); break;	case ETHTOOL_GREGS: {		struct ethtool_regs *regaddr = (struct ethtool_regs *)A(data);		/* darned variable size arguments */		if (get_user(len, (u32 *)&regaddr->len)) {			err = -EFAULT;			goto out;		}		len += sizeof(struct ethtool_regs);		break;	}	case ETHTOOL_GSET:	case ETHTOOL_SSET:	len = sizeof(struct ethtool_cmd); break;	default:		err = -EOPNOTSUPP;		goto out;	}	if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {		err = -EFAULT;		goto out;	}	old_fs = get_fs();	set_fs (KERNEL_DS);	err = sys_ioctl (fd, cmd, (unsigned long)&ifr);	set_fs (old_fs);	if (!err) {		u32 data;		__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));		len = copy_to_user((char *)A(data), ifr.ifr_data, len);		if (len)			err = -EFAULT;	}out:	free_page((unsigned long)ifr.ifr_data);	return err;}static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg){	struct ifreq ifr;	mm_segment_t old_fs;	int err, len;	u32 data;		if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))		return -EFAULT;	ifr.ifr_data = (__kernel_caddr_t)get_free_page(GFP_KERNEL);	if (!ifr.ifr_data)		return -EAGAIN;	switch (cmd) {	case SIOCBONDENSLAVE:	case SIOCBONDRELEASE:	case SIOCBONDSETHWADDR:	case SIOCBONDCHANGEACTIVE:		len = IFNAMSIZ * sizeof(char);		break;	case SIOCBONDSLAVEINFOQUERY:		len = sizeof(struct ifslave);		break;	case SIOCBONDINFOQUERY:		len = sizeof(struct ifbond);		break;	default:		err = -EINVAL;		goto out;	};	__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));	if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {		err = -EFAULT;		goto out;	}	old_fs = get_fs();	set_fs (KERNEL_DS);	err = sys_ioctl (fd, cmd, (unsigned long)&ifr);	set_fs (old_fs);	if (!err) {		len = copy_to_user((char *)A(data), ifr.ifr_data, len);		if (len)			err = -EFAULT;	}out:	free_page((unsigned long)ifr.ifr_data);	return err;}static inline int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg){	struct ifreq ifr;	mm_segment_t old_fs;	int err;		switch (cmd) {	case SIOCSIFMAP:		err = copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(ifr.ifr_name));		err |= __get_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));		err |= __get_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));		err |= __get_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));		err |= __get_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));		err |= __get_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));		err |= __get_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));		if (err)			return -EFAULT;		break;	case SIOCGPPPSTATS:	case SIOCGPPPCSTATS:	case SIOCGPPPVER:		if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))			return -EFAULT;		ifr.ifr_data = (__kernel_caddr_t)get_free_page(GFP_KERNEL);		if (!ifr.ifr_data)			return -EAGAIN;		break;	default:		if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))			return -EFAULT;		break;	}	old_fs = get_fs();	set_fs (KERNEL_DS);	err = sys_ioctl (fd, cmd, (unsigned long)&ifr);	set_fs (old_fs);	if (!err) {		switch (cmd) {		case SIOCGIFFLAGS:		case SIOCGIFMETRIC:		case SIOCGIFMTU:		case SIOCGIFMEM:		case SIOCGIFHWADDR:		case SIOCGIFINDEX:		case SIOCGIFADDR:		case SIOCGIFBRDADDR:		case SIOCGIFDSTADDR:		case SIOCGIFNETMASK:		case SIOCGIFTXQLEN:			if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32)))				return -EFAULT;			break;		case SIOCGPPPSTATS:		case SIOCGPPPCSTATS:		case SIOCGPPPVER:		{			u32 data;			int len;			__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));			if(cmd == SIOCGPPPVER)				len = strlen((char *)ifr.ifr_data) + 1;			else if(cmd == SIOCGPPPCSTATS)				len = sizeof(struct ppp_comp_stats);			else				len = sizeof(struct ppp_stats);			len = copy_to_user((char *)A(data), ifr.ifr_data, len);			free_page((unsigned long)ifr.ifr_data);			if(len)				return -EFAULT;			break;		}		case SIOCGIFMAP:			err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name));			err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));			err |= __put_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));			err |= __put_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));			err |= __put_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));			err |= __put_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));			err |= __put_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));			if (err)				err = -EFAULT;			break;		}	} else {		switch (cmd) {		case SIOCGPPPSTATS:		case SIOCGPPPCSTATS:		case SIOCGPPPVER:			free_page((unsigned long)ifr.ifr_data);			break;		}	}	return err;}struct rtentry32 {        u32   		rt_pad1;        struct sockaddr rt_dst;         /* target address               */        struct sockaddr rt_gateway;     /* gateway addr (RTF_GATEWAY)   */        struct sockaddr rt_genmask;     /* target network mask (IP)     */        unsigned short  rt_flags;        short           rt_pad2;        u32   		rt_pad3;        unsigned char   rt_tos;        unsigned char   rt_class;        short           rt_pad4;        short           rt_metric;      /* +1 for binary compatibility! */        /* char * */ u32 rt_dev;        /* forcing the device at add    */        u32   		rt_mtu;         /* per route MTU/Window         */        u32   		rt_window;      /* Window clamping              */        unsigned short  rt_irtt;        /* Initial RTT                  */};struct in6_rtmsg32 {	struct in6_addr		rtmsg_dst;	struct in6_addr		rtmsg_src;	struct in6_addr		rtmsg_gateway;	u32			rtmsg_type;	u16			rtmsg_dst_len;	u16			rtmsg_src_len;	u32			rtmsg_metric;	u32			rtmsg_info;	u32			rtmsg_flags;	s32			rtmsg_ifindex;};extern struct socket *sockfd_lookup(int fd, int *err);static inline int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){	int ret;	void *r = NULL;	struct in6_rtmsg r6;	struct rtentry r4;	char devname[16];	u32 rtdev;	mm_segment_t old_fs = get_fs();		struct socket *mysock = sockfd_lookup(fd, &ret);	if (mysock && mysock->sk && mysock->sk->family == AF_INET6) { /* ipv6 */		ret = copy_from_user (&r6.rtmsg_dst, &(((struct in6_rtmsg32 *)arg)->rtmsg_dst),			3 * sizeof(struct in6_addr));		ret |= __get_user (r6.rtmsg_type, &(((struct in6_rtmsg32 *)arg)->rtmsg_type));		ret |= __get_user (r6.rtmsg_dst_len, &(((struct in6_rtmsg32 *)arg)->rtmsg_dst_len));		ret |= __get_user (r6.rtmsg_src_len, &(((struct in6_rtmsg32 *)arg)->rtmsg_src_len));		ret |= __get_user (r6.rtmsg_metric, &(((struct in6_rtmsg32 *)arg)->rtmsg_metric));		ret |= __get_user (r6.rtmsg_info, &(((struct in6_rtmsg32 *)arg)->rtmsg_info));		ret |= __get_user (r6.rtmsg_flags, &(((struct in6_rtmsg32 *)arg)->rtmsg_flags));		ret |= __get_user (r6.rtmsg_ifindex, &(((struct in6_rtmsg32 *)arg)->rtmsg_ifindex));				r = (void *) &r6;	} else { /* ipv4 */		ret = copy_from_user (&r4.rt_dst, &(((struct rtentry32 *)arg)->rt_dst), 3 * sizeof(struct sockaddr));		ret |= __get_user (r4.rt_flags, &(((struct rtentry32 *)arg)->rt_flags));		ret |= __get_user (r4.rt_metric, &(((struct rtentry32 *)arg)->rt_metric));		ret |= __get_user (r4.rt_mtu, &(((struct rtentry32 *)arg)->rt_mtu));		ret |= __get_user (r4.rt_window, &(((struct rtentry32 *)arg)->rt_window));		ret |= __get_user (r4.rt_irtt, &(((struct rtentry32 *)arg)->rt_irtt));		ret |= __get_user (rtdev, &(((struct rtentry32 *)arg)->rt_dev));		if (rtdev) {			ret |= copy_from_user (devname, (char *)A(rtdev), 15);			r4.rt_dev = devname; devname[15] = 0;		} else			r4.rt_dev = 0;		r = (void *) &r4;	}	if (ret)		return -EFAULT;	set_fs (KERNEL_DS);	ret = sys_ioctl (fd, cmd, (long) r);	set_fs (old_fs);	return ret;}struct hd_geometry32 {	unsigned char heads;	unsigned char sectors;	unsigned short cylinders;	u32 start;};                        static inline int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg){	mm_segment_t old_fs = get_fs();	struct hd_geometry geo;	int err;		set_fs (KERNEL_DS);	err = sys_ioctl(fd, HDIO_GETGEO, (unsigned long)&geo);	set_fs (old_fs);	if (!err) {		err = copy_to_user ((struct hd_geometry32 *)arg, &geo, 4);		err |= __put_user (geo.start, &(((struct hd_geometry32 *)arg)->start));	}	return err ? -EFAULT : 0;}struct  fbcmap32 {	int             index;          /* first element (0 origin) */	int             count;	u32		red;	u32		green;	u32		blue;};#define FBIOPUTCMAP32	_IOW('F', 3, struct fbcmap32)#define FBIOGETCMAP32	_IOW('F', 4, struct fbcmap32)static inline int fbiogetputcmap(unsigned int fd, unsigned int cmd, unsigned long arg){	struct fbcmap f;	int ret;

⌨️ 快捷键说明

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