Exemplo n.º 1
0
Arquivo: ping.c Projeto: AyanUR/redes
int reciveping(sred *cabr,unsigned char *tuip,int *tiempopac,int sec,int tamtra)
{
        int tamano;
        struct timeval start, end;
        long int ptime=0;
	gettimeofday(&start, NULL);
        while( ptime < 100)//ciclo que recibira tramas
        {
                tamano = recvfrom(cabr->paquete,tramapingrec,74,0,NULL,0);
                if(tamano == -1)
                        printf("Error al recibir ping");
                else
                {
                        if(!memcmp(tramapingrec,cabr->mac,6)&&!memcmp(tramapingrec+12,ethertypeping,2)&&!memcmp(tramapingrec+26,tuip,4)&&!memcmp(tramapingrec+30,cabr->ip,4))
                        {
                               	gettimeofday(&end, NULL);
                                ptime =(end.tv_sec - start.tv_sec)*1000 + (end.tv_usec - start.tv_usec)/1000;
                                ctapac[1]++;
				tiempopac[intime]=ptime;intime++;
                                printf("\nrespuesta desde ");putip(tuip);
                       printf(": bytes=74 tiempo=%ldms ttl=%d",ptime,tramapingenv[22]);
				return(1);
                        }
                }
                gettimeofday(&end, NULL);
                ptime =(end.tv_sec - start.tv_sec)*1000 + (end.tv_usec - start.tv_usec)/1000;
        }
        printf("\nrespuesta desde ");putip(tuip);
        printf(": fallida time=%ldms ttl=%d",ptime,tramapingenv[22]);
	ctapac[2]++;
	return(0);
}
Exemplo n.º 2
0
Arquivo: red.c Projeto: AyanUR/redes
void putdatos()
{
	printf("\n\t\tpaquete:\t\t\t%d",cabr->paquete);
	printf("\n\t\tindice:\t\t\t\t%d",cabr->indice);
	printf("\n\t\tip:\t\t\t\t");putip(cabr->ip);
	printf("\n\t\tmac:\t\t\t\t");putmac(cabr->mac);
	printf("\n\t\tmascara:\t\t\t");putip(cabr->mascara);
	printf("\n\t\tip publica:\t\t\t");putip(cabr->ippu);
	printf("\n\t\tip puerta enlace:\t\t");putip(cabr->ipenlace);
	printf("\n\t\tmac puerta enlace\t\t");putmac(cabr->macenlace);
}
void process_name_release_request(struct subnet_record *subrec, 
                                  struct packet_struct *p)
{
	struct nmb_packet *nmb = &p->packet.nmb;
	struct in_addr owner_ip;
	struct nmb_name *question = &nmb->question.question_name;
	unstring qname;
	BOOL bcast = nmb->header.nm_flags.bcast;
	uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
	BOOL group = (nb_flags & NB_GROUP) ? True : False;
	struct name_record *namerec;
	int rcode = 0;
  
	putip((char *)&owner_ip,&nmb->additional->rdata[2]);  
  
	if(!bcast) {
		/* We should only get broadcast name release packets here.
		   Anyone trying to release unicast should be going to a WINS
		   server. If the code gets here, then either we are not a wins
		   server and they sent it anyway, or we are a WINS server and
		   the request was malformed. Either way, log an error here.
		   and send an error reply back.
		*/
		DEBUG(0,("process_name_release_request: unicast name release request \
received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
			nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name));      

		send_name_release_response(FMT_ERR, p);
		return;
	}
Exemplo n.º 4
0
Arquivo: arp.c Projeto: AyanUR/redes
int resivearp(sred *cabr,unsigned char *tuip,unsigned char *tumac)
{
        struct timeval start, end;
        double time;
	gettimeofday(&start, NULL);
        while(time<2000)
        {
                int tam;
                tam=recvfrom(cabr->paquete,tramaarprec,48,0,NULL,0);
                if(tam==-1)
                        {perror("\nError al recibir trama");}
                else
                {
                        if(!memcmp(tramaarprec+20,codrespuesta,2)&&!memcmp(tramaarprec+0,cabr->mac,6)&&!memcmp(tramaarprec+28,tuip,4))
                        {
                                memcpy(tumac+0,tramaarprec+6,6);
				printf("\npidiendo mac ala ip ");putip(tuip);printf(" ...");
                                printf("su mac es: ");putmac(tumac);printf("\n");
                                return 0;
                        }
                }
                gettimeofday(&end, NULL);
                time =(end.tv_sec - start.tv_sec)*1000 + (end.tv_usec - start.tv_usec)/1000.0;
        }
	return 1;
}
Exemplo n.º 5
0
int open_udp_socket(const char *host, int port)
{
	int type = SOCK_DGRAM;
	struct sockaddr_in sock_out;
	int res;
	struct in_addr *addr;

	addr = interpret_addr2(host);

	res = socket(PF_INET, type, 0);
	if (res == -1) {
		return -1;
	}

	memset((char *)&sock_out,'\0',sizeof(sock_out));
	putip((char *)&sock_out.sin_addr,(char *)addr);
	sock_out.sin_port = htons(port);
	sock_out.sin_family = PF_INET;

	if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
		close(res);
		return -1;
	}

	return res;
}
Exemplo n.º 6
0
static void release_name_timeout_response(struct subnet_record *subrec,
					  struct response_record *rrec)
{
	/* a release is *always* considered to be successful when it
	   times out. This doesn't cause problems as if a WINS server
	   doesn't respond and someone else wants the name then the
	   normal WACK/name query from the WINS server will cope */
	struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
	bool bcast = sent_nmb->header.nm_flags.bcast;
	struct nmb_name *question_name = &sent_nmb->question.question_name;
	struct in_addr released_ip;

	/* Get the ip address we were trying to release. */
	putip((char*)&released_ip ,&sent_nmb->additional->rdata[2]);

	if (!bcast) {
		/* mark the WINS server temporarily dead */
		wins_srv_died(rrec->packet->ip, released_ip);
	}

	DEBUG(5,("release_name_timeout_response: success in releasing name %s on subnet %s.\n",
		 nmb_namestr(question_name), subrec->subnet_name));

	if (rrec->success_fn) {
		(*(release_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, released_ip);
	}

	standard_success_release( subrec, rrec->userdata, question_name, released_ip);
	remove_response_record(subrec, rrec);
}
Exemplo n.º 7
0
Arquivo: mysql.c Projeto: AyanUR/redes
int comprueba(unsigned char *ipin,unsigned char *macin)
{
	sprintf(consulta,"select * from ipmac where ip='%d.%d.%d.%d'",ipin[0],ipin[1],ipin[2],ipin[3]);
	if (mysql_query(con,consulta))
		{fprintf(stderr, "%s\n", mysql_error(con));printf("\n\n\t\t\terror mysql");exit(-1);}
	res=mysql_use_result(con);
	while ((row = mysql_fetch_row(res)) != NULL)
	{
		sscanf(row[0],"%d.%d.%d.%d",(int*)&ipm[0],(int*)&ipm[1],(int*)&ipm[2],(int*)&ipm[3]);
		sscanf(row[1],"%x:%x:%x:%x:%x:%x",(unsigned int *)&macm[0],(unsigned int *)&macm[1],(unsigned int *)&macm[2],(unsigned int *)&macm[3],(unsigned int *)&macm[4],(unsigned int *)&macm[5]);
		if(!memcmp(ipin+0,ipm+0,4))
		{
			if(!memcmp(macin+0,macm+0,6))
			{
				mysql_free_result(res);
				return 0;
			}
			printf("\n\nla mac es incorrecta");
			printf("\nip:");putip(ipin);printf("\tmac:");putmac(macin);
			memcpy(cabr->macbase+0,macm+0,6);
			//printf("cabr->macbase====");putmac(cabr->macbase);
			mysql_free_result(res);
			return 1;
		}
	}
	mysql_free_result(res);
	return 3;
}
Exemplo n.º 8
0
static void find_all_domain_master_names_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)
{
  /* 
   * We now have a list of all the domain master browsers for all workgroups
   * that have registered with the WINS server. Now do a node status request
   * to each one and look for the first 1b name in the reply. This will be
   * the workgroup name that we will add to the unicast subnet as a 'non-local'
   * workgroup.
   */

  struct nmb_name nmbname;
  struct in_addr send_ip;
  int i;

  if( DEBUGLVL( 5 ) )
  {
    dbgtext( "find_all_domain_master_names_query_succes:\n" );
    dbgtext( "Got answer from WINS server of %d ", (rrec->rdlength / 6) );
    dbgtext( "IP addresses for Domain Master Browsers.\n" );
  }

  for(i = 0; i < rrec->rdlength / 6; i++)
  {
    /* Initiate the node status requests. */
    make_nmb_name(&nmbname, "*", 0);

    putip((char *)&send_ip, (char *)&rrec->rdata[(i*6) + 2]);

    /* 
     * Don't send node status requests to ourself.
     */

    if(ismyip( send_ip ))
    {
      if( DEBUGLVL( 5 ) )
      {
        dbgtext( "find_all_domain_master_names_query_succes:\n" );
        dbgtext( "Not sending node status to our own IP " );
        dbgtext( "%s.\n", inet_ntoa(send_ip) );
      }
      continue;
    }

    if( DEBUGLVL( 5 ) )
    {
      dbgtext( "find_all_domain_master_names_query_success:\n" );
      dbgtext( "Sending node status request to IP %s.\n", inet_ntoa(send_ip) );
    }

    node_status( subrec, &nmbname, send_ip, 
                 get_domain_master_name_node_status_success,
                 get_domain_master_name_node_status_fail,
                 NULL);
  }
}
Exemplo n.º 9
0
static void register_name_timeout_response(struct subnet_record *subrec,
					   struct response_record *rrec)
{
	/*
	 * If we are registering unicast, then NOT getting a response is an
	 * error - we do not have the name. If we are registering broadcast,
	 * then we don't expect to get a response.
	 */

	struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
	bool bcast = sent_nmb->header.nm_flags.bcast;
	bool success = False;
	struct nmb_name *question_name = &sent_nmb->question.question_name;
	uint16_t nb_flags = 0;
	int ttl = 0;
	struct in_addr registered_ip;
	
	if (bcast) {
		if(rrec->num_msgs == 0) {
			/* Not receiving a message is success for broadcast registration. */
			success = True; 

			/* Pull the success values from the original request packet. */
			nb_flags = get_nb_flags(sent_nmb->additional->rdata);
			ttl = sent_nmb->additional->ttl;
			putip(&registered_ip,&sent_nmb->additional->rdata[2]);
		}
	} else {
		/* wins timeouts are special */
		wins_registration_timeout(subrec, rrec);
		return;
	}

	DEBUG(5,("register_name_timeout_response: %s in registering name %s on subnet %s.\n",
		 success ? "success" : "failure", nmb_namestr(question_name), subrec->subnet_name));
	if(success) {
		/* Enter the registered name into the subnet name database before calling
		   the success function. */
		standard_success_register(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
		if( rrec->success_fn)
			(*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
	} else {
		struct nmb_name qname = *question_name;
		if( rrec->fail_fn)
			(*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
		/* Remove the name. */
		standard_fail_register( subrec, &qname);
	}

	/* Ensure we don't retry. */
	remove_response_record(subrec, rrec);
}
Exemplo n.º 10
0
/********************************************************
resolve via "hosts" method
*********************************************************/
static BOOL resolve_hosts(const char *name, struct in_addr *return_ip)
{
	/*
	 * "host" means do a localhost, or dns lookup.
	 */
	struct hostent *hp;

	DEBUG(3,("resolve_name: Attempting host lookup for name %s<0x20>\n", name));
	
	if (((hp = Get_Hostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
		putip((char *)return_ip,(char *)hp->h_addr);
		return True;
	}
	return False;
}
Exemplo n.º 11
0
static void wins_next_registration(struct response_record *rrec)
{
	struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
	struct nmb_name *nmbname = &sent_nmb->question.question_name;
	uint16 nb_flags = get_nb_flags(sent_nmb->additional->rdata);
	struct userdata_struct *userdata = rrec->userdata;
	const char *tag;
	struct in_addr last_ip;
	struct subnet_record *subrec;

	putip(&last_ip,&sent_nmb->additional->rdata[2]);

	if (!userdata) {
		/* it wasn't multi-homed */
		return;
	}

	tag = (const char *)userdata->data;

	for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
		if (ip_equal(last_ip, subrec->myip)) {
			subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec);
			break;
		}
	}

	if (!subrec) {
		/* no more to do! */
		return;
	}

	switch (sent_nmb->header.opcode) {
	case NMB_NAME_MULTIHOMED_REG_OPCODE:
		multihomed_register_one(nmbname, nb_flags, NULL, NULL, subrec->myip, tag);
		break;
	case NMB_NAME_REFRESH_OPCODE_8:
		queue_wins_refresh(nmbname, 
				   register_name_response,
				   register_name_timeout_response,
				   nb_flags, subrec->myip, tag);
		break;
	}
}
Exemplo n.º 12
0
Arquivo: ping.c Projeto: AyanUR/redes
void estadisticas(int *tiempopac,unsigned char *tuip,int pac)
{
	int min,max,med=0;
	min=tiempopac[0];
	max=tiempopac[0];
	for(i=0;i<ctapac[1];i++)
	{
		//printf("%d  ",tiempopac[i]);
		if(tiempopac[i]<min)
			min=tiempopac[i];
		if(tiempopac[i]>max)
			max=tiempopac[i];
		med=med+tiempopac[i];
	}
	med=med/ctapac[1];
	printf("\n\nestadisticas ping para ");putip(tuip);puts(":\n");
	printf("paquetes enviados=%d, recividos=%d, perdidos=%d\n",ctapac[0],ctapac[1],ctapac[2]);
	printf("(%d %% ",(ctapac[2]*100)/pac);printf("perdidos),\n");
	printf("tiempos aproximados de ida y vuelta en milisegundos:\n");
	printf("minimo=%dms, maximo=%dms, media=%dms\n\n",min,max,med);
}
Exemplo n.º 13
0
/****************************************************************************
send a single packet to a port on another machine
****************************************************************************/
BOOL
send_one_packet (char *buf, int len, struct in_addr ip, int port, int type)
{
    BOOL ret;
    int out_fd;
    struct sockaddr_in sock_out;

    if (passive)
        return (True);

    /* create a socket to write to */
    out_fd = socket (AF_INET, type, 0);
    if (out_fd == -1)
    {
        DEBUG (0, ("socket failed"));
        return False;
    }

    /* set the address and port */
    memset ((char *) &sock_out, '\0', sizeof (sock_out));
    putip ((char *) &sock_out.sin_addr, (char *) &ip);
    sock_out.sin_port = htons (port);
    sock_out.sin_family = AF_INET;

    if (DEBUGLEVEL > 0)
        DEBUG (3, ("sending a packet of len %d to (%s) on port %d of type %s\n",
                   len, inet_ntoa (ip), port, type == SOCK_DGRAM ? "DGRAM" : "STREAM"));

    /* send it */
    ret = (sendto (out_fd, buf, len, 0, (struct sockaddr *) &sock_out, sizeof (sock_out)) >= 0);

    if (!ret)
        DEBUG (0, ("Packet send to %s(%d) failed ERRNO=%s\n",
                   inet_ntoa (ip), port, unix_error_string (errno)));

    close (out_fd);
    return (ret);
}
Exemplo n.º 14
0
BOOL cli_session_request(struct cli_state *cli,
			 struct nmb_name *calling, struct nmb_name *called)
{
	char *p;
	int len = 4;
	extern pstring user_socket_options;

	/* 445 doesn't have session request */
	if (cli->port == 445) return True;

	/* send a session request (RFC 1002) */
	memcpy(&(cli->calling), calling, sizeof(*calling));
	memcpy(&(cli->called ), called , sizeof(*called ));
  
	/* put in the destination name */
	p = cli->outbuf+len;
	name_mangle(cli->called .name, p, cli->called .name_type);
	len += name_len(p);

	/* and my name */
	p = cli->outbuf+len;
	name_mangle(cli->calling.name, p, cli->calling.name_type);
	len += name_len(p);

        /* setup the packet length
         * Remove four bytes from the length count, since the length
         * field in the NBT Session Service header counts the number
         * of bytes which follow.  The cli_send_smb() function knows
         * about this and accounts for those four bytes.
         * CRH.
         */
        len -= 4;
	_smb_setlen(cli->outbuf,len);
	SCVAL(cli->outbuf,0,0x81);

#ifdef WITH_SSL
retry:
#endif /* WITH_SSL */

	cli_send_smb(cli);
	DEBUG(5,("Sent session request\n"));

	if (!cli_receive_smb(cli))
		return False;

	if (CVAL(cli->inbuf,0) == 0x84) {
		/* C. Hoch  9/14/95 Start */
		/* For information, here is the response structure.
		 * We do the byte-twiddling to for portability.
		struct RetargetResponse{
		unsigned char type;
		unsigned char flags;
		int16 length;
		int32 ip_addr;
		int16 port;
		};
		*/
		int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
		/* SESSION RETARGET */
		putip((char *)&cli->dest_ip,cli->inbuf+4);

		cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT);
		if (cli->fd == -1)
			return False;

		DEBUG(3,("Retargeted\n"));

		set_socket_options(cli->fd,user_socket_options);

		/* Try again */
		{
			static int depth;
			BOOL ret;
			if (depth > 4) {
				DEBUG(0,("Retarget recursion - failing\n"));
				return False;
			}
			depth++;
			ret = cli_session_request(cli, calling, called);
			depth--;
			return ret;
		}
	} /* C. Hoch 9/14/95 End */

#ifdef WITH_SSL
    if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */
        if (!sslutil_fd_is_ssl(cli->fd)){
            if (sslutil_connect(cli->fd) == 0)
                goto retry;
        }
    }
#endif /* WITH_SSL */

	if (CVAL(cli->inbuf,0) != 0x82) {
                /* This is the wrong place to put the error... JRA. */
		cli->rap_error = CVAL(cli->inbuf,4);
		return False;
	}
	return(True);
}
Exemplo n.º 15
0
static void register_name_response(struct subnet_record *subrec,
                       struct response_record *rrec, struct packet_struct *p)
{
	/* 
	 * If we are registering broadcast, then getting a response is an
	 * error - we do not have the name. If we are registering unicast,
	 * then we expect to get a response.
	 */

	struct nmb_packet *nmb = &p->packet.nmb;
	BOOL bcast = nmb->header.nm_flags.bcast;
	BOOL success = True;
	struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
	struct nmb_name *answer_name = &nmb->answers->rr_name;
	struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
	int ttl = 0;
	uint16 nb_flags = 0;
	struct in_addr register_ip;
	fstring reg_name;
	
	putip(&register_ip,&sent_nmb->additional->rdata[2]);
	fstrcpy(reg_name, inet_ntoa(register_ip));
	
	if (subrec == unicast_subnet) {
		/* we know that this wins server is definately alive - for the moment! */
		wins_srv_alive(rrec->packet->ip, register_ip);
	}

	/* Sanity check. Ensure that the answer name in the incoming packet is the
	   same as the requested name in the outgoing packet. */

	if(!question_name || !answer_name) {
		DEBUG(0,("register_name_response: malformed response (%s is NULL).\n",
			 question_name ? "question_name" : "answer_name" ));
		return;
	}

	if(!nmb_name_equal(question_name, answer_name)) {
		DEBUG(0,("register_name_response: Answer name %s differs from question name %s.\n", 
			 nmb_namestr(answer_name), nmb_namestr(question_name)));
		return;
	}

	if(bcast) {
		/*
		 * Special hack to cope with old Samba nmbd's.
		 * Earlier versions of Samba (up to 1.9.16p11) respond 
		 * to a broadcast name registration of WORKGROUP<1b> when 
		 * they should not. Hence, until these versions are gone, 
		 * we should treat such errors as success for this particular
		 * case only. [email protected].
		 */
		
#if 1 /* OLD_SAMBA_SERVER_HACK */
		unstring ans_name;
		pull_ascii_nstring(ans_name, sizeof(ans_name), answer_name->name);
		if((nmb->header.rcode == ACT_ERR) && strequal(lp_workgroup(), ans_name) &&
		   (answer_name->name_type == 0x1b)) {
			/* Pretend we did not get this. */
			rrec->num_msgs--;

			DEBUG(5,("register_name_response: Ignoring broadcast response to registration of name %s due to old Samba server bug.\n", 
				 nmb_namestr(answer_name)));
			return;
		}
#endif /* OLD_SAMBA_SERVER_HACK */

		/* Someone else has the name. Log the problem. */
		DEBUG(1,("register_name_response: Failed to register name %s IP %s on subnet %s via broadcast. Error code was %d. Reject came from IP %s\n", 
			 nmb_namestr(answer_name), 
			 reg_name,
			 subrec->subnet_name, nmb->header.rcode, inet_ntoa(p->ip)));
		success = False;
	} else {
		/* Unicast - check to see if the response allows us to have the name. */
		if (nmb->header.opcode == NMB_WACK_OPCODE) {
			/* WINS server is telling us to wait. Pretend we didn't get
			   the response but don't send out any more register requests. */

			DEBUG(5,("register_name_response: WACK from WINS server %s in registering name %s IP %s\n", 
				 inet_ntoa(p->ip), nmb_namestr(answer_name), reg_name));

			rrec->repeat_count = 0;
			/* How long we should wait for. */
			rrec->repeat_time = p->timestamp + nmb->answers->ttl;
			rrec->num_msgs--;
			return;
		} else if (nmb->header.rcode != 0) {
			/* Error code - we didn't get the name. */
			success = False;

			DEBUG(0,("register_name_response: %sserver at IP %s rejected our name registration of %s IP %s with error code %d.\n", 
				 subrec==unicast_subnet?"WINS ":"",
				 inet_ntoa(p->ip), 
				 nmb_namestr(answer_name), 
				 reg_name,
				 nmb->header.rcode));
		} else {
			success = True;
			/* Get the data we need to pass to the success function. */
			nb_flags = get_nb_flags(nmb->answers->rdata);
			ttl = nmb->answers->ttl;

			/* send off a registration for the next IP, if any */
			wins_next_registration(rrec);
		}
	} 

	DEBUG(5,("register_name_response: %s in registering %sname %s IP %s with %s.\n",
		 success ? "success" : "failure", 
		 subrec==unicast_subnet?"WINS ":"",
		 nmb_namestr(answer_name), 
		 reg_name,
		 inet_ntoa(rrec->packet->ip)));

	if(success) {
		/* Enter the registered name into the subnet name database before calling
		   the success function. */
		standard_success_register(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip);
		if( rrec->success_fn)
			(*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip);
	} else {
		if( rrec->fail_fn)
			(*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
		/* Remove the name. */
		standard_fail_register( subrec, rrec, question_name);
	}

	/* Ensure we don't retry. */
	remove_response_record(subrec, rrec);
}
Exemplo n.º 16
0
static void wins_registration_timeout(struct subnet_record *subrec,
				      struct response_record *rrec)
{
	struct userdata_struct *userdata = rrec->userdata;
	struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
	struct nmb_name *nmbname = &sent_nmb->question.question_name;
	struct in_addr register_ip;
	fstring src_addr;

	putip(&register_ip,&sent_nmb->additional->rdata[2]);

	fstrcpy(src_addr, inet_ntoa(register_ip));

	DEBUG(2,("wins_registration_timeout: WINS server %s timed out registering IP %s\n", 
		 inet_ntoa(rrec->packet->ip), src_addr));

	/* mark it temporarily dead for this source address */
	wins_srv_died(rrec->packet->ip, register_ip);

	/* if we have some userdata then use that to work out what
	   wins server to try next */
	if (userdata) {
		const char *tag = (const char *)userdata->data;

		/* try the next wins server in our failover list for
		   this tag */
		rrec->packet->ip = wins_srv_ip_tag(tag, register_ip);
	}

	/* if we have run out of wins servers for this tag then they
	   must all have timed out. We treat this as *success*, not
	   failure, and go into our standard name refresh mode. This
	   copes with all the wins servers being down */
	if (wins_srv_is_dead(rrec->packet->ip, register_ip)) {
		uint16 nb_flags = get_nb_flags(sent_nmb->additional->rdata);
		int ttl = sent_nmb->additional->ttl;

		standard_success_register(subrec, userdata, nmbname, nb_flags, ttl, register_ip);
		if(rrec->success_fn) {
			(*(register_name_success_function)rrec->success_fn)(subrec, 
									    rrec->userdata, 
									    nmbname, 
									    nb_flags, 
									    ttl, 
									    register_ip);
		}

		/* send off a registration for the next IP, if any */
		wins_next_registration(rrec);

		/* don't need to send this packet any more */
		remove_response_record(subrec, rrec);
		return;
	}
	
	/* we will be moving to the next WINS server for this group,
	   send it immediately */
	rrec->repeat_count = 2;
	rrec->repeat_time = time(NULL) + 1;
	rrec->in_expiration_processing = False;

	DEBUG(6,("Retrying register of name %s IP %s with WINS server %s\n",
		 nmb_namestr(nmbname), src_addr, inet_ntoa(rrec->packet->ip)));

	/* notice that we don't remove the response record. This keeps
	   us trying to register with each of our failover wins servers */
}
Exemplo n.º 17
0
int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
{
  struct sockaddr_in sock_out;
  int res,ret;
  int connect_loop = 250; /* 250 milliseconds */
  int loops = (timeout) / connect_loop;

  /* create a socket to write to */
  res = socket(PF_INET, type, 0);
  if (res == -1) 
    { DEBUG(0,("socket error\n")); return -1; }

  if (type != SOCK_STREAM) return(res);
  
  memset((char *)&sock_out,'\0',sizeof(sock_out));
  putip((char *)&sock_out.sin_addr,(char *)addr);
  
  sock_out.sin_port = htons( port );
  sock_out.sin_family = PF_INET;

  /* set it non-blocking */
  set_blocking(res,False);

  DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
  
  /* and connect it to the destination */
connect_again:
  ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));

  /* Some systems return EAGAIN when they mean EINPROGRESS */
  if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
        errno == EAGAIN) && loops--) {
    msleep(connect_loop);
    goto connect_again;
  }

  if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
         errno == EAGAIN)) {
      DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
      close(res);
      return -1;
  }

#ifdef EISCONN
  if (ret < 0 && errno == EISCONN) {
    errno = 0;
    ret = 0;
  }
#endif

  if (ret < 0) {
    DEBUG(1,("error connecting to %s:%d (%s)\n",
	     inet_ntoa(*addr),port,strerror(errno)));
    close(res);
    return -1;
  }

  /* set it blocking again */
  set_blocking(res,True);

  return res;
}
Exemplo n.º 18
0
static void release_name_response(struct subnet_record *subrec,
				  struct response_record *rrec, struct packet_struct *p)
{
	/* 
	 * If we are releasing broadcast, then getting a response is an
	 * error. If we are releasing unicast, then we expect to get a response.
	 */
	struct nmb_packet *nmb = &p->packet.nmb;
	bool bcast = nmb->header.nm_flags.bcast;
	bool success = True;
	struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
	struct nmb_name *answer_name = &nmb->answers->rr_name;
	struct in_addr released_ip;

	/* Sanity check. Ensure that the answer name in the incoming packet is the
	   same as the requested name in the outgoing packet. */
	if (!nmb_name_equal(question_name, answer_name)) {
		DEBUG(0,("release_name_response: Answer name %s differs from question name %s.\n", 
			 nmb_namestr(answer_name), nmb_namestr(question_name)));
		return;
	}

	if (bcast) {
		/* Someone sent a response to a bcast release? ignore it. */
		return;
	}

	/* Unicast - check to see if the response allows us to release the name. */
	if (nmb->header.rcode != 0) {
		/* Error code - we were told not to release the name ! What now ! */
		success = False;

		DEBUG(0,("release_name_response: WINS server at IP %s rejected our \
name release of name %s with error code %d.\n", 
			 inet_ntoa(p->ip), 
			 nmb_namestr(answer_name), nmb->header.rcode));
	} else if (nmb->header.opcode == NMB_WACK_OPCODE) {
		/* WINS server is telling us to wait. Pretend we didn't get
		   the response but don't send out any more release requests. */

		DEBUG(5,("release_name_response: WACK from WINS server %s in releasing \
name %s on subnet %s.\n", 
			 inet_ntoa(p->ip), nmb_namestr(answer_name), subrec->subnet_name));

		rrec->repeat_count = 0;
		/* How long we should wait for. */
		rrec->repeat_time = p->timestamp + nmb->answers->ttl;
		rrec->num_msgs--;
		return;
	}

	DEBUG(5,("release_name_response: %s in releasing name %s on subnet %s.\n",
		 success ? "success" : "failure", nmb_namestr(answer_name), subrec->subnet_name));
	if (success) {
		putip((char*)&released_ip ,&nmb->answers->rdata[2]);

		if(rrec->success_fn)
			(*(release_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, released_ip);
		standard_success_release( subrec, rrec->userdata, answer_name, released_ip);
	} else {
		/* We have no standard_fail_release - maybe we should add one ? */
		if (rrec->fail_fn) {
			(*(release_name_fail_function)rrec->fail_fn)(subrec, rrec, answer_name);
		}
	}

	remove_response_record(subrec, rrec);
}
Exemplo n.º 19
0
/****************************************************************************
  do a netbios name query to find someones IP
  returns an array of IP addresses or NULL if none
  *count will be set to the number of addresses returned
  ****************************************************************************/
struct in_addr *
name_query (int fd, const char *name, int name_type, BOOL bcast, BOOL recurse,
            struct in_addr to_ip, int *count, void (*fn) (struct packet_struct *))
{
    BOOL found = False;
    int i, retries = 3;
    int retry_time = bcast ? 250 : 2000;
    struct timeval tval;
    struct packet_struct p;
    struct packet_struct *p2;
    struct nmb_packet *nmb = &p.packet.nmb;
    static int name_trn_id = 0;
    struct in_addr *ip_list = NULL;

    memset ((char *) &p, '\0', sizeof (p));
    (*count) = 0;

    if (!name_trn_id)
        name_trn_id = ((unsigned) time (NULL) % (unsigned) 0x7FFF) +
            ((unsigned) getpid () % (unsigned) 100);
    name_trn_id = (name_trn_id + 1) % (unsigned) 0x7FFF;

    nmb->header.name_trn_id = name_trn_id;
    nmb->header.opcode = 0;
    nmb->header.response = False;
    nmb->header.nm_flags.bcast = bcast;
    nmb->header.nm_flags.recursion_available = False;
    nmb->header.nm_flags.recursion_desired = recurse;
    nmb->header.nm_flags.trunc = False;
    nmb->header.nm_flags.authoritative = False;
    nmb->header.rcode = 0;
    nmb->header.qdcount = 1;
    nmb->header.ancount = 0;
    nmb->header.nscount = 0;
    nmb->header.arcount = 0;

    make_nmb_name (&nmb->question.question_name, name, name_type);

    nmb->question.question_type = 0x20;
    nmb->question.question_class = 0x1;

    p.ip = to_ip;
    p.port = NMB_PORT;
    p.fd = fd;
    p.timestamp = time (NULL);
    p.packet_type = NMB_PACKET;

    GetTimeOfDay (&tval);

    if (!send_packet (&p))
        return NULL;

    retries--;

    while (1)
    {
        struct timeval tval2;
        GetTimeOfDay (&tval2);
        if (TvalDiff (&tval, &tval2) > retry_time)
        {
            if (!retries)
                break;
            if (!found && !send_packet (&p))
                return NULL;
            GetTimeOfDay (&tval);
            retries--;
        }

        if ((p2 = receive_packet (fd, NMB_PACKET, 90)))
        {
            struct nmb_packet *nmb2 = &p2->packet.nmb;
            debug_nmb_packet (p2);

            if (nmb->header.name_trn_id != nmb2->header.name_trn_id || !nmb2->header.response)
            {
                /* 
                 * Its not for us - maybe deal with it later 
                 * (put it on the queue?).
                 */
                if (fn)
                    fn (p2);
                else
                    free_packet (p2);
                continue;
            }

            if (nmb2->header.opcode != 0 ||
                nmb2->header.nm_flags.bcast || nmb2->header.rcode || !nmb2->header.ancount)
            {
                /* 
                 * XXXX what do we do with this? Could be a redirect, but
                 * we'll discard it for the moment.
                 */
                free_packet (p2);
                continue;
            }

            ip_list = (struct in_addr *) Realloc (ip_list, sizeof (ip_list[0]) *
                                                  ((*count) + nmb2->answers->rdlength / 6));
            if (ip_list)
            {
                DEBUG (fn ? 3 : 2, ("Got a positive name query response from %s ( ",
                                    inet_ntoa (p2->ip)));
                for (i = 0; i < nmb2->answers->rdlength / 6; i++)
                {
                    putip ((char *) &ip_list[(*count)], &nmb2->answers->rdata[2 + i * 6]);
                    DEBUG (fn ? 3 : 2, ("%s ", inet_ntoa (ip_list[(*count)])));
                    (*count)++;
                }
                DEBUG (fn ? 3 : 2, (")\n"));
            }

            found = True;
            retries = 0;
            free_packet (p2);
            if (fn)
                break;

            /*
             * If we're doing a unicast lookup we only
             * expect one reply. Don't wait the full 2
             * seconds if we got one. JRA.
             */
            if (!bcast && found)
                break;
        }
    }

    return ip_list;
}
Exemplo n.º 20
0
/****************************************************************************
  send a session request.  see rfc1002.txt 4.3 and 4.3.2
****************************************************************************/
BOOL cli_session_request(struct cli_state *cli,
			 const struct nmb_name *calling,
			 const struct nmb_name *called)
{
	char *p;
	int len = 4;
	extern pstring user_socket_options;
	io_struct ps;
	uchar nb_type;

	ZERO_STRUCT(ps);
	io_init(&ps, 4096, MARSHALL);

	/* send a session request (RFC 1002) */

	smb_set_nbnames(cli->hnd, calling, called);

	/* put in the destination name */
	p = ps.data_p;
	name_mangle(called->name, p, called->name_type);
	len += name_len(p);

	/* and my name */
	p = ps.data_p + len-4;
	name_mangle(calling->name, p, calling->name_type);
	len += name_len(p);

	ps.data_offset = len;
	smb_send_smb(cli->hnd, &ps, 0x81);
	io_free(&ps);

	DEBUG(5, ("Sent session request: %s to %s\n",
			nmb_namestr(calling), nmb_namestr(called)));

	if (!smb_receive_smb(cli->hnd, &ps, &nb_type))
		return False;

	if (nb_type == 0x84)
	{
		int fd;
		/* C. Hoch  9/14/95 Start */
		/* For information, here is the response structure.
		 * We do the byte-twiddling to for portability.
		 struct RetargetResponse{
		 unsigned char type;
		 unsigned char flags;
		 int16 length;
		 int32 ip_addr;
		 int16 port;
		 };
		 */
		int port = (CVAL(ps.data_p, 4) << 8) + CVAL(ps.data_p, 5);
		/* SESSION RETARGET */
		putip((char *)&cli->dest_ip, ps.data_p);

		fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port,
					LONG_CONNECT_TIMEOUT);
		if (fd == -1 || !smb_set_fd(cli->hnd, fd))
			return False;

		cli->dbg(3, "Retargeted\n");

		set_socket_options(fd, user_socket_options);

		/* Try again */
		{
			static int depth;
			BOOL ret;
			if (depth > 4)
			{
				cli->dbg( 0,
					  "Retarget recursion - failing\n");
				return False;
			}
			depth++;
			ret = cli_session_request(cli, calling, called);
			depth--;
			return ret;
		}
	}			/* C. Hoch 9/14/95 End */

	if (nb_type != 0x82)
	{
		/* This is the wrong place to put the error... JRA. */
		cli->rap_error = CVAL(ps.data_p, 0);
		return False;
	}
	return (True);
}
Exemplo n.º 21
0
static void domain_master_node_status_success(struct subnet_record *subrec,
                                              struct userdata_struct *userdata,
                                              struct res_rec *answers,
                                              struct in_addr from_ip)
{
  struct work_record *work = find_workgroup_on_subnet( subrec, userdata->data);

  if( work == NULL )
  {
    if( DEBUGLVL( 0 ) )
    {
      dbgtext( "domain_master_node_status_success:\n" );
      dbgtext( "Unable to find workgroup " );
      dbgtext( "%s on subnet %s.\n", userdata->data, subrec->subnet_name );
    }
    return;
  }

  if( DEBUGLVL( 3 ) )
  {
    dbgtext( "domain_master_node_status_success:\n" );
    dbgtext( "Success in node status for workgroup " );
    dbgtext( "%s from ip %s\n", work->work_group, inet_ntoa(from_ip) );
  }

  /* Go through the list of names found at answers->rdata and look for
     the first SERVER<0x20> name. */

  if(answers->rdata != NULL)
  {
    char *p = answers->rdata;
    int numnames = CVAL(p, 0);

    p += 1;

    while (numnames--)
    {
      char qname[17];
      uint16 nb_flags;
      int name_type;

      StrnCpy(qname,p,15);
      name_type = CVAL(p,15);
      nb_flags = get_nb_flags(&p[16]);
      trim_string(qname,NULL," ");

      p += 18;

      if(!(nb_flags & NB_GROUP) && (name_type == 0x20))
      {
        struct nmb_name nmbname;

        make_nmb_name(&nmbname, qname, name_type);

        /* Copy the dmb name and IP address
           into the workgroup struct. */

        work->dmb_name = nmbname;
        putip((char *)&work->dmb_addr, &from_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);
        break;
      }
    }
  }
  else
    if( DEBUGLVL( 0 ) )
    {
      dbgtext( "domain_master_node_status_success:\n" );
      dbgtext( "Failed to find a SERVER<0x20> name in reply from IP " );
      dbgtext( "%s.\n", inet_ntoa(from_ip) );
    }
}
Exemplo n.º 22
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;
  int size = sizeof(struct userdata_struct) + sizeof(fstring)+1;

  if( !(work = find_workgroup_on_subnet(subrec, q_name->name)) )
  {
    if( DEBUGLVL( 0 ) )
      {
      dbgtext( "find_domain_master_name_query_success:\n" );
      dbgtext( "Failed to find workgroup %s\n", q_name->name );
      }
    return;
  }

  /* First check if we already have a dmb for this workgroup. */

  if(!ip_equal(work->dmb_addr, ipzero) && ip_equal(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
    putip((char *)&work->dmb_addr, &ipzero);

  /* Now initiate the node status request. */
  make_nmb_name(&nmbname,"*",0x0);

  /* 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 *)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;
  pstrcpy(userdata->data, work->work_group);

  node_status( subrec, &nmbname, answer_ip, 
               domain_master_node_status_success,
               domain_master_node_status_fail,
               userdata);

  zero_free(userdata, size);
}
Exemplo n.º 23
0
static struct work_record *create_workgroup(char *name, int ttl)
{
  struct work_record *work;
  struct subnet_record *subrec;
  int t = -1;
  
  if((work = (struct work_record *)malloc(sizeof(*work))) == NULL)
  {
    DEBUG(0,("create_workgroup: malloc fail !\n"));
    return NULL;
  }
  bzero((char *)work, sizeof(*work));
 
  StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
  work->serverlist = NULL;
  
  work->RunningElection = False;
  work->ElectionCount = 0;
  work->announce_interval = 0;
  work->needelection = False;
  work->needannounce = True;
  work->lastannounce_time = time(NULL);
  work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
  work->dom_state = DOMAIN_NONE;
  work->log_state = LOGON_NONE;
  
  work->death_time = (ttl != PERMANENT_TTL) ? time(NULL)+(ttl*3) : PERMANENT_TTL;

  /* Make sure all token representations of workgroups are unique. */
  
  for (subrec = FIRST_SUBNET; subrec && (t == -1); 
           subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
  {
    struct work_record *w;
    for (w = subrec->workgrouplist; w && t == -1; w = w->next)
    {
      if (strequal(w->work_group, work->work_group))
        t = w->token;
    }
  }
  
  if (t == -1)
    work->token = ++workgroup_count;
  else
    work->token = t;
  
  /* No known local master browser as yet. */
  *work->local_master_browser_name = '\0';

  /* No known domain master browser as yet. */
  *work->dmb_name.name = '\0';
  putip((char *)&work->dmb_addr, &ipzero);

  /* WfWg  uses 01040b01 */
  /* Win95 uses 01041501 */
  /* NTAS  uses ???????? */
  work->ElectionCriterion  = (MAINTAIN_LIST)|(BROWSER_ELECTION_VERSION<<8); 
  work->ElectionCriterion |= (lp_os_level() << 24);
  if (lp_domain_master())
    work->ElectionCriterion |= 0x80;
  
  return work;
}