예제 #1
0
/*---
 * Control hooks:
 * ipfw_ctl_h() is a wrapper for linux to FreeBSD sockopt call convention.
 * then call the ipfw handler in order to manage requests.
 * In turn this is called by the linux set/get handlers.
 */
static int
ipfw_ctl_h(struct sockopt *s, int cmd, int dir, int len, void __user *user)
{
	struct thread t;
	int ret = EINVAL;

	memset(s, 0, sizeof(*s));
	s->sopt_name = cmd;
	s->sopt_dir = dir;
	s->sopt_valsize = len;
	s->sopt_val = user;

	/* sopt_td is not used but it is referenced */
	memset(&t, 0, sizeof(t));
	s->sopt_td = &t;
	
	if (ip_fw_ctl_ptr && cmd != IP_DUMMYNET3 && (cmd == IP_FW3 ||
	    cmd < IP_DUMMYNET_CONFIGURE))
		ret = ip_fw_ctl_ptr(s);
	else if (ip_dn_ctl_ptr && (cmd == IP_DUMMYNET3 ||
	    cmd >= IP_DUMMYNET_CONFIGURE))
		ret = ip_dn_ctl_ptr(s);
	
	return -ret;	/* errors are < 0 on linux */
}
예제 #2
0
static void
ip_fw_sockopt_dispatch(netmsg_t msg)
{
	struct sockopt *sopt = msg->lmsg.u.ms_resultp;
	int error;

	KKASSERT(mycpuid == 0);

	if (IPFW_LOADED)
		error = ip_fw_ctl_ptr(sopt);
	else
		error = ENOPROTOOPT;
	lwkt_replymsg(&msg->lmsg, error);
}
예제 #3
0
파일: wipfw.c 프로젝트: superactive/wipfw
/* IRP_MJ_DEVICE_CONTROL for control device dispatcher */
NTSTATUS
DispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP irp)
{
    PIO_STACK_LOCATION irps = IoGetCurrentIrpStackLocation(irp);
    
    ULONG ioctl = irps->Parameters.DeviceIoControl.IoControlCode,
        len = irps->Parameters.DeviceIoControl.InputBufferLength,
        size = irps->Parameters.DeviceIoControl.OutputBufferLength;
    
    void *buf = irp->AssociatedIrp.SystemBuffer;
    NTSTATUS status;

    irp->IoStatus.Information = 0;      // neccessary?

    switch (ioctl) {
    case IP_FW_SETSOCKOPT:
    case IP_FW_GETSOCKOPT: {
        
        struct sockopt *sopt;

        if (len < sizeof(struct sockopt)) {
            status = STATUS_INFO_LENGTH_MISMATCH;
            break;
        }

        sopt = (struct sockopt *)buf;

        // setup sopt->sopt_val
        if (sopt->sopt_valsize > 0)
            sopt->sopt_val = sopt->sopt_val_buf;
        else
            sopt->sopt_val = NULL;

        if (ip_fw_ctl_ptr != NULL) {
            status = ip_fw_ctl_ptr(sopt);
            if (status == STATUS_SUCCESS && ioctl == IP_FW_GETSOCKOPT) {
                irp->IoStatus.Information = sizeof(struct sockopt) + sopt->sopt_valsize;
            }

        } else
            status = STATUS_INVALID_PARAMETER;      // ??? good status ???

        break;
    }

    case IP_FW_SET_IFLIST:

        if (len < sizeof(struct ip_fw_iflist_entry)) {
            status = STATUS_INFO_LENGTH_MISMATCH;
            break;
        }

        status = iflist_setup((struct ip_fw_iflist_entry *)buf);

        break;
    
    case IP_FW_SYSCTL_IO: {
    
    	struct sysctl *ctldata;
    	int *n;
    	
    	if (len < sizeof(struct sysctl)) {
    		status = STATUS_INFO_LENGTH_MISMATCH;
    		break;
    	}
    	
    	ctldata = (struct sysctl *)buf;
    	
    	switch (ctldata->sysctl_name) {
    	case FW_ONE_PASS:
    		n = _fw_one_pass;
    		break;
    	case FW_DEBUG:
    		n = _fw_debug;
    		break;
    	case FW_VERBOSE:
    		n = _fw_verbose;
    		break;	
    	case FW_VERBOSE_LIMIT:
    		n = _fw_verbose_limit;
    		break;
    	case DYN_BUCKETS:
    		n = _fw_dyn_buckets;
    		break;
    	case CURR_DYN_BUCKETS:
    		n = _fw_curr_dyn_buckets;
    		ctldata->sopt_dir = SOPT_GET;
    		break;
    	case DYN_COUNT:
    		n = _fw_dyn_count;
    		ctldata->sopt_dir = SOPT_GET;
    		break;
    	case DYN_MAX:
    		n = _fw_dyn_max;
    		break;
    	case STATIC_COUNT:
    		n = _fw_static_count;
    		ctldata->sopt_dir = SOPT_GET;
    		break;
    	case DYN_ACK_LIFETIME:
    		n = _fw_dyn_ack_lifetime;
    		break;
    	case DYN_SYN_LIFETIME:
    		n = _fw_dyn_syn_lifetime;
    		break;
    	case DYN_FIN_LIFETIME:
    		n = _fw_dyn_fin_lifetime;
    		break;
    	case DYN_RST_LIFETIME:
    		n = _fw_dyn_rst_lifetime;
    		break;
    	case DYN_UDP_LIFETIME:
    		n = _fw_dyn_udp_lifetime;
    		break;
    	case DYN_SHORT_LIFETIME:
    		n = _fw_dyn_short_lifetime;
    		break;
#ifndef IPFW2
    	case DYN_GRACE_TIME:
    		n = _fw_dyn_grace_time;
    		ctldata->sopt_dir = SOPT_GET;
#else
        case DYN_KEEPALIVE:
    		n = _fw_dyn_keepalive;
#endif
    		break;
       	default:
    		break;
    	}
    	
    	if (ctldata->sopt_dir == SOPT_SET) {
    		*n = ctldata->sysctl_val;
    	}
    	
    	ctldata->sysctl_val = *n;
    	irp->IoStatus.Information = sizeof(struct sysctl);
    	
    	status = STATUS_SUCCESS;
        break;
    }
    
    default:
        status = STATUS_NOT_SUPPORTED;
    }

    irp->IoStatus.Status = status;
    IoCompleteRequest(irp, IO_NO_INCREMENT);

    return status;
}