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

📄 ioctl32.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        } ifr_ifru;};struct ifconf32 {        int     ifc_len;                        /* size of buffer       */        __kernel_caddr_t32  ifcbuf;};static 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);	err = copy_to_user((struct ifreq32 *)arg, &ifr32, sizeof(struct ifreq32));	return (err ? -EFAULT : 0);}static 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 (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 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:	case SIOCETHTOOL:		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;		if(cmd == SIOCETHTOOL) {			u32 data;			__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));			if(copy_from_user(ifr.ifr_data,					  (char *)A(data),					  sizeof(struct ethtool_cmd))) {				free_page((unsigned long)ifr.ifr_data);				return -EFAULT;			}		}		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:		case SIOCETHTOOL:		{			u32 data;			int len;			__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));			if(cmd == SIOCETHTOOL)				len = sizeof(struct ethtool_cmd);			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;		}	}	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;	char red[256], green[256], blue[256];	u32 r, g, b;	mm_segment_t old_fs = get_fs();		ret = get_user(f.index, &(((struct fbcmap32 *)arg)->index));	ret |= __get_user(f.count, &(((struct fbcmap32 *)arg)->count));	ret |= __get_user(r, &(((struct fbcmap32 *)arg)->red));	ret |= __get_user(g, &(((struct fbcmap32 *)arg)->green));	ret |= __get_user(b, &(((struct fbcmap32 *)arg)->blue));	if (ret)		return -EFAULT;	if ((f.index < 0) || (f.index > 255)) return -EINVAL;	if (f.index + f.count > 256)		f.count = 256 - f.index;	if (cmd == FBIOPUTCMAP32) {		ret = copy_from_user (red, (char *)A(r), f.count);		ret |= copy_from_user (green, (char *)A(g), f.count);		ret |= copy_from_user (blue, (char *)A(b), f.count);		if (ret)			return -EFAULT;	}	f.red = red; f.green = green; f.blue = blue;	set_fs (KERNEL_DS);	ret = sys_ioctl (fd, (cmd == FBIOPUTCMAP32) ? FBIOPUTCMAP_SPARC : FBIOGETCMAP_SPARC, (long)&f);	set_fs (old_fs);	if (!ret && cmd == FBIOGETCMAP32) {		ret = copy_to_user ((char *)A(r), red, f.count);		ret |= copy_to_user ((char *)A(g), green, f.count);		ret |= copy_to_user ((char *)A(b), blue, f.count);	}	return ret ? -EFAULT : 0;}struct fbcursor32 {	short set;		/* what to set, choose from the list above */	short enable;		/* cursor on/off */	struct fbcurpos pos;	/* cursor position */	struct fbcurpos hot;	/* cursor hot spot */	struct fbcmap32 cmap;	/* color map info */	struct fbcurpos size;	/* cursor bit map size */	u32	image;		/* cursor image bits */	u32	mask;		/* cursor mask bits */};	#define FBIOSCURSOR32	_IOW('F', 24, struct fbcursor32)#define FBIOGCURSOR32	_IOW('F', 25, struct fbcursor32)static inline int fbiogscursor(unsigned int fd, unsigned int cmd, unsigned long arg){	struct fbcursor f;	int ret;	char red[2], green[2], blue[2];	char image[128], mask[128];	u32 r, g, b;	u32 m, i;	mm_segment_t old_fs = get_fs();		ret = copy_from_user (&f, (struct fbcursor32 *)arg, 2 * sizeof (short) + 2 * sizeof(struct fbcurpos));	ret |= __get_user(f.size.fbx, &(((struct fbcursor32 *)arg)->size.fbx));	ret |= __get_user(f.size.fby, &(((struct fbcursor32 *)arg)->size.fby));	ret |= __get_user(f.cmap.index, &(((struct fbcursor32 *)arg)->cmap.index));	ret |= __get_user(f.cmap.count, &(((struct fbcursor32 *)arg)->cmap.count));	ret |= __get_user(r, &(((struct fbcursor32 *)arg)->cmap.red));	ret |= __get_user(g, &(((struct fbcursor32 *)arg)->cmap.green));	ret |= __get_user(b, &(((struct fbcursor32 *)arg)->cmap.blue));	ret |= __get_user(m, &(((struct fbcursor32 *)arg)->mask));	ret |= __get_user(i, &(((struct fbcursor32 *)arg)->image));	if (ret)		return -EFAULT;	if (f.set & FB_CUR_SETCMAP) {		if ((uint) f.size.fby > 32)			return -EINVAL;		ret = copy_from_user (mask, (char *)A(m), f.size.fby * 4);		ret |= copy_from_user (image, (char *)A(i), f.size.fby * 4);		if (ret)			return -EFAULT;		f.image = image; f.mask = mask;	}	if (f.set & FB_CUR_SETCMAP) {		ret = copy_from_user (red, (char *)A(r), 2);		ret |= copy_from_user (green, (char *)A(g), 2);		ret |= copy_from_user (blue, (char *)A(b), 2);		if (ret)			return -EFAULT;		f.cmap.red = red; f.cmap.green = green; f.cmap.blue = blue;	}	set_fs (KERNEL_DS);	ret = sys_ioctl (fd, FBIOSCURSOR, (long)&f);	set_fs (old_fs);	return ret;}struct fb_fix_screeninfo32 {	char			id[16];        __kernel_caddr_t32	smem_start;	__u32			smem_len;	__u32			type;	__u32			type_aux;	__u32			visual;	__u16			xpanstep;	__u16			ypanstep;	__u16			ywrapstep;	__u32			line_length;        __kernel_caddr_t32	mmio_start;	__u32			mmio_len;	__u32			accel;	__u16			reserved[3];};struct fb_cmap32 {	__u32			start;	__u32			len;	__kernel_caddr_t32	red;	__kernel_caddr_t32	green;	__kernel_caddr_t32	blue;	__kernel_caddr_t32	transp;};static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg){	mm_segment_t old_fs = get_fs();	u32 red = 0, green = 0, blue = 0, transp = 0;	struct fb_fix_screeninfo fix;	struct fb_cmap cmap;	void *karg;	int err = 0;	memset(&cmap, 0, sizeof(cmap));	switch (cmd) {

⌨️ 快捷键说明

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