Ejemplo n.º 1
0
/****************************************************************************
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;
}
Ejemplo n.º 2
0
/**
 * 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;
}
Ejemplo n.º 3
0
/*
  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)));
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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);
}