📄 ip_ioctl.c
字号:
/*ip_ioctl.cCopyright 1995 Philip Homburg*/#include "inet.h"#include "buf.h"#include "event.h"#include "type.h"#include "arp.h"#include "assert.h"#include "clock.h"#include "icmp_lib.h"#include "ip.h"#include "ip_int.h"#include "ipr.h"THIS_FILEFORWARD int ip_checkopt ARGS(( ip_fd_t *ip_fd ));FORWARD void reply_thr_get ARGS(( ip_fd_t *ip_fd, size_t reply, int for_ioctl ));FORWARD void report_addr ARGS(( ip_port_t *ip_port ));PUBLIC int ip_ioctl (fd, req)int fd;ioreq_t req;{ ip_fd_t *ip_fd; ip_port_t *ip_port; nwio_ipopt_t *ipopt; nwio_ipopt_t oldopt, newopt; nwio_ipconf2_t *ipconf2; nwio_ipconf_t *ipconf; nwio_route_t *route_ent; acc_t *data; int result; unsigned int new_en_flags, new_di_flags, old_en_flags, old_di_flags; unsigned long new_flags; int ent_no, r; nwio_ipconf_t ipconf_var; assert (fd>=0 && fd<=IP_FD_NR); ip_fd= &ip_fd_table[fd]; assert (ip_fd->if_flags & IFF_INUSE); switch (req) { case NWIOSIPOPT: ip_port= ip_fd->if_port; if (!(ip_port->ip_flags & IPF_IPADDRSET)) { ip_fd->if_ioctl= NWIOSIPOPT; ip_fd->if_flags |= IFF_IOCTL_IP; return NW_SUSPEND; } ip_fd->if_flags &= ~IFF_IOCTL_IP; data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0, sizeof(nwio_ipopt_t), TRUE); data= bf_packIffLess (data, sizeof(nwio_ipopt_t)); assert (data->acc_length == sizeof(nwio_ipopt_t)); ipopt= (nwio_ipopt_t *)ptr2acc_data(data); oldopt= ip_fd->if_ipopt; newopt= *ipopt; old_en_flags= oldopt.nwio_flags & 0xffff; old_di_flags= (oldopt.nwio_flags >> 16) & 0xffff; new_en_flags= newopt.nwio_flags & 0xffff; new_di_flags= (newopt.nwio_flags >> 16) & 0xffff; if (new_en_flags & new_di_flags) { bf_afree(data); reply_thr_get (ip_fd, EBADMODE, TRUE); return NW_OK; } /* NWIO_ACC_MASK */ if (new_di_flags & NWIO_ACC_MASK) { bf_afree(data); reply_thr_get (ip_fd, EBADMODE, TRUE); return NW_OK; /* access modes can't be disable */ } if (!(new_en_flags & NWIO_ACC_MASK)) new_en_flags |= (old_en_flags & NWIO_ACC_MASK); /* NWIO_LOC_MASK */ if (!((new_en_flags|new_di_flags) & NWIO_LOC_MASK)) { new_en_flags |= (old_en_flags & NWIO_LOC_MASK); new_di_flags |= (old_di_flags & NWIO_LOC_MASK); } /* NWIO_BROAD_MASK */ if (!((new_en_flags|new_di_flags) & NWIO_BROAD_MASK)) { new_en_flags |= (old_en_flags & NWIO_BROAD_MASK); new_di_flags |= (old_di_flags & NWIO_BROAD_MASK); } /* NWIO_REM_MASK */ if (!((new_en_flags|new_di_flags) & NWIO_REM_MASK)) { new_en_flags |= (old_en_flags & NWIO_REM_MASK); new_di_flags |= (old_di_flags & NWIO_REM_MASK); newopt.nwio_rem= oldopt.nwio_rem; } /* NWIO_PROTO_MASK */ if (!((new_en_flags|new_di_flags) & NWIO_PROTO_MASK)) { new_en_flags |= (old_en_flags & NWIO_PROTO_MASK); new_di_flags |= (old_di_flags & NWIO_PROTO_MASK); newopt.nwio_proto= oldopt.nwio_proto; } /* NWIO_HDR_O_MASK */ if (!((new_en_flags|new_di_flags) & NWIO_HDR_O_MASK)) { new_en_flags |= (old_en_flags & NWIO_HDR_O_MASK); new_di_flags |= (old_di_flags & NWIO_HDR_O_MASK); newopt.nwio_tos= oldopt.nwio_tos; newopt.nwio_ttl= oldopt.nwio_ttl; newopt.nwio_df= oldopt.nwio_df; newopt.nwio_hdropt= oldopt.nwio_hdropt; } /* NWIO_RW_MASK */ if (!((new_en_flags|new_di_flags) & NWIO_RW_MASK)) { new_en_flags |= (old_en_flags & NWIO_RW_MASK); new_di_flags |= (old_di_flags & NWIO_RW_MASK); } new_flags= ((unsigned long)new_di_flags << 16) | new_en_flags; if ((new_flags & NWIO_RWDATONLY) && (new_flags & (NWIO_REMANY|NWIO_PROTOANY|NWIO_HDR_O_ANY))) { bf_afree(data); reply_thr_get(ip_fd, EBADMODE, TRUE); return NW_OK; } if (ip_fd->if_flags & IFF_OPTSET) ip_unhash_proto(ip_fd); newopt.nwio_flags= new_flags; ip_fd->if_ipopt= newopt; result= ip_checkopt(ip_fd); if (result<0) ip_fd->if_ipopt= oldopt; bf_afree(data); reply_thr_get (ip_fd, result, TRUE); return NW_OK; case NWIOGIPOPT: data= bf_memreq(sizeof(nwio_ipopt_t)); ipopt= (nwio_ipopt_t *)ptr2acc_data(data); *ipopt= ip_fd->if_ipopt; result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0, data, TRUE); return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result, (acc_t *)0, TRUE); case NWIOSIPCONF2: case NWIOSIPCONF: ip_port= ip_fd->if_port; if (req == NWIOSIPCONF2) { data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0, sizeof(*ipconf2), TRUE); data= bf_packIffLess (data, sizeof(*ipconf2)); assert (data->acc_length == sizeof(*ipconf2)); ipconf2= (nwio_ipconf2_t *)ptr2acc_data(data); ipconf= &ipconf_var; ipconf->nwic_flags= ipconf2->nwic_flags; ipconf->nwic_ipaddr= ipconf2->nwic_ipaddr; ipconf->nwic_netmask= ipconf2->nwic_netmask; ipconf->nwic_flags &= ~NWIC_MTU_SET; } else { data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0, sizeof(*ipconf), TRUE); data= bf_packIffLess (data, sizeof(*ipconf)); assert (data->acc_length == sizeof(*ipconf)); ipconf= (nwio_ipconf_t *)ptr2acc_data(data); } r= ip_setconf(ip_port-ip_port_table, ipconf); bf_afree(data); return (*ip_fd->if_put_userdata)(ip_fd-> if_srfd, r, (acc_t *)0, TRUE); case NWIOGIPCONF2: ip_port= ip_fd->if_port; if (!(ip_port->ip_flags & IPF_IPADDRSET)) { ip_fd->if_ioctl= NWIOGIPCONF2; ip_fd->if_flags |= IFF_IOCTL_IP; return NW_SUSPEND; } ip_fd->if_flags &= ~IFF_IOCTL_IP; data= bf_memreq(sizeof(nwio_ipconf_t)); ipconf2= (nwio_ipconf2_t *)ptr2acc_data(data); ipconf2->nwic_flags= NWIC_IPADDR_SET; ipconf2->nwic_ipaddr= ip_port->ip_ipaddr; ipconf2->nwic_netmask= ip_port->ip_subnetmask; if (ip_port->ip_flags & IPF_NETMASKSET) ipconf2->nwic_flags |= NWIC_NETMASK_SET; result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0, data, TRUE); return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result, (acc_t *)0, TRUE); case NWIOGIPCONF: ip_port= ip_fd->if_port; if (!(ip_port->ip_flags & IPF_IPADDRSET)) { ip_fd->if_ioctl= NWIOGIPCONF; ip_fd->if_flags |= IFF_IOCTL_IP; return NW_SUSPEND; } ip_fd->if_flags &= ~IFF_IOCTL_IP; data= bf_memreq(sizeof(*ipconf)); ipconf= (nwio_ipconf_t *)ptr2acc_data(data); ipconf->nwic_flags= NWIC_IPADDR_SET; ipconf->nwic_ipaddr= ip_port->ip_ipaddr; ipconf->nwic_netmask= ip_port->ip_subnetmask; if (ip_port->ip_flags & IPF_NETMASKSET) ipconf->nwic_flags |= NWIC_NETMASK_SET; ipconf->nwic_mtu= ip_port->ip_mtu; result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0, data, TRUE); return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result, (acc_t *)0, TRUE); case NWIOGIPOROUTE: data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0, sizeof(nwio_route_t), TRUE); if (data == NULL) { return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, EFAULT, NULL, TRUE); } data= bf_packIffLess (data, sizeof(nwio_route_t) ); route_ent= (nwio_route_t *)ptr2acc_data(data); ent_no= route_ent->nwr_ent_no; bf_afree(data); data= bf_memreq(sizeof(nwio_route_t)); route_ent= (nwio_route_t *)ptr2acc_data(data); result= ipr_get_oroute(ent_no, route_ent); if (result < 0) bf_afree(data); else { assert(result == NW_OK); result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0, data, TRUE); } return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result, (acc_t *)0, TRUE); case NWIOSIPOROUTE: data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0, sizeof(nwio_route_t), TRUE); if (data == NULL) { return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, EFAULT, NULL, TRUE); } if (!(ip_fd->if_port->ip_flags & IPF_IPADDRSET)) { /* Interface is down, no changes allowed */ return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, EINVAL, NULL, TRUE); } data= bf_packIffLess (data, sizeof(nwio_route_t) ); route_ent= (nwio_route_t *)ptr2acc_data(data); result= ipr_add_oroute(ip_fd->if_port-ip_port_table, route_ent->nwr_dest, route_ent->nwr_netmask, route_ent->nwr_gateway, (time_t)0, route_ent->nwr_dist, route_ent->nwr_mtu, !!(route_ent->nwr_flags & NWRF_STATIC), route_ent->nwr_pref, NULL); bf_afree(data); return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result, (acc_t *)0, TRUE); case NWIODIPOROUTE: data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0, sizeof(nwio_route_t), TRUE); if (data == NULL) { return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, EFAULT, NULL, TRUE); } data= bf_packIffLess (data, sizeof(nwio_route_t) ); route_ent= (nwio_route_t *)ptr2acc_data(data); result= ipr_del_oroute(ip_fd->if_port-ip_port_table, route_ent->nwr_dest, route_ent->nwr_netmask, route_ent->nwr_gateway, !!(route_ent->nwr_flags & NWRF_STATIC)); bf_afree(data); return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result, (acc_t *)0, TRUE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -