static PyObject * netcmp(PyObject *self, PyObject *args) { char *astr; char *bstr; struct addr a; struct addr b; int rval; int cmp = 0; struct intf_entry *entry = NULL; rval = PyArg_ParseTuple(args, "ss:netcmp", &astr, &bstr); if (!rval) return NULL; /* printf("Got addresses %s, %s\n", astr, bstr); */ rval = addr_pton(astr, &a); if (rval<0) myerror("Could not read first address"); rval = addr_pton(bstr, &b); if (rval<0) myerror("Could not read second address"); cmp = addr_cmp(&a, &b); return Py_BuildValue("i", cmp); }
int dht_group_test_init(void) { int i; /* Some simple debugging */ debug = 0; event_init(); dht_init(); addr_pton("127.0.0.1", &addr); /* Set up the nodes */ for (i = 0; i < GROUP_SIZE; ++i) { struct dht_node *dht = kad_make_dht(PORT_BASE + i); assert(dht != NULL); node[i] = dht_group_new(dht); dht_group_register_cb(node[i], receive_msg, NULL); assert(node[i] != NULL); } return 0; }
int addr_pton_cidr(const char* p, struct xaddr* n, int* l) { struct xaddr tmp; int masklen = -1; char addrbuf[64]; char* mp; char* cp; /* Don't modify argument */ if (p == NULL || strlcpy(addrbuf, p, sizeof(addrbuf)) >= sizeof(addrbuf)) return (-1); if ((mp = strchr(addrbuf, '/')) != NULL) { *mp = '\0'; mp++; masklen = (int) strtol(mp, &cp, 10); if (*mp == '\0' || *cp != '\0' || masklen > 128) return (-1); } if (addr_pton(addrbuf, &tmp) == -1) return (-1); if (mp == NULL) masklen = addr_unicast_masklen(tmp.af); if (addr_masklen_valid(tmp.af, masklen) == -1) return (-1); if (n != NULL) rte_memcpy(n, &tmp, sizeof(*n)); if (l != NULL) *l = masklen; return (0); }
in_addr_t anubis_lookup_ip_address(const char *expression) { //get param char *buffer = anubis_parse_param("lookup_ip_address", expression); if(!buffer) return 0; if(!strcasecmp(buffer, "ff:ff:ff:ff:ff:ff") || !strcasecmp(buffer, "Broadcast")) { return INADDR_BROADCAST; }//end if else { arp_t *handle = arp_open(); struct arp_entry arp_entry = {0}; if(!handle) { anubis_perror("arp_open()"); return 0; }//end if addr_pton(buffer, &arp_entry.arp_ha); int ret = arp_loop(handle, arp_lookup_ip_address_callback, (void *)&arp_entry); if(ret == 1) { char *ip_address = addr_ntoa(&arp_entry.arp_pa); arp_close(handle); return anubis_ip_aton(ip_address); }//end if else { anubis_err("lookup_ip_address(): \"%s\" is not found\n", buffer); arp_close(handle); return 0; }//end else }//end else }//end anubis_lookup_ip_address
/* * Match "addr" against list pattern list "_list", which may contain a * mix of CIDR addresses and old-school wildcards. * * If addr is NULL, then no matching is performed, but _list is parsed * and checked for well-formedness. * * Returns 1 on match found (never returned when addr == NULL). * Returns 0 on if no match found, or no errors found when addr == NULL. * Returns -1 on negated match found (never returned when addr == NULL). * Returns -2 on invalid list entry. */ int addr_match_list(const char *addr, const char *_list) { char *list, *cp, *o; struct xaddr try_addr, match_addr; u_int masklen, neg; int ret = 0, r; if (addr != NULL && addr_pton(addr, &try_addr) != 0) { debug2("%s: couldn't parse address %.100s", __func__, addr); return 0; } if ((o = list = strdup(_list)) == NULL) return -1; while ((cp = strsep(&list, ",")) != NULL) { neg = *cp == '!'; if (neg) cp++; if (*cp == '\0') { ret = -2; break; } /* Prefer CIDR address matching */ r = addr_pton_cidr(cp, &match_addr, &masklen); if (r == -2) { error("Inconsistent mask length for " "network \"%.100s\"", cp); ret = -2; break; } else if (r == 0) { if (addr != NULL && addr_netmatch(&try_addr, &match_addr, masklen) == 0) { foundit: if (neg) { ret = -1; break; } ret = 1; } continue; } else { /* If CIDR parse failed, try wildcard string match */ if (addr != NULL && match_pattern(addr, cp) == 1) goto foundit; } } free(o); return ret; }
static int conf_rpa_flush(struct ipc_user *u, char *data, size_t len, __unused struct blob_buf *reply) { conf conf = container_of(u, conf_s, ipc_users[CONF_IPC_RPA_FLUSH]); struct blob_attr *tb[CONF_RPA_MAX]; struct in6_addr rpa; if(blobmsg_parse(conf_rpa_attrs, CONF_RPA_MAX, tb, data, len) || !tb[CONF_RPA_RPA] || !addr_pton(&rpa, blobmsg_get_string(tb[CONF_RPA_RPA])) || tb[CONF_RPA_GROUPS] || tb[CONF_RPA_RPL_JP]) return -EINVAL; pim_rpa_update(conf->pim, &rpa); pim_rpa_flush(conf->pim, &rpa); return 0; }
/*- - network = net.pton(presentation) presentation is something like "df:33:44:12:45:54", or "1.2.3.4", or a host name return is the binary, network byte-ordered address (you have to know what kind it was!) */ static int lnet_pton(lua_State *L) { const char* src = luaL_checkstring(L, 1); struct addr dst; if(addr_pton(src, &dst) < 0) { return luaL_error(L, "pton failed on '%s'", src); } int size = dst.addr_bits; void* addr = &dst.__addr_u; lua_pushlstring(L, addr, size/8); return 1; }
static int conf_rpa_set(struct ipc_user *u, char *data, size_t len, __unused struct blob_buf *reply) { conf conf = container_of(u, conf_s, ipc_users[CONF_IPC_RPA_SET]); struct blob_attr *tb[CONF_RPA_MAX]; struct in6_addr rpa; if(blobmsg_parse(conf_rpa_attrs, CONF_RPA_MAX, tb, data, len) || !tb[CONF_RPA_RPA] || !addr_pton(&rpa, blobmsg_get_string(tb[CONF_RPA_RPA])) || tb[CONF_RPA_GROUPS]) return -1; if(tb[CONF_RPA_RPL_JP]) pim_rpa_set_rpl_jp(conf->pim, &rpa, blobmsg_get_u8(tb[CONF_RPA_RPL_JP])); return 0; }
int main(int argc, char* argv[]) { if (getuid() != 0) { printf("You need to be root\n"); return 1; } route_t* router = route_open(); struct route_entry entry; addr_pton("8.8.8.8", &entry.route_dst); route_get(router, &entry); printf("gateway is %s\n", addr_ntoa(&entry.route_gw)); route_close(router); return 0; }
static int conf_rpa_mod(conf conf, char *data, size_t len, __unused struct blob_buf *reply, bool del) { struct blob_attr *tb[CONF_RPA_MAX]; struct in6_addr rpa; struct in6_addr gr; uint8_t plen; if(blobmsg_parse(conf_rpa_attrs, CONF_RPA_MAX, tb, data, len) || !tb[CONF_RPA_RPA] || !addr_pton(&rpa, blobmsg_get_string(tb[CONF_RPA_RPA])) || !tb[CONF_RPA_GROUPS] || !prefix_pton(&gr, &plen, blobmsg_get_string(tb[CONF_RPA_GROUPS])) || !addr_is_multicast(&gr) || tb[CONF_RPA_RPL_JP]) return -EINVAL; if(del) pim_rpa_del(conf->pim, &rpa, &gr, plen); else pim_rpa_add(conf->pim, &rpa, &gr, plen); return 0; }
/* * Parse a CIDR address (x.x.x.x/y or xxxx:yyyy::/z). * Return -1 on parse error, -2 on inconsistency or 0 on success. */ static int addr_pton_cidr(const char *p, struct xaddr *n, u_int *l) { struct xaddr tmp; long unsigned int masklen = 999; char addrbuf[64], *mp, *cp; /* Don't modify argument */ if (p == NULL || strlcpy(addrbuf, p, sizeof(addrbuf)) > sizeof(addrbuf)) return -1; if ((mp = strchr(addrbuf, '/')) != NULL) { *mp = '\0'; mp++; masklen = strtoul(mp, &cp, 10); if (*mp == '\0' || *cp != '\0' || masklen > 128) return -1; } if (addr_pton(addrbuf, &tmp) == -1) return -1; if (mp == NULL) masklen = addr_unicast_masklen(tmp.af); if (masklen_valid(tmp.af, masklen) == -1) return -2; if (addr_host_is_all0s(&tmp, masklen) != 0) return -2; if (n != NULL) memcpy(n, &tmp, sizeof(*n)); if (l != NULL) *l = masklen; return 0; }
static int conf_proxy_mod(conf conf, char *data, size_t len, __unused struct blob_buf *reply, bool del) { struct blob_attr* tb[CONF_PROXY_MAX]; int iport; const char* saddr; struct in6_addr addr; if (blobmsg_parse(conf_proxy_attrs, CONF_PROXY_MAX, tb, data, len)) return -1; if(!tb[CONF_PROXY_ADDR] || !tb[CONF_PROXY_PORT] || !(saddr = blobmsg_get_string(tb[CONF_PROXY_ADDR])) || !(iport = blobmsg_get_u32(tb[CONF_PROXY_PORT]))) return -EINVAL; if(!(addr_pton(&addr, saddr)) || iport >= 65535 || iport <= 0) return -EINVAL; if(del) { pim_ctl_del_proxy(conf->pim, &addr, (in_port_t) iport); } else { pim_ctl_add_proxy(conf->pim, &addr, (in_port_t) iport); } return 0; }
static char * arpd_expandips(int naddresses, char **addresses) { static char filter[1024]; char line[1024], *p; struct addr dst; if (naddresses == 0) return (NULL); filter[0] = '\0'; while (naddresses--) { /* Get current address */ p = *addresses++; if (filter[0] != '\0') { if (strlcat(filter, " or ", sizeof(filter)) >= sizeof(filter)) errx(1, "%s: too many address for filter", __func__); } if (addr_pton(p, &dst) != -1) { snprintf(line, sizeof(line), "dst %s%s", dst.addr_bits != 32 ? "net ": "", p); } else { char *first, *second; struct addr astart, aend; struct in_addr in; ip_addr_t istart, iend; second = p; first = strsep(&second, "-"); if (second == NULL) errx(1, "%s: Invalid network range: %s", __func__, p); line[0] = '\0'; if (addr_pton(first, &astart) == -1 || addr_pton(second, &aend) == -1) errx(1, "%s: bad addresses %s-%s", __func__, first, second); #ifdef HAVE_BROKEN_DNET if (addr_cmp(&astart, &aend) <= 0) #else if (addr_cmp(&astart, &aend) >= 0) #endif errx(1, "%s: inverted range %s-%s", __func__, first, second); /* Completely, IPv4 specific */ istart = ntohl(astart.addr_ip); iend = ntohl(aend.addr_ip); while (istart <= iend) { char single[32]; int count = 0, done = 0; ip_addr_t tmp; do { ip_addr_t bit = 1 << count; ip_addr_t mask; mask = ~(~0 << count); tmp = istart | mask; if (istart & bit) done = 1; if (iend < tmp) { count--; mask = ~(~0 << count); tmp = istart | mask; break; } else if (done) break; count++; } while (count < IP_ADDR_BITS); if (line[0] != '\0') strlcat(line, " or ", sizeof(line)); in.s_addr = htonl(istart); snprintf(single, sizeof(single), "dst net %s/%d", inet_ntoa(in), 32 - count); strlcat(line, single, sizeof(line)); istart = tmp + 1; } } if (strlcat(filter, line, sizeof(filter)) >= sizeof(filter)) errx(1, "%s: too many address for filter", __func__); } return (filter); }
int intf_main(int argc, char *argv[]) { struct intf_entry *entry; struct addr *ap, addr; char *cmd, buf[1024]; if (argc < 2) usage(); cmd = argv[1]; entry = (struct intf_entry *)buf; memset(entry, 0, sizeof(*entry)); entry->intf_len = sizeof(buf); if ((intf = intf_open()) == NULL) err(1, "intf_open"); if (strcmp(cmd, "show") == 0) { if (intf_loop(intf, print_intf, NULL) < 0) err(1, "intf_loop"); } else if (strcmp(cmd, "get") == 0) { if (argc < 3) usage(); strlcpy(entry->intf_name, argv[2], sizeof(entry->intf_name)); if (intf_get(intf, entry) < 0) err(1, "intf_get"); print_intf(entry, NULL); } else if (strcmp(cmd, "src") == 0) { if (argc < 3 || addr_aton(argv[2], &addr) < 0) usage(); if (intf_get_src(intf, entry, &addr) < 0) err(1, "intf_get_src"); print_intf(entry, NULL); } else if (strcmp(cmd, "dst") == 0) { if (argc < 3 || addr_aton(argv[2], &addr) < 0) usage(); if (intf_get_dst(intf, entry, &addr) < 0) err(1, "intf_get_dst"); print_intf(entry, NULL); } else if (strcmp(cmd, "set") == 0) { if (argc < 4) usage(); strlcpy(entry->intf_name, argv[2], sizeof(entry->intf_name)); for (argv += 3, argc -= 3; argc > 1; argv += 2, argc -= 2) { if (strcmp(argv[0], "alias") == 0) { ap = &entry->intf_alias_addrs [entry->intf_alias_num++]; } else if (strcmp(argv[0], "dst") == 0) { ap = &entry->intf_dst_addr; } else if (strcmp(argv[0], "inet") == 0) { ap = &entry->intf_addr; } else if (strcmp(argv[0], "link") == 0) { ap = &entry->intf_link_addr; } else break; if (addr_pton(argv[1], ap) < 0) err(1, "invalid address: %s", argv[1]); } for ( ; argc > 0; argv++, argc--) { if (strcmp(argv[0], "up") == 0) entry->intf_flags |= INTF_FLAG_UP; else if (strcmp(argv[0], "down") == 0) entry->intf_flags &= ~INTF_FLAG_UP; else if (strcmp(argv[0], "arp") == 0) entry->intf_flags &= ~INTF_FLAG_NOARP; else if (strcmp(argv[0], "noarp") == 0) entry->intf_flags |= INTF_FLAG_NOARP; else usage(); } if (intf_set(intf, entry) < 0) err(1, "intf_set"); } else usage(); intf_close(intf); exit(0); }
/* * Match "addr" against list CIDR list "_list". Lexical wildcards and * negation are not supported. If "addr" == NULL, will verify structure * of "_list". * * Returns 1 on match found (never returned when addr == NULL). * Returns 0 on if no match found, or no errors found when addr == NULL. * Returns -1 on error */ int addr_match_cidr_list(const char *addr, const char *_list) { char *list, *cp, *o; struct xaddr try_addr, match_addr; u_int masklen; int ret = 0, r; if (addr != NULL && addr_pton(addr, &try_addr) != 0) { debug2("%s: couldn't parse address %.100s", __func__, addr); return 0; } if ((o = list = strdup(_list)) == NULL) return -1; while ((cp = strsep(&list, ",")) != NULL) { if (*cp == '\0') { error("%s: empty entry in list \"%.100s\"", __func__, o); ret = -1; break; } /* * NB. This function is called in pre-auth with untrusted data, * so be extra paranoid about junk reaching getaddrino (via * addr_pton_cidr). */ /* Stop junk from reaching getaddrinfo. +3 is for masklen */ if (strlen(cp) > INET6_ADDRSTRLEN + 3) { error("%s: list entry \"%.100s\" too long", __func__, cp); ret = -1; break; } #define VALID_CIDR_CHARS "0123456789abcdefABCDEF.:/" if (strspn(cp, VALID_CIDR_CHARS) != strlen(cp)) { error("%s: list entry \"%.100s\" contains invalid " "characters", __func__, cp); ret = -1; } /* Prefer CIDR address matching */ r = addr_pton_cidr(cp, &match_addr, &masklen); if (r == -1) { error("Invalid network entry \"%.100s\"", cp); ret = -1; break; } else if (r == -2) { error("Inconsistent mask length for " "network \"%.100s\"", cp); ret = -1; break; } else if (r == 0 && addr != NULL) { if (addr_netmatch(&try_addr, &match_addr, masklen) == 0) ret = 1; continue; } } free(o); return ret; }
static int conf_link_set(struct ipc_user *u, char *data, size_t len, __unused struct blob_buf *reply) { conf conf = container_of(u, conf_s, ipc_users[CONF_IPC_LINK_SET]); struct blob_attr *tb[CONF_LINK_MAX]; iface_flags flags = 0, flags_mod = 0; iface i; int ret = 0; if(blobmsg_parse(conf_link_attrs, CONF_LINK_MAX, tb, data, len) || !tb[CONF_LINK_DEV]) return -EINVAL; if(tb[CONF_LINK_LLQC] || tb[CONF_LINK_ROBUSTNESS]) { return -EOPNOTSUPP; } if(!(i = iface_get_byname(conf->igs, blobmsg_get_string(tb[CONF_LINK_DEV]), 1))) return -ENOMEM; iface_ref(i); #define _(attr, flag) \ if(attr) { \ flags_mod |= flag; \ if(blobmsg_get_bool(attr)) { \ flags |= flag; \ } else { \ flags &= ~(flag); \ } \ }\ _(tb[CONF_LINK_PIM], IFACE_FLAG_PIM); _(tb[CONF_LINK_SSBIDIR], IFACE_FLAG_SSBIDIR); _(tb[CONF_LINK_MLD], IFACE_FLAG_MLD_QUERIER); _(tb[CONF_LINK_IGMP], IFACE_FLAG_IGMP_QUERIER); #undef _ if(tb[CONF_LINK_PROXY]) { char *s = NULL; char *port = NULL; struct in6_addr addr; if(!(s = blobmsg_get_string(tb[CONF_LINK_PROXY]))) return -EINVAL; if(!strcmp(s, "off")) { flags_mod |= IFACE_FLAG_PROXY; flags &= ~(IFACE_FLAG_PROXY); } else if(!(port = strchr(s, ' ')) || strchr(port + 1, ' ')) { return -EINVAL; } else { *port = '\0'; port++; int p; if((sscanf(port, "%d", &p) != 1) || p >= 65536 || p<=0 || !addr_pton(&addr, s)) return -EINVAL; if(i->proxy_port != p || addr_cmp(&i->proxy_addr, &addr)) { addr_cpy(&i->proxy_addr, &addr); i->proxy_port = (in_port_t) p; flags_mod |= IFACE_FLAG_PROXY; flags |= IFACE_FLAG_PROXY; } } } conf_set_iface_flags(i, flags, flags_mod); if(tb[CONF_LINK_HELLO]) { int hello = blobmsg_get_u32(tb[CONF_LINK_HELLO]); conf_set_ifvalue(i, CIFV_PIM_HELLO_PERIOD_MS, (hello>0)?hello:INT_MIN); } if(tb[CONF_LINK_JOIN]) { int join = blobmsg_get_u32(tb[CONF_LINK_JOIN]); conf_set_ifvalue(i, CIFV_PIM_US_T_PERIODIC_MS, (join>0)?join:INT_MIN); } iface_unref(i); return ret; }
u_int8_t *anubis_lookup_mac_address(const char *expression, const char *device) { //get param char *buffer = anubis_parse_param("lookup_mac_address", expression); if(!buffer) return NULL; if(!strcasecmp(buffer, "255.255.255.255") || !strcasecmp(buffer, "Broadcast")) { return (u_int8_t *)"\xff\xff\xff\xff\xff\xff"; }//end if else if(!strncasecmp(buffer, "224.", 4) || !strncasecmp(buffer, "239.", 4)) { char mac_address[MAC_ADDRSTRLEN] = {0}; int byte1 = 1, byte2 = 0, byte3 = 0, byte4 = 0; if(sscanf(buffer, "%d.%d.%d.%d", &byte1, &byte2, &byte3, &byte4) != 4) { anubis_err("lookup_mac_address(): \"%s\" is not found\n", buffer); return NULL; }//end if snprintf(mac_address, sizeof(mac_address), "01:00:5e:%02x:%02x:%02x", byte2, byte3, byte4); return anubis_mac_aton(mac_address); }//end if multicast else { arp_t *handle = arp_open(); struct arp_entry arp_entry = {0}; int arping = 0; if(!handle) { anubis_perror("arp_open()"); return NULL; }//end if addr_pton(buffer, &arp_entry.arp_pa); AGAIN: if(arp_get(handle, &arp_entry) == 0) { char *mac_address = addr_ntoa(&arp_entry.arp_ha); arp_close(handle); if(arping) { anubis_verbose("Found \"%s\" at \"%s\"\n", buffer, mac_address); }//end if found return anubis_mac_aton(mac_address); }//end if else { if(arping) { anubis_err("lookup_mac_address(): \"%s\" is not found\n", buffer); arp_close(handle); return NULL; }//end if else { //try to arping anubis_verbose("MAC address of \"%s\" is not found in the ARP cache, trying to arping \"%s\"\n", buffer, buffer); pid_t pid = fork(); if(pid == 0) { FILE *temp_out_stream = out_stream; FILE *temp_err_stream = err_stream; int out_fail = 0; int err_fail = 0; out_stream = anubis_null_stream(); err_stream = anubis_null_stream(); if(!out_stream) { out_stream = temp_out_stream; out_fail = 1; }//end if if(!err_stream) { err_stream = temp_err_stream; err_fail = 1; }//end if //arping 3 three times for(int i = 0 ; i < 3 ; i++) anubis_arping(device, buffer); anubis_wait_microsecond(800000); //wait 800 ms //restore if(!out_fail) { fclose(out_stream); out_stream = temp_out_stream; }//end if if(!err_fail) { fclose(err_stream); err_stream = temp_err_stream; }//end if exit(0); }//end if else if(pid < 0) { anubis_perror("fork()"); }//end if #ifdef __CYGWIN__ wait(0); #else wait(NULL); #endif //wait fork finish arping = 1; goto AGAIN; } }//end else }//end else }//end anubis_lookup_mac_address
int conf_group_set(struct ipc_user *u, char *data, size_t len, __unused struct blob_buf *reply) { conf conf = container_of(u, conf_s, ipc_users[CONF_IPC_GROUP_SET]); ifgroups igs = conf->igs; pim pim = conf->pim; struct blob_attr *tb[CONF_G_MAX]; struct in6_addr grp, src; group g = NULL; source s = NULL; gsource gs = NULL; iface i = NULL; ifgroup ig = NULL; ifgsource ifgs = NULL; int join = 0, listen = 0, local = 0; char *str; int ret = 0; if(blobmsg_parse(conf_g_attrs, CONF_G_MAX, tb, data, len) || !tb[CONF_G_GROUP] || !addr_pton(&grp, blobmsg_get_string(tb[CONF_G_GROUP])) || !addr_is_multicast(&grp) || (tb[CONF_G_SRC] && !addr_pton(&src, blobmsg_get_string(tb[CONF_G_SRC]))) || (tb[CONF_G_LISTENER] && !tb[CONF_G_DEV])) return -EINVAL; if(tb[CONF_G_PIM]) { if(!(str = blobmsg_get_string(tb[CONF_G_PIM]))) return -EINVAL; else if (!strcmp(str, "join")) join = PIM_JOIN; else if(!strcmp(str, "prune")) join = PIM_PRUNE; else if(!strcmp(str, "none")) join = PIM_NONE; else return -EINVAL; } if(tb[CONF_G_LISTENER]) { if(!(str = blobmsg_get_string(tb[CONF_G_LISTENER]))) return -EINVAL; else if (!strcmp(str, "include")) listen = PIM_JOIN; else if(!strcmp(str, "exclude")) listen = PIM_PRUNE; else if(!strcmp(str, "none")) listen = PIM_NONE; else return -EINVAL; } if(tb[CONF_G_LOCAL]) { if(!(str = blobmsg_get_string(tb[CONF_G_LOCAL]))) return -EINVAL; else if (!strcmp(str, "include")) local = PIM_JOIN; else if(!strcmp(str, "exclude")) local = PIM_PRUNE; else if(!strcmp(str, "none")) local = PIM_NONE; else return -EINVAL; } if((tb[CONF_G_LOCAL] && !tb[CONF_G_DEV]) || (tb[CONF_G_LISTENER] && !tb[CONF_G_DEV])) return -EINVAL; if((tb[CONF_G_GROUP] && (!(g = group_get(igs, &grp, 1)) || !group_ref(g))) || (tb[CONF_G_SRC] && ((!(s = source_get(igs, &src, 1)) || !group_ref(s)) || (!(gs = gsource_get(g, s, 1)) || !gsource_ref(gs)))) || (tb[CONF_G_DEV] && ((!(i = iface_get_byname(igs, blobmsg_get_string(tb[CONF_G_DEV]), 1)) || !iface_ref(i)) || (!(ig = ifgroup_get(i, g, 1)) || !ifgroup_ref(ig)))) || (ig && gs && (!(ifgs = ifgsource_get(ig, gs, 1)) || !ifgsource_ref(ifgs)))) { ret = -ENOMEM; goto out; } if(tb[CONF_G_PIM]) { if(gs) { L_INFO("Set configuration of gsource "GSOURCE_L" - pim_join_desired : %s", GSOURCE_LA(gs), PIM_STATE_STR(join)); if(!gs->conf_join_desired) gsource_ref(gs); gs->conf_join_desired = join; pim_gsource_conf_changed(pim, gs); if(!gs->conf_join_desired) gsource_unref(gs); } else { L_INFO("Set configuration of group "GROUP_L" - pim_join_desired : %s", GROUP_LA(g), PIM_STATE_STR(join)); if(!g->conf_join_desired) group_ref(g); g->conf_join_desired = join; pim_group_conf_changed(pim, g); if(!g->conf_join_desired) group_unref(g); } } if(tb[CONF_G_LOCAL]) { L_INFO("Set configuration of ifgroup "IFGROUP_L" - local_exclude : %d", IFGROUP_LA(ig), (local == PIM_PRUNE)); if(!ig->conf_local_exclude) ifgroup_ref(ig); ig->conf_local_exclude = !!(local == PIM_PRUNE); pim_ifgroup_conf_changed(pim, ig); if(!ig->conf_local_exclude) ifgroup_unref(ig); } if (tb[CONF_G_LISTENER]) { if(ifgs) { listener_update_G_S(ifgs, LISTENER_CONF, listen == PIM_JOIN, listen == PIM_PRUNE); } else { listener_update_G(ig, LISTENER_CONF, listen == PIM_PRUNE); } } out: if(ifgs) ifgsource_unref(ifgs); if(gs) gsource_unref(gs); if(ig) ifgroup_unref(ig); if(g) group_unref(g); if(s) source_unref(s); if(i) iface_unref(i); return ret; }