/** * Looks for the group's matched destination address in a list of addresses. * Returns 1 if found, 0 if not found */ int addr_in_list(int listidx, uint32_t *addrlist, int size) { int i, rval; if (group_list[listidx].destaddr.s_addr == 0) { rval = interface_in_list(addrlist, size); if (rval == -1) { return 0; } else { group_list[listidx].destaddr = m_interface[rval].addr; return 1; } } for (i = 0; i < size; i++) { if (addrlist[i] == 0) { return 0; } if (group_list[listidx].destaddr.s_addr == addrlist[i]) { return 1; } } return 0; }
void update_interfaces() { struct int_sock *new_list=NULL; struct int_sock *i=NULL,*j,*prev; struct int_sock *new_int=NULL; int i_fd,o_fd; /* if all interfaces are '+'-interfaces, we bridge broadcast */ do_broadcast_bridging=1; update_interface_trigger=0; syslog(LOG_DEBUG,"rechecking interfaces"); if (read_sys(&new_list)) return; for (i=select_set.i_s_list; i; i=i->next) { if (!interface_in_list(i,new_list)) { /* remove interface i */ j=select_set.i_s_list; prev=NULL; while (j) { if (!strncmp(j->dev_name,i->dev_name, DEV_NAME_LEN)) { if (!prev) { select_set.i_s_list=j->next; } else { prev->next=j->next; } prev=j; j=j->next; free(j); } else { j=j->next; } } /* and close the socket */ close(i->i_fd); close(i->o_fd); syslog(LOG_INFO,"removed interface %s",i->dev_name); } } for (i=new_list; i; i=i->next) { if (!interface_in_list(i,select_set.i_s_list)) { /* add interface i */ new_int=malloc(sizeof(struct int_sock)); if (!new_int) { syslog(LOG_ERR,"can't add interface %s -- " \ "no memory",i->dev_name); continue; } i_fd=open_incoming_socket(i->dev_name); if (i_fd==-1) { free(new_int); continue; } o_fd=open_outgoing_socket(i->dev_name); if (o_fd==-1) { close(i_fd); free(new_int); continue; } strncpy(new_int->dev_name,i->dev_name,DEV_NAME_LEN); new_int->i_fd=i_fd; new_int->o_fd=o_fd; new_int->features=i->features; new_int->next=select_set.i_s_list; select_set.i_s_list=new_int; syslog(LOG_INFO,"added interface %s",i->dev_name); } } /* kill temporary new_list */ while (new_list) { i=new_list->next; free(new_list); new_list=i; } /* prepare the fd_set for select */ FD_ZERO(&select_set.fds); for (i=select_set.i_s_list; i; i=i->next) { FD_SET(i->i_fd,&select_set.fds); select_set.highest_fd=(i->i_fd>select_set.highest_fd)? i->i_fd:select_set.highest_fd; } }