Esempio n. 1
0
static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
{
    struct instance *o = vo;
    o->i = i;
    
    // check arguments
    NCDValRef type_arg;
    NCDValRef name_arg;
    if (!NCDVal_ListRead(params->args, 2, &type_arg, &name_arg)) {
        ModuleLog(o->i, BLOG_ERROR, "wrong arity");
        goto fail0;
    }
    if (!NCDVal_IsString(type_arg) || !NCDVal_IsStringNoNulls(name_arg)) {
        ModuleLog(o->i, BLOG_ERROR, "wrong type");
        goto fail0;
    }
    
    // null terminate name
    NCDValNullTermString name_nts;
    if (!NCDVal_StringNullTerminate(name_arg, &name_nts)) {
        ModuleLog(o->i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
        goto fail0;
    }
    
    if (NCDVal_StringEquals(type_arg, "index")) {
        if (sscanf(name_nts.data, "%"SCNu32, &o->index) != 1) {
            ModuleLog(o->i, BLOG_ERROR, "wrong index argument");
            goto fail1;
        }
    }
    else if (NCDVal_StringEquals(type_arg, "wlan")) {
        if (!find_wlan_rfill(name_nts.data, &o->index)) {
            ModuleLog(o->i, BLOG_ERROR, "failed to find rfkill for wlan interface");
            goto fail1;
        }
    }
    else {
        ModuleLog(o->i, BLOG_ERROR, "unknown type argument");
        goto fail1;
    }
    
    // init monitor
    if (!NCDRfkillMonitor_Init(&o->monitor, o->i->params->iparams->reactor, (NCDRfkillMonitor_handler)monitor_handler, o)) {
        ModuleLog(o->i, BLOG_ERROR, "monitor failed");
        goto fail1;
    }
    
    // set not up
    o->up = 0;
    
    // free name nts
    NCDValNullTermString_Free(&name_nts);
    return;
    
fail1:
    NCDValNullTermString_Free(&name_nts);
fail0:
    NCDModuleInst_Backend_DeadError(i);
}
Esempio n. 2
0
static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
{
    struct instance *o = vo;
    o->i = i;
    
    // read arguments
    NCDValRef ifname_arg;
    NCDValRef addr_arg;
    NCDValRef prefix_arg = NCDVal_NewInvalid();
    if (!NCDVal_ListRead(params->args, 2, &ifname_arg, &addr_arg) &&
        !NCDVal_ListRead(params->args, 3, &ifname_arg, &addr_arg, &prefix_arg)
    ) {
        ModuleLog(o->i, BLOG_ERROR, "wrong arity");
        goto fail0;
    }
    if (!NCDVal_IsStringNoNulls(ifname_arg) || !NCDVal_IsString(addr_arg) ||
        (!NCDVal_IsInvalid(prefix_arg) && !NCDVal_IsString(prefix_arg))
    ) {
        ModuleLog(o->i, BLOG_ERROR, "wrong type");
        goto fail0;
    }
    
    // null terminate ifname
    if (!NCDVal_StringNullTerminate(ifname_arg, &o->ifname_nts)) {
        ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
        goto fail0;
    }
    
    if (NCDVal_IsInvalid(prefix_arg)) {
        if (!ipaddr_parse_ipv4_ifaddr(NCDVal_StringMemRef(addr_arg), &o->ifaddr)) {
            ModuleLog(o->i, BLOG_ERROR, "wrong CIDR notation address");
            goto fail1;
        }
    } else {
        if (!ipaddr_parse_ipv4_addr(NCDVal_StringMemRef(addr_arg), &o->ifaddr.addr)) {
            ModuleLog(o->i, BLOG_ERROR, "wrong address");
            goto fail1;
        }
        
        if (!ipaddr_parse_ipv4_prefix(NCDVal_StringMemRef(prefix_arg), &o->ifaddr.prefix)) {
            ModuleLog(o->i, BLOG_ERROR, "wrong prefix");
            goto fail1;
        }
    }
    
    // add address
    if (!NCDIfConfig_add_ipv4_addr(o->ifname_nts.data, o->ifaddr)) {
        ModuleLog(o->i, BLOG_ERROR, "failed to add IP address");
        goto fail1;
    }
    
    // signal up
    NCDModuleInst_Backend_Up(o->i);
    return;
    
fail1:
    NCDValNullTermString_Free(&o->ifname_nts);
fail0:
    NCDModuleInst_Backend_DeadError(i);
}
Esempio n. 3
0
static void func_die (void *vo)
{
    struct instance *o = vo;
    
    // remove route
    int res = 0; // to remove warning
    switch (o->type) {
        case TYPE_NORMAL:
            res = NCDIfConfig_remove_ipv6_route(o->dest, &o->gateway, o->metric, o->ifname_nts.data);
            break;
        case TYPE_IFONLY:
            res = NCDIfConfig_remove_ipv6_route(o->dest, NULL, o->metric, o->ifname_nts.data);
            break;
        case TYPE_BLACKHOLE:
            res = NCDIfConfig_remove_ipv6_blackhole_route(o->dest, o->metric);
            break;
        default: ASSERT(0);
    }
    if (!res) {
        ModuleLog(o->i, BLOG_ERROR, "failed to remove route");
    }
    
    // free ifname nts
    NCDValNullTermString_Free(&o->ifname_nts);
    
    NCDModuleInst_Backend_Dead(o->i);
}
Esempio n. 4
0
static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
{
    struct instance *o = vo;
    o->i = i;
    
    // read arguments
    NCDValRef input_arg;
    NCDValRef regex_arg;
    if (!NCDVal_ListRead(params->args, 2, &input_arg, &regex_arg)) {
        ModuleLog(o->i, BLOG_ERROR, "wrong arity");
        goto fail0;
    }
    if (!NCDVal_IsString(input_arg) || !NCDVal_IsStringNoNulls(regex_arg)) {
        ModuleLog(o->i, BLOG_ERROR, "wrong type");
        goto fail0;
    }
    o->input = NCDVal_StringMemRef(input_arg);
    
    // make sure we don't overflow regoff_t
    if (o->input.len > INT_MAX) {
        ModuleLog(o->i, BLOG_ERROR, "input string too long");
        goto fail0;
    }
    
    // null terminate regex
    NCDValNullTermString regex_nts;
    if (!NCDVal_StringNullTerminate(regex_arg, &regex_nts)) {
        ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
        goto fail0;
    }
    
    // compile regex
    regex_t preg;
    int ret = regcomp(&preg, regex_nts.data, REG_EXTENDED);
    NCDValNullTermString_Free(&regex_nts);
    if (ret != 0) {
        ModuleLog(o->i, BLOG_ERROR, "regcomp failed (error=%d)", ret);
        goto fail0;
    }
    
    // execute match
    o->matches[0].rm_so = 0;
    o->matches[0].rm_eo = o->input.len;
    o->succeeded = (regexec(&preg, o->input.ptr, MAX_MATCHES, o->matches, REG_STARTEND) == 0);
    
    // free regex
    regfree(&preg);
    
    // signal up
    NCDModuleInst_Backend_Up(o->i);
    return;
    
fail0:
    NCDModuleInst_Backend_DeadError(i);
}
Esempio n. 5
0
static void func_die (void *vo)
{
    struct instance *o = vo;
    
    // remove address
    if (!NCDIfConfig_remove_ipv4_addr(o->ifname_nts.data, o->ifaddr)) {
        ModuleLog(o->i, BLOG_ERROR, "failed to remove IP address");
    }
    
    // free ifname nts
    NCDValNullTermString_Free(&o->ifname_nts);
    
    NCDModuleInst_Backend_Dead(o->i);
}
Esempio n. 6
0
static void stat_func_new_common (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, int is_lstat)
{
    struct stat_instance *o = vo;
    o->i = i;
    
    NCDValRef filename_arg;
    if (!NCDVal_ListRead(params->args, 1, &filename_arg)) {
        ModuleLog(i, BLOG_ERROR, "wrong arity");
        goto fail0;
    }
    if (!NCDVal_IsString(filename_arg)) {
        ModuleLog(i, BLOG_ERROR, "wrong type");
        goto fail0;
    }
    
    o->succeeded = 0;
    
    if (!NCDVal_IsStringNoNulls(filename_arg)) {
        goto out;
    }
    
    // null terminate filename
    NCDValNullTermString filename_nts;
    if (!NCDVal_StringNullTerminate(filename_arg, &filename_nts)) {
        ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
        goto fail0;
    }
    
    int res;
    if (is_lstat) {
        res = lstat(filename_nts.data, &o->result);
    } else {
        res = stat(filename_nts.data, &o->result);
    }
    NCDValNullTermString_Free(&filename_nts);
    
    if (res < 0) {
        goto out;
    }
    
    o->succeeded = 1;
    
out:
    NCDModuleInst_Backend_Up(i);
    return;
    
fail0:
    NCDModuleInst_Backend_DeadError(i);
}
Esempio n. 7
0
static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
{
    struct instance *o = vo;
    o->i = i;
    
    // read arguments
    NCDValRef arg_ifname;
    NCDValRef arg_addr;
    if (!NCDVal_ListRead(params->args, 2, &arg_ifname, &arg_addr)) {
        ModuleLog(o->i, BLOG_ERROR, "wrong arity");
        goto fail0;
    }
    if (!NCDVal_IsStringNoNulls(arg_ifname) || !NCDVal_IsString(arg_addr)) {
        ModuleLog(o->i, BLOG_ERROR, "wrong type");
        goto fail0;
    }
    
    // parse address
    uint32_t addr;
    if (!ipaddr_parse_ipv4_addr_bin(NCDVal_StringData(arg_addr), NCDVal_StringLength(arg_addr), &addr)) {
        ModuleLog(o->i, BLOG_ERROR, "wrong address");
        goto fail0;
    }
    
    // null terminate ifname
    NCDValNullTermString ifname_nts;
    if (!NCDVal_StringNullTerminate(arg_ifname, &ifname_nts)) {
        ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
        goto fail0;
    }
    
    // init arpprobe
    int res = BArpProbe_Init(&o->arpprobe, ifname_nts.data, addr, i->params->iparams->reactor, o, (BArpProbe_handler)arpprobe_handler);
    NCDValNullTermString_Free(&ifname_nts);
    if (!res) {
        ModuleLog(o->i, BLOG_ERROR, "BArpProbe_Init failed");
        goto fail0;
    }
    
    // set state unknown
    o->state = STATE_UNKNOWN;
    return;
    
fail0:
    NCDModuleInst_Backend_DeadError(i);
}
Esempio n. 8
0
static void read_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
{
    struct read_instance *o = vo;
    o->i = i;
    
    // read arguments
    NCDValRef filename_arg;
    if (!NCDVal_ListRead(params->args, 1, &filename_arg)) {
        ModuleLog(i, BLOG_ERROR, "wrong arity");
        goto fail0;
    }
    if (!NCDVal_IsStringNoNulls(filename_arg)) {
        ModuleLog(i, BLOG_ERROR, "wrong type");
        goto fail0;
    }
    
    // get null terminated name
    NCDValNullTermString filename_nts;
    if (!NCDVal_StringNullTerminate(filename_arg, &filename_nts)) {
        ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
        goto fail0;
    }
    
    // read file
    int res = read_file(filename_nts.data, &o->file_data, &o->file_len);
    NCDValNullTermString_Free(&filename_nts);
    if (!res) {
        ModuleLog(i, BLOG_ERROR, "failed to read file");
        goto fail0;
    }
    
    // signal up
    NCDModuleInst_Backend_Up(i);
    return;
    
fail0:
    NCDModuleInst_Backend_DeadError(i);
}
Esempio n. 9
0
static void write_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
{
    // read arguments
    NCDValRef filename_arg;
    NCDValRef contents_arg;
    if (!NCDVal_ListRead(params->args, 2, &filename_arg, &contents_arg)) {
        ModuleLog(i, BLOG_ERROR, "wrong arity");
        goto fail0;
    }
    if (!NCDVal_IsStringNoNulls(filename_arg) || !NCDVal_IsString(contents_arg)) {
        ModuleLog(i, BLOG_ERROR, "wrong type");
        goto fail0;
    }
    
    // get null terminated name
    NCDValNullTermString filename_nts;
    if (!NCDVal_StringNullTerminate(filename_arg, &filename_nts)) {
        ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
        goto fail0;
    }
    
    // write file
    int res = write_file(filename_nts.data, NCDVal_StringMemRef(contents_arg));
    NCDValNullTermString_Free(&filename_nts);
    if (!res) {
        ModuleLog(i, BLOG_ERROR, "failed to write file");
        goto fail0;
    }
    
    // signal up
    NCDModuleInst_Backend_Up(i);
    return;
    
fail0:
    NCDModuleInst_Backend_DeadError(i);
}
Esempio n. 10
0
static void replace_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
{
    struct replace_instance *o = vo;
    o->i = i;
    
    // read arguments
    NCDValRef input_arg;
    NCDValRef regex_arg;
    NCDValRef replace_arg;
    if (!NCDVal_ListRead(params->args, 3, &input_arg, &regex_arg, &replace_arg)) {
        ModuleLog(i, BLOG_ERROR, "wrong arity");
        goto fail1;
    }
    if (!NCDVal_IsString(input_arg) || !NCDVal_IsList(regex_arg) || !NCDVal_IsList(replace_arg)) {
        ModuleLog(i, BLOG_ERROR, "wrong type");
        goto fail1;
    }
    
    // check number of regex/replace
    if (NCDVal_ListCount(regex_arg) != NCDVal_ListCount(replace_arg)) {
        ModuleLog(i, BLOG_ERROR, "number of regex's is not the same as number of replacements");
        goto fail1;
    }
    size_t num_regex = NCDVal_ListCount(regex_arg);
    
    // allocate array for compiled regex's
    regex_t *regs = BAllocArray(num_regex, sizeof(regs[0]));
    if (!regs) {
        ModuleLog(i, BLOG_ERROR, "BAllocArray failed");
        goto fail1;
    }
    size_t num_done_regex = 0;
    
    // compile regex's, check arguments
    while (num_done_regex < num_regex) {
        NCDValRef regex = NCDVal_ListGet(regex_arg, num_done_regex);
        NCDValRef replace = NCDVal_ListGet(replace_arg, num_done_regex);
        
        if (!NCDVal_IsStringNoNulls(regex) || !NCDVal_IsString(replace)) {
            ModuleLog(i, BLOG_ERROR, "wrong regex/replace type for pair %zu", num_done_regex);
            goto fail2;
        }
        
        // null terminate regex
        NCDValNullTermString regex_nts;
        if (!NCDVal_StringNullTerminate(regex, &regex_nts)) {
            ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
            goto fail2;
        }
        
        int res = regcomp(&regs[num_done_regex], regex_nts.data, REG_EXTENDED);
        NCDValNullTermString_Free(&regex_nts);
        if (res != 0) {
            ModuleLog(i, BLOG_ERROR, "regcomp failed for pair %zu (error=%d)", num_done_regex, res);
            goto fail2;
        }
        
        num_done_regex++;
    }
    
    // init output string
    ExpString out;
    if (!ExpString_Init(&out)) {
        ModuleLog(i, BLOG_ERROR, "ExpString_Init failed");
        goto fail2;
    }
    
    // input state
    MemRef in = NCDVal_StringMemRef(input_arg);
    size_t in_pos = 0;
    
    // process input
    while (in_pos < in.len) {
        // find first match
        int have_match = 0;
        size_t match_regex = 0; // to remove warning
        regmatch_t match = {0, 0}; // to remove warning
        for (size_t j = 0; j < num_regex; j++) {
            regmatch_t this_match;
            this_match.rm_so = 0;
            this_match.rm_eo = in.len - in_pos;
            if (regexec(&regs[j], in.ptr + in_pos, 1, &this_match, REG_STARTEND) == 0 && (!have_match || this_match.rm_so < match.rm_so)) {
                have_match = 1;
                match_regex = j;
                match = this_match;
            }
        }
        
        // if no match, append remaining data and finish
        if (!have_match) {
            if (!ExpString_AppendBinaryMr(&out, MemRef_SubFrom(in, in_pos))) {
                ModuleLog(i, BLOG_ERROR, "ExpString_AppendBinaryMr failed");
                goto fail3;
            }
            break;
        }
        
        // append data before match
        if (!ExpString_AppendBinaryMr(&out, MemRef_Sub(in, in_pos, match.rm_so))) {
            ModuleLog(i, BLOG_ERROR, "ExpString_AppendBinaryMr failed");
            goto fail3;
        }
        
        // append replacement data
        NCDValRef replace = NCDVal_ListGet(replace_arg, match_regex);
        if (!ExpString_AppendBinaryMr(&out, NCDVal_StringMemRef(replace))) {
            ModuleLog(i, BLOG_ERROR, "ExpString_AppendBinaryMr failed");
            goto fail3;
        }
        
        in_pos += match.rm_eo;
    }
    
    // set output
    o->output = ExpString_GetMr(&out);
    
    // free compiled regex's
    while (num_done_regex-- > 0) {
        regfree(&regs[num_done_regex]);
    }
    
    // free array
    BFree(regs);
    
    // signal up
    NCDModuleInst_Backend_Up(i);
    return;
    
fail3:
    ExpString_Free(&out);
fail2:
    while (num_done_regex-- > 0) {
        regfree(&regs[num_done_regex]);
    }
    BFree(regs);
fail1:
    NCDModuleInst_Backend_DeadError(i);
}
Esempio n. 11
0
static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
{
    struct instance *o = vo;
    o->i = i;
    
    // check arguments
    NCDValRef ifname_arg;
    NCDValRef opts_arg = NCDVal_NewInvalid();
    if (!NCDVal_ListRead(params->args, 1, &ifname_arg) && !NCDVal_ListRead(params->args, 2, &ifname_arg, &opts_arg)) {
        ModuleLog(o->i, BLOG_ERROR, "wrong arity");
        goto fail0;
    }
    if (!NCDVal_IsStringNoNulls(ifname_arg) || (!NCDVal_IsInvalid(opts_arg) && !NCDVal_IsList(opts_arg))) {
        ModuleLog(o->i, BLOG_ERROR, "wrong type");
        goto fail0;
    }
    
    NCDValNullTermString hostname_nts = NCDValNullTermString_NewDummy();
    NCDValNullTermString vendorclassid_nts = NCDValNullTermString_NewDummy();
    
    struct BDHCPClient_opts opts = {};
    
    // read options
    size_t count = NCDVal_IsInvalid(opts_arg) ? 0 : NCDVal_ListCount(opts_arg);
    for (size_t j = 0; j < count; j++) {
        NCDValRef opt = NCDVal_ListGet(opts_arg, j);
        
        // read name
        if (!NCDVal_IsString(opt)) {
            ModuleLog(o->i, BLOG_ERROR, "wrong option name type");
            goto fail1;
        }
        
        if (NCDVal_StringEquals(opt, "hostname") || NCDVal_StringEquals(opt, "vendorclassid")) {
            int is_hostname = NCDVal_StringEquals(opt, "hostname");
            
            // read value
            if (j == count) {
                ModuleLog(o->i, BLOG_ERROR, "option value missing");
                goto fail1;
            }
            NCDValRef val = NCDVal_ListGet(opts_arg, j + 1);
            if (!NCDVal_IsStringNoNulls(val)) {
                ModuleLog(o->i, BLOG_ERROR, "wrong option value type");
                goto fail1;
            }
            
            // null terminate
            NCDValNullTermString nts;
            if (!NCDVal_StringNullTerminate(val, &nts)) {
                ModuleLog(o->i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
                goto fail1;
            }
            NCDValNullTermString *nts_ptr = (is_hostname ? &hostname_nts : &vendorclassid_nts);
            NCDValNullTermString_Free(nts_ptr);
            *nts_ptr = nts;
            
            if (is_hostname) {
                opts.hostname = nts.data;
            } else {
                opts.vendorclassid = nts.data;
            }
            
            j++;
        }
        else if (NCDVal_StringEquals(opt, "auto_clientid")) {
            opts.auto_clientid = 1;
        }
        else {
            ModuleLog(o->i, BLOG_ERROR, "unknown option name");
            goto fail1;
        }
    }
    
    // null terminate ifname
    NCDValNullTermString ifname_nts;
    if (!NCDVal_StringNullTerminate(ifname_arg, &ifname_nts)) {
        ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
        goto fail1;
    }
    
    // init DHCP
    int res = BDHCPClient_Init(&o->dhcp, ifname_nts.data, opts, o->i->params->iparams->reactor, o->i->params->iparams->random2, (BDHCPClient_handler)dhcp_handler, o);
    NCDValNullTermString_Free(&ifname_nts);
    if (!res) {
        ModuleLog(o->i, BLOG_ERROR, "BDHCPClient_Init failed");
        goto fail1;
    }
    
    // set not up
    o->up = 0;
    
    // free options nts's
    NCDValNullTermString_Free(&hostname_nts);
    NCDValNullTermString_Free(&vendorclassid_nts);
    return;
    
fail1:
    NCDValNullTermString_Free(&hostname_nts);
    NCDValNullTermString_Free(&vendorclassid_nts);
fail0:
    NCDModuleInst_Backend_DeadError(i);
}
Esempio n. 12
0
static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
{
    struct instance *o = vo;
    o->i = i;
    
    // read arguments
    NCDValRef dest_arg;
    NCDValRef dest_prefix_arg = NCDVal_NewInvalid();
    NCDValRef gateway_arg;
    NCDValRef metric_arg;
    NCDValRef ifname_arg;
    if (!NCDVal_ListRead(params->args, 4, &dest_arg, &gateway_arg, &metric_arg, &ifname_arg) &&
        !NCDVal_ListRead(params->args, 5, &dest_arg, &dest_prefix_arg, &gateway_arg, &metric_arg, &ifname_arg)
    ) {
        ModuleLog(o->i, BLOG_ERROR, "wrong arity");
        goto fail0;
    }
    if (!NCDVal_IsString(dest_arg) || !NCDVal_IsString(gateway_arg) ||
        !NCDVal_IsStringNoNulls(ifname_arg) ||
        (!NCDVal_IsInvalid(dest_prefix_arg) && !NCDVal_IsString(dest_prefix_arg))
    ) {
        ModuleLog(o->i, BLOG_ERROR, "wrong type");
        goto fail0;
    }
    
    // read dest
    if (NCDVal_IsInvalid(dest_prefix_arg)) {
        if (!ipaddr6_parse_ipv6_ifaddr_bin(NCDVal_StringData(dest_arg), NCDVal_StringLength(dest_arg), &o->dest)) {
            ModuleLog(o->i, BLOG_ERROR, "wrong CIDR notation dest");
            goto fail0;
        }
    } else {
        if (!ipaddr6_parse_ipv6_addr_bin(NCDVal_StringData(dest_arg), NCDVal_StringLength(dest_arg), &o->dest.addr)) {
            ModuleLog(o->i, BLOG_ERROR, "wrong dest addr");
            goto fail0;
        }
        if (!ipaddr6_parse_ipv6_prefix_bin(NCDVal_StringData(dest_prefix_arg), NCDVal_StringLength(dest_prefix_arg), &o->dest.prefix)) {
            ModuleLog(o->i, BLOG_ERROR, "wrong dest prefix");
            goto fail0;
        }
    }
    
    // read gateway and choose type
    if (NCDVal_StringEquals(gateway_arg, "none")) {
        o->type = TYPE_IFONLY;
    }
    else if (NCDVal_StringEquals(gateway_arg, "blackhole")) {
        o->type = TYPE_BLACKHOLE;
    } else {
        if (!ipaddr6_parse_ipv6_addr_bin(NCDVal_StringData(gateway_arg), NCDVal_StringLength(gateway_arg), &o->gateway)) {
            ModuleLog(o->i, BLOG_ERROR, "wrong gateway");
            goto fail0;
        }
        o->type = TYPE_NORMAL;
    }
    
    // read metric
    uintmax_t metric;
    if (!ncd_read_uintmax(metric_arg, &metric) || metric > INT_MAX) {
        ModuleLog(i, BLOG_ERROR, "bad metric");
        goto fail0;
    }
    o->metric = metric;
    
    // null terminate ifname
    if (!NCDVal_StringNullTerminate(ifname_arg, &o->ifname_nts)) {
        ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
        goto fail0;
    }
    
    // add route
    int res = 0; // to remove warning
    switch (o->type) {
        case TYPE_NORMAL:
            res = NCDIfConfig_add_ipv6_route(o->dest, &o->gateway, o->metric, o->ifname_nts.data);
            break;
        case TYPE_IFONLY:
            res = NCDIfConfig_add_ipv6_route(o->dest, NULL, o->metric, o->ifname_nts.data);
            break;
        case TYPE_BLACKHOLE:
            res = NCDIfConfig_add_ipv6_blackhole_route(o->dest, o->metric);
            break;
        default: ASSERT(0);
    }
    if (!res) {
        ModuleLog(o->i, BLOG_ERROR, "failed to add route");
        goto fail1;
    }
    
    // signal up
    NCDModuleInst_Backend_Up(o->i);
    return;
    
fail1:
    NCDValNullTermString_Free(&o->ifname_nts);
fail0:
    NCDModuleInst_Backend_DeadError(i);
}
Esempio n. 13
0
static void func_new_resolvconf (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
{
    struct global *g = ModuleGlobal(i);
    struct instance *o = vo;
    o->i = i;
    
    // init servers list
    LinkedList1_Init(&o->entries);
    
    // get arguments
    NCDValRef lines_arg;
    NCDValRef priority_arg;
    if (!NCDVal_ListRead(params->args, 2, &lines_arg, &priority_arg)) {
        ModuleLog(o->i, BLOG_ERROR, "wrong arity");
        goto fail1;
    }
    if (!NCDVal_IsList(lines_arg) || !NCDVal_IsString(priority_arg)) {
        ModuleLog(o->i, BLOG_ERROR, "wrong type");
        goto fail1;
    }
    
    uintmax_t priority;
    if (!ncd_read_uintmax(priority_arg, &priority) || priority > INT_MAX) {
        ModuleLog(o->i, BLOG_ERROR, "wrong priority");
        goto fail1;
    }
    
    // read lines
    size_t count = NCDVal_ListCount(lines_arg);
    for (size_t j = 0; j < count; j++) {
        int loop_failed = 1;
        
        NCDValRef line = NCDVal_ListGet(lines_arg, j);
        if (!NCDVal_IsList(line) || NCDVal_ListCount(line) != 2) {
            ModuleLog(o->i, BLOG_ERROR, "lines element is not a list with two elements");
            goto loop_fail0;
        }
        
        NCDValRef type = NCDVal_ListGet(line, 0);
        NCDValRef value = NCDVal_ListGet(line, 1);
        if (!NCDVal_IsStringNoNulls(type) || !NCDVal_IsStringNoNulls(value)) {
            ModuleLog(o->i, BLOG_ERROR, "wrong type of type or value");
            goto loop_fail0;
        }
        
        NCDValNullTermString type_nts;
        if (!NCDVal_StringNullTerminate(type, &type_nts)) {
            ModuleLog(o->i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
            goto loop_fail0;
        }
        
        NCDValNullTermString value_nts;
        if (!NCDVal_StringNullTerminate(value, &value_nts)) {
            ModuleLog(o->i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
            goto loop_fail1;
        }
        
        if (!add_dns_entry(o, type_nts.data, value_nts.data, priority)) {
            ModuleLog(o->i, BLOG_ERROR, "failed to add dns entry");
            goto loop_fail2;
        }
        
        loop_failed = 0;
    loop_fail2:
        NCDValNullTermString_Free(&value_nts);
    loop_fail1:
        NCDValNullTermString_Free(&type_nts);
    loop_fail0:
        if (loop_failed) {
            goto fail1;
        }
    }
    
    // add to instances
    LinkedList1_Append(&g->instances, &o->instances_node);
    
    // set servers
    if (!set_servers(g)) {
        ModuleLog(o->i, BLOG_ERROR, "failed to set DNS servers");
        goto fail2;
    }
    
    // signal up
    NCDModuleInst_Backend_Up(o->i);
    return;
    
fail2:
    LinkedList1_Remove(&g->instances, &o->instances_node);
fail1:
    remove_entries(o);
    NCDModuleInst_Backend_DeadError(i);
}