int
ip_selector_db_lookup(
        struct IPSelectorDb *db,
        int part,
        const struct IPSelectorFields *fields)
{
  struct IPSelectorDbEntry *entry = db->heads[part];
  int action = -1;

  DEBUG_LOW(
          lookup,
          "Fields %p: Lookup db part %d: %s",
          fields,
          part,
          debug_str_ip_selector_fields(
                  DEBUG_STRBUF_GET(),
                  fields,
                  sizeof *fields));

  if (entry == NULL)
    {
      DEBUG_LOW(
              lookup,
              "Fields %p: Lookup db part %d: no entries; no match",
              fields,
              part);
    }

  while (entry != NULL)
    {
      struct IPSelectorGroup *selector_group = (void *)(entry + 1);

      if (ip_selector_match_fields_to_group(selector_group, fields))
        {
          action = entry->action;

          DEBUG_LOW(lookup, "Fields %p matched entry %p.", fields, entry);
          break;
        }

      entry = entry->next;
    }

  DEBUG_LOW(lookup, "Fields %p action is %d.", fields, action);

  return action;
}
示例#2
0
文件: Delay.c 项目: ibanezjem/Project
void Debug_Output(U8 bCnt)
{ 
	DEBUG_HIGH();

	while(bCnt--)
	{
		DEBUG_LOW();
		DelayUs2x(1);
		DEBUG_HIGH();
	}
}
static ssize_t
spd_proc_write(
        struct file *file,
        const char __user *data,
        size_t data_len,
        loff_t *pos)
{
    size_t bytes_read = 0;

    DEBUG_LOW(proc, "Write of %d bytes.", (int) data_len);
    while (bytes_read < data_len)
    {
        struct KernelSpdCommand command;
        int status;

        if (data_len < sizeof command)
        {
            DEBUG_FAIL(
                    proc,
                    "Data length %d less than sizeof command %d bytes.",
                    (int) data_len,
                    (int) sizeof command);

            bytes_read = -EFAULT;
            break;
        }

        status = copy_from_user(&command, data, sizeof command);
        if (status != 0)
        {
            DEBUG_FAIL(proc, "Copy from user failed.");
            bytes_read = -EFAULT;
            break;
        }

        if (command.bytecount < sizeof command)
        {
            DEBUG_FAIL(
                    proc,
                    "Command bytecount %d less than command size %d.",
                    (int) command.bytecount,
                    (int) sizeof command);

            bytes_read = -EINVAL;
            break;
        }

        if (command.bytecount > KERNELSPD_PROCFS_COMMAND_BYTECOUNT_MAX)
        {
            DEBUG_FAIL(
                    proc,
                    "Command bytecount %d bigger than max command size %d.",
                    (int) command.bytecount,
                    (int) KERNELSPD_PROCFS_COMMAND_BYTECOUNT_MAX);

            bytes_read = -EINVAL;
            break;
        }

        if (command.bytecount > data_len - bytes_read)
        {
            DEBUG_FAIL(
                    proc,
                    "Command bytecount %d bigger than data_len %d.",
                    (int) command.bytecount,
                    (int) data_len);

            bytes_read = -EINVAL;
            break;
        }

        bytes_read += sizeof command;

        status =
            process_command(
                    &command,
                    data + bytes_read,
                    command.bytecount - sizeof command);

        if (status < 0)
        {
            bytes_read = status;
            break;
        }

        bytes_read += command.bytecount;
    }

    return bytes_read;
}
int
process_command(
        struct KernelSpdCommand *cmd,
        const char __user *cmd_data,
        size_t cmd_data_bytecount)

{
    int status = 0;

    DEBUG_LOW(proc, "Processing command id %d.", cmd->command_id);

    switch (cmd->command_id)
    {
    case KERNEL_SPD_ACTIVATE:
        {
            int ipsec_boundary_bytecount = cmd_data_bytecount;

            if (active != 0)
            {
                DEBUG_FAIL(def, "Kernel SPD already active.");
                status = -EFAULT;
            }
            else
            {
                status =
                    update_ipsec_boundary(
                            cmd_data,
                            ipsec_boundary_bytecount);

                if (status != 0)
                {
                    break;
                }

                if (spd_hooks_init() != 0)
                {
                    DEBUG_FAIL(proc, "Kernel SPD Failed activating NF Hooks.");
                    status = -EFAULT;
                }

                active = 1;

                DEBUG_HIGH(
                        kernel,
                        "Kernel SPD activated. IPsec boundary: '%s'.",
                        ipsec_boundary);
            }
        }
        break;

    case KERNEL_SPD_DEACTIVATE:
        {
            if (active == 0)
            {
                DEBUG_FAIL(proc, "Kernel SPD not active.");
            }
            else
            {
                DEBUG_HIGH(proc, "Kernel SPD deactivated.");
                spd_hooks_uninit();
                bypass_kuid = INVALID_UID;
            }

            active = 0;
        }
        break;

    case KERNEL_SPD_INSERT_ENTRY:
        {
            struct IPSelectorDbEntry *entry;
            const int payload_bytecount = cmd_data_bytecount;

            if (!KERNEL_SPD_ID_VALID(cmd->spd_id))
            {
                DEBUG_FAIL(
                        proc,
                        "Invalid SPD id %d.",
                        cmd->spd_id);

                status = -EFAULT;
                break;
            }

            entry = vmalloc(sizeof *entry + payload_bytecount);
            if (entry == NULL)
            {
                DEBUG_FAIL(
                        proc,
                        "vmalloc(%d) failed.",
                        (int) (sizeof *entry + payload_bytecount));

                status = -EFAULT;
                break;
            }

            status = copy_from_user(entry + 1, cmd_data, payload_bytecount);
            if (status != 0)
            {
                DEBUG_FAIL(proc, "Copy from user failed.");

                vfree(entry);
                status = -EFAULT;
                break;
            }

            entry->action = cmd->action_id;
            entry->id = cmd->entry_id;
            entry->priority = cmd->priority;

            if (ip_selector_db_entry_check(
                        entry,
                        sizeof *entry + payload_bytecount)
                < 0)
            {
                DEBUG_FAIL(proc, "Selector check failed.");

                vfree(entry);
                status = -EFAULT;
                break;
            }

            DEBUG_DUMP(
                    proc,
                    debug_dump_ip_selector_group,
                    entry + 1,
                    payload_bytecount,
                    "Insert entry %d to spd "
                    "id %d action %d priority %d precedence %d:",
                    entry->id,
                    cmd->spd_id,
                    entry->action,
                    entry->priority,
                    cmd->precedence);

            write_lock_bh(&spd_lock);
            ip_selector_db_entry_add(
                    &spd,
                    cmd->spd_id,
                    entry,
                    cmd->precedence);
            write_unlock_bh(&spd_lock);
        }
        break;

    case KERNEL_SPD_REMOVE_ENTRY:

        if (!KERNEL_SPD_ID_VALID(cmd->spd_id))
        {
            DEBUG_FAIL(
                    proc,
                    "Invalid SPD id %d.",
                    cmd->spd_id);

            status = -EFAULT;
            break;
        }

        {
            struct IPSelectorDbEntry *removed;

            write_lock_bh(&spd_lock);
            removed =
                ip_selector_db_entry_remove(
                        &spd,
                        cmd->spd_id,
                        cmd->entry_id);

            write_unlock_bh(&spd_lock);

            if (removed != NULL)
            {
                DEBUG_DUMP(
                        proc,
                        debug_dump_ip_selector_group,
                        removed + 1,
                        -1,
                        "Removed entry %d to spd id %d action %d "
                        "priority %d:",
                        removed->id,
                        cmd->spd_id,
                        removed->action,
                        removed->priority);

                vfree(removed);
            }
            else
            {
                DEBUG_FAIL(
                        proc,
                        "Remove failed: Entry %d not found from spd id %d.",
                        cmd->entry_id,
                        cmd->spd_id);
            }
        }

        break;

    case KERNEL_SPD_UPDATE_IPSEC_BOUNDARY:
        {
            int new_ipsec_boundary_bytecount = cmd_data_bytecount;

            if (active == 0)
            {
                DEBUG_FAIL(def, "Kernel SPD is not active.");
                return -EFAULT;
            }

            status =
                update_ipsec_boundary(
                        cmd_data,
                        new_ipsec_boundary_bytecount);

            if (status != 0)
            {
                break;
            }

            DEBUG_HIGH(
                    kernel,
                    "IPsec boundary updated: '%s'.",
                    ipsec_boundary);
        }
        break;

    case KERNEL_SPD_VERSION_SYNC:
        {
            int version_bytecount = cmd_data_bytecount;
            uint32_t version;

            if (version_bytecount != sizeof version)
            {
                DEBUG_FAIL(
                        def,
                        "Invalid version size %d; should be %d.",
                        version_bytecount,
                        (int) sizeof version);
                return -EFAULT;
            }

            status =
                copy_from_user(
                        &version,
                        cmd_data,
                        sizeof version);
            if (status != 0)
            {
                DEBUG_FAIL(def, "Copy from user failed.");
                return -EFAULT;
            }

            if (version != KERNEL_SPD_VERSION)
            {
                DEBUG_FAIL(
                        def,
                        "Invalid version %d; should be %d.",
                        version,
                        KERNEL_SPD_VERSION);

                return -EINVAL;
            }

            DEBUG_HIGH(
                    kernel,
                    "Versions in sync: %d.",
                    version);
        }
        break;

    case KERNEL_SPD_ADD_BYPASS_UID:
        {
            uint32_t uid;

            if (active == 0)
            {
                DEBUG_FAIL(def, "Kernel SPD is not active.");
                return -EFAULT;
            }

            status =
                copy_from_user(
                        &uid,
                        cmd_data,
                        sizeof uid);
            if (status != 0)
            {
                DEBUG_FAIL(def, "Copy from user failed.");
                return -EFAULT;
            }

            write_lock_bh(&spd_lock);
            bypass_kuid = make_kuid(current_user_ns(), (uid_t) uid);
            write_unlock_bh(&spd_lock);

            DEBUG_HIGH(
                    kernel,
                    "Set bypass uid to %u.",
                    uid);
        }
        break;



    default:
        DEBUG_FAIL(proc, "Unknown command id %d.", cmd->command_id);
        break;
    }

    DEBUG_LOW(proc, "Returning %d", status);

    return status;
}