📄 ioctl32.c
字号:
} 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 + -