/**************************************************************************** Try and find an interface that matches an ip. If we cannot, return NULL **************************************************************************/ static struct interface *iface_find(struct interface *interfaces, struct in_addr ip, bool CheckMask) { struct interface *i; if (is_zero_ip_v4(ip)) return interfaces; for (i=interfaces;i;i=i->next) if (CheckMask) { if (same_net_v4(i->ip,ip,i->nmask)) return i; } else if (i->ip.s_addr == ip.s_addr) return i; return NULL; }
/** * Check if a struct sockaddr has an unspecified address. */ bool is_zero_addr(const struct sockaddr_storage *pss) { #if defined(HAVE_IPV6) if (pss->ss_family == AF_INET6) { const struct in6_addr *pin6 = &((const struct sockaddr_in6 *)pss)->sin6_addr; return IN6_IS_ADDR_UNSPECIFIED(pin6); } #endif if (pss->ss_family == AF_INET) { const struct in_addr *pin = &((const struct sockaddr_in *)pss)->sin_addr; return is_zero_ip_v4(*pin); } return false; }
/* mark a wins server as temporarily dead */ void wins_srv_died(struct in_addr wins_ip, struct in_addr src_ip) { char *keystr; if (is_zero_ip_v4(wins_ip) || wins_srv_is_dead(wins_ip, src_ip)) return; keystr = wins_srv_keystr(wins_ip, src_ip); gencache_set(keystr, "DOWN", time(NULL) + DEATH_TIME); SAFE_FREE(keystr); DEBUG(4,("Marking wins server %s dead for %u seconds from source %s\n", inet_ntoa(wins_ip), DEATH_TIME, inet_ntoa(src_ip))); }
const struct in_addr *first_ipv4_iface(void) { struct interface *i; for (i=local_interfaces;i ;i=i->next) { if ((i->ip.ss_family == AF_INET) && (!is_zero_ip_v4(((struct sockaddr_in *)&i->ip)->sin_addr))) { break; } } if (!i) { return NULL; } return &((const struct sockaddr_in *)&i->ip)->sin_addr; }
static void find_domain_master_name_query_success(struct subnet_record *subrec, struct userdata_struct *userdata_in, struct nmb_name *q_name, struct in_addr answer_ip, struct res_rec *rrec) { /* * Unfortunately, finding the IP address of the Domain Master Browser, * as we have here, is not enough. We need to now do a sync to the * SERVERNAME<0x20> NetBIOS name, as only recent NT servers will * respond to the SMBSERVER name. To get this name from IP * address we do a Node status request, and look for the first * NAME<0x20> in the response, and take that as the server name. * We also keep a cache of the Domain Master Browser name for this * workgroup in the Workgroup struct, so that if the same IP addess * is returned every time, we don't need to do the node status * request. */ struct work_record *work; struct nmb_name nmbname; struct userdata_struct *userdata; size_t size = sizeof(struct userdata_struct) + sizeof(fstring)+1; unstring qname; pull_ascii_nstring(qname, sizeof(qname), q_name->name); if( !(work = find_workgroup_on_subnet(subrec, qname)) ) { if( DEBUGLVL( 0 ) ) { dbgtext( "find_domain_master_name_query_success:\n" ); dbgtext( "Failed to find workgroup %s\n", qname); } return; } /* First check if we already have a dmb for this workgroup. */ if(!is_zero_ip_v4(work->dmb_addr) && ip_equal_v4(work->dmb_addr, answer_ip)) { /* Do the local master browser announcement to the domain master browser name and IP. */ announce_local_master_browser_to_domain_master_browser( work ); /* Now synchronise lists with the domain master browser. */ sync_with_dmb(work); return; } else { zero_ip_v4(&work->dmb_addr); } /* Now initiate the node status request. */ /* We used to use the name "*",0x0 here, but some Windows * servers don't answer that name. However we *know* they * have the name workgroup#1b (as we just looked it up). * So do the node status request on this name instead. * Found at LBL labs. JRA. */ make_nmb_name(&nmbname,work->work_group,0x1b); /* Put the workgroup name into the userdata so we know what workgroup we're talking to when the reply comes back. */ /* Setup the userdata_struct - this is copied so we can use a stack variable for this. */ if((userdata = (struct userdata_struct *)SMB_MALLOC(size)) == NULL) { DEBUG(0, ("find_domain_master_name_query_success: malloc fail.\n")); return; } userdata->copy_fn = NULL; userdata->free_fn = NULL; userdata->userdata_len = strlen(work->work_group)+1; overmalloc_safe_strcpy(userdata->data, work->work_group, size - sizeof(*userdata) - 1); node_status( subrec, &nmbname, answer_ip, domain_master_node_status_success, domain_master_node_status_fail, userdata); zero_free(userdata, size); }