/* * Handle the IOCTL system call for the NET devices. This basically * means I/O control for the SOCKET layer (future expansions could be * a variable number of socket table entries, et al), and for the more * general protocols like ARP. The latter currently lives in the INET * module, so we have to get ugly a tiny little bit. Later... -FvK */ static int net_fioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { extern int arp_ioctl(unsigned int, void *); /* Dispatch on the minor device. */ switch(MINOR(inode->i_rdev)) { case 0: /* NET (SOCKET) */ DPRINTF((net_debug, "NET: SOCKET level I/O control request.\n")); return(net_ioctl(cmd, arg)); #ifdef CONFIG_INET case 1: /* ARP */ DPRINTF((net_debug, "NET: ARP level I/O control request.\n")); return(arp_ioctl(cmd, (void *) arg)); #endif default: return(-ENODEV); } /*NOTREACHED*/ return(-EINVAL); }
static void recv_unix(void) { UN_CTX ctx; struct atmarp_req req; int len,reply; len = un_recv(&ctx,unix_sock,&req,sizeof(req)); if (len < 0) { diag(COMPONENT,DIAG_ERROR,"recv_unix: %s",strerror(errno)); return; } if (len != sizeof(req)) { diag(COMPONENT,DIAG_ERROR,"bad unix read: %d != %d",len,sizeof(req)); return; } switch (req.type) { case art_create: reply = ioctl(kernel,SIOCMKCLIP,req.itf); if (reply >= 0) itf_create(reply); break; case art_qos: case art_set: case art_delete: reply = arp_ioctl(&req); break; case art_table: reply = table_update(); break; case art_query: query_ip(&ctx,req.ip); return; default: diag(COMPONENT,DIAG_ERROR,"invalid request msg type 0x%x",req.type); reply = -EINVAL; } if (un_send(&ctx,&reply,sizeof(reply)) < 0) diag(COMPONENT,DIAG_ERROR,"un_send: %s",strerror(errno)); }
static int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct sock *sk=(struct sock *)sock->data; int err, pid; switch(cmd) { case FIOSETOWN: case SIOCSPGRP: err=verify_area(VERIFY_READ,(int *)arg,sizeof(long)); if(err) return err; pid = get_fs_long((int *) arg); /* see inet_fcntl */ if (current->pid != pid && current->pgrp != -pid && !suser()) return -EPERM; sk->proc = pid; return(0); case FIOGETOWN: case SIOCGPGRP: err=verify_area(VERIFY_WRITE,(void *) arg, sizeof(long)); if(err) return err; put_fs_long(sk->proc,(int *)arg); return(0); case SIOCGSTAMP: if(sk->stamp.tv_sec==0) return -ENOENT; err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(struct timeval)); if(err) return err; memcpy_tofs((void *)arg,&sk->stamp,sizeof(struct timeval)); return 0; case SIOCADDRT: case SIOCADDRTOLD: case SIOCDELRT: case SIOCDELRTOLD: return(ip_rt_ioctl(cmd,(void *) arg)); case SIOCDARP: case SIOCGARP: case SIOCSARP: return(arp_ioctl(cmd,(void *) arg)); #ifdef CONFIG_INET_RARP case SIOCDRARP: case SIOCGRARP: case SIOCSRARP: return(rarp_ioctl(cmd,(void *) arg)); #endif case SIOCGIFCONF: case SIOCGIFFLAGS: case SIOCSIFFLAGS: case SIOCGIFADDR: case SIOCSIFADDR: /* begin multicast support change */ case SIOCADDMULTI: case SIOCDELMULTI: /* end multicast support change */ case SIOCGIFDSTADDR: case SIOCSIFDSTADDR: case SIOCGIFBRDADDR: case SIOCSIFBRDADDR: case SIOCGIFNETMASK: case SIOCSIFNETMASK: case SIOCGIFMETRIC: case SIOCSIFMETRIC: case SIOCGIFMEM: case SIOCSIFMEM: case SIOCGIFMTU: case SIOCSIFMTU: case SIOCSIFLINK: case SIOCGIFHWADDR: case SIOCSIFHWADDR: case OLD_SIOCGIFHWADDR: case SIOCSIFMAP: case SIOCGIFMAP: case SIOCSIFSLAVE: case SIOCGIFSLAVE: return(dev_ioctl(cmd,(void *) arg)); default: if ((cmd >= SIOCDEVPRIVATE) && (cmd <= (SIOCDEVPRIVATE + 15))) return(dev_ioctl(cmd,(void *) arg)); if (sk->prot->ioctl==NULL) return(-EINVAL); return(sk->prot->ioctl(sk, cmd, arg)); } /*NOTREACHED*/ return(0); }