示例#1
0
END_TEST

START_TEST(test_ip_equal)
{
    int res;
    IP ip1, ip2;
    ip_reset(&ip1);
    ip_reset(&ip2);

    res = ip_equal(NULL, NULL);
    ck_assert_msg(res == 0, "ip_equal(NULL, NULL): expected result 0, got %u.", res);

    res = ip_equal(&ip1, NULL);
    ck_assert_msg(res == 0, "ip_equal(PTR, NULL): expected result 0, got %u.", res);

    res = ip_equal(NULL, &ip1);
    ck_assert_msg(res == 0, "ip_equal(NULL, PTR): expected result 0, got %u.", res);

    ip1.family = AF_INET;
    ip1.ip4.uint32 = net_htonl(0x7F000001);

    res = ip_equal(&ip1, &ip2);
    ck_assert_msg(res == 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_UNSPEC, 0} ): expected result 0, got %u.", res);

    ip2.family = AF_INET;
    ip2.ip4.uint32 = net_htonl(0x7F000001);

    res = ip_equal(&ip1, &ip2);
    ck_assert_msg(res != 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET, 127.0.0.1} ): expected result != 0, got 0.");

    ip2.ip4.uint32 = net_htonl(0x7F000002);

    res = ip_equal(&ip1, &ip2);
    ck_assert_msg(res == 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET, 127.0.0.2} ): expected result 0, got %u.", res);

    ip2.family = AF_INET6;
    ip2.ip6.uint32[0] = 0;
    ip2.ip6.uint32[1] = 0;
    ip2.ip6.uint32[2] = net_htonl(0xFFFF);
    ip2.ip6.uint32[3] = net_htonl(0x7F000001);

    ck_assert_msg(IPV6_IPV4_IN_V6(ip2.ip6) != 0,
                  "IPV6_IPV4_IN_V6(::ffff:127.0.0.1): expected != 0, got 0.");

    res = ip_equal(&ip1, &ip2);
    ck_assert_msg(res != 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET6, ::ffff:127.0.0.1} ): expected result != 0, got 0.");

    memcpy(&ip2.ip6, &in6addr_loopback, sizeof(IP6));
    res = ip_equal(&ip1, &ip2);
    ck_assert_msg(res == 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET6, ::1} ): expected result 0, got %u.", res);

    memcpy(&ip1, &ip2, sizeof(IP));
    res = ip_equal(&ip1, &ip2);
    ck_assert_msg(res != 0, "ip_equal( {AF_INET6, ::1}, {AF_INET6, ::1} ): expected result != 0, got 0.");

    ip2.ip6.uint8[15]++;
    res = ip_equal(&ip1, &ip2);
    ck_assert_msg(res == 0, "ip_equal( {AF_INET6, ::1}, {AF_INET6, ::2} ): expected result 0, got %res.", res);
}
示例#2
0
//  -----------------------------
void test_ip()
{
    int            i,k;
    IPADDRESS    * ipa[MAXIP];
    unsigned       ipaddress,ipx;
    unsigned short ipaddress6[8], ipx6[8];

    printf("IPADDRESS testing\n");

    srand( time(0) );

    for(i=0;i<MAXIP;i++)
    {
        if( i % 2 )
        {
            ipa[i]= ip_new(IPV4_FAMILY);
            ipaddress = rand() * rand();
            ip_set( ipa[i], &ipaddress, IPV4_FAMILY  );

            if( !ip_equal(ipa[i],&ipaddress, IPV4_FAMILY ) )
                printf("error with ip_equal\n");

            ip_get( ipa[i], &ipx, IPV4_FAMILY );
            if( ipx != ipaddress )
                printf("error with ip_get\n");

        }
        else
        {
            ipa[i]= ip_new(IPV6_FAMILY);

            for(k=0;k<8;k++) ipaddress6[k] = (char) (rand() % (1<<16)); 

            ip_set( ipa[i], ipaddress6, IPV6_FAMILY  );

            if( !ip_equal(ipa[i],&ipaddress6, IPV6_FAMILY ) )
                printf("error with ip6_equal\n");

            ip_get( ipa[i], ipx6, IPV6_FAMILY  );

            for(k=0;k<8;k++)
                if( ipx6[k] != ipaddress6[k] )
                    printf("error with ip6_get\n");

        }

        printf("[%d] ",i);
        ip_fprint(stdout,ipa[i]);
        printf("\n");
    }

    printf("IP testing completed\n");
}
示例#3
0
/****************************************************************************
add an interface to the linked list of interfaces
****************************************************************************/
static void add_interface(struct in_addr ip, struct in_addr nmask)
{
    struct interface *iface;
    if (iface_find(ip, False)) {
        DEBUG(3,("not adding duplicate interface %s\n",inet_ntoa(ip)));
        return;
    }

#if !defined(__s390__)
    if (ip_equal(nmask, allones_ip)) {
        DEBUG(3,("not adding non-broadcast interface %s\n",inet_ntoa(ip)));
        return;
    }
#endif

    iface = SMB_MALLOC_P(struct interface);
    if (!iface) return;

    ZERO_STRUCTPN(iface);

    iface->ip = ip;
    iface->nmask = nmask;
    iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);

    DLIST_ADD(local_interfaces, iface);

    DEBUG(2,("added interface ip=%s ",inet_ntoa(iface->ip)));
    DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
    DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));
}
示例#4
0
/****************************************************************************
  check if an IP is one of mine
  **************************************************************************/
BOOL ismyip(struct in_addr ip)
{
    struct interface *i;
    for (i=local_interfaces; i; i=i->next)
        if (ip_equal(i->ip,ip)) return True;
    return False;
}
示例#5
0
static void arp_input(const uint8_t *pkt, int pkt_len)
{
    struct ethhdr *eh = (struct ethhdr *)pkt;
    struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
    uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
    struct ethhdr *reh = (struct ethhdr *)arp_reply;
    struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
    int ar_op;
    struct ex_list *ex_ptr;

    ar_op = ntohs(ah->ar_op);
    switch(ar_op) {
        uint32_t    ar_tip_ip;

    case ARPOP_REQUEST:
        ar_tip_ip = ip_read32h(ah->ar_tip);
        if ((ar_tip_ip & 0xffffff00) == special_addr_ip) {
            uint32_t  ar_tip_low = ar_tip_ip & 0xff;
            if ( CTL_IS_DNS(ar_tip_low) || ar_tip_low == CTL_ALIAS)
                goto arp_ok;
            for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
                if (ex_ptr->ex_addr == ar_tip_low)
                    goto arp_ok;
            }
            return;
        arp_ok:
            
            memcpy(client_ethaddr, eh->h_source, ETH_ALEN);

            
            memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
            memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
            reh->h_source[5] = ar_tip_low;
            reh->h_proto = htons(ETH_P_ARP);

            rah->ar_hrd = htons(1);
            rah->ar_pro = htons(ETH_P_IP);
            rah->ar_hln = ETH_ALEN;
            rah->ar_pln = 4;
            rah->ar_op = htons(ARPOP_REPLY);
            memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
            memcpy(rah->ar_sip, ah->ar_tip, 4);
            memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
            memcpy(rah->ar_tip, ah->ar_sip, 4);
            slirp_output(arp_reply, sizeof(arp_reply));
        }
        break;
    case ARPOP_REPLY:
        
        if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN) &&
            ip_equal( ip_read(ah->ar_sip), client_ip )) {
            memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN);
        }
        break;
    default:
        break;
    }
}
示例#6
0
/* ipport_equal
 *  compares two IPAny_Port structures
 *  unset means unequal
 *
 * returns 0 when not equal or when uninitialized
 */
int ipport_equal(IP_Port *a, IP_Port *b)
{
    if (!a || !b)
        return 0;

    if (!a->port || (a->port != b->port))
        return 0;

    return ip_equal(&a->ip, &b->ip);
};
示例#7
0
文件: nmbd.c 项目: edwacode/r6300v2
static void msg_nmbd_send_packet(int msg_type, struct process_id src,
				 void *buf, size_t len, void *private_data)
{
	struct packet_struct *p = (struct packet_struct *)buf;
	struct subnet_record *subrec;
	struct in_addr *local_ip;

	DEBUG(10, ("Received send_packet from %d\n", procid_to_pid(&src)));

	if (len != sizeof(struct packet_struct)) {
		DEBUG(2, ("Discarding invalid packet length from %d\n",
			  procid_to_pid(&src)));
		return;
	}

	if ((p->packet_type != NMB_PACKET) &&
	    (p->packet_type != DGRAM_PACKET)) {
		DEBUG(2, ("Discarding invalid packet type from %d: %d\n",
			  procid_to_pid(&src), p->packet_type));
		return;
	}

	local_ip = iface_ip(p->ip);

	if (local_ip == NULL) {
		DEBUG(2, ("Could not find ip for packet from %d\n",
			  procid_to_pid(&src)));
		return;
	}

	subrec = FIRST_SUBNET;

	p->fd = (p->packet_type == NMB_PACKET) ?
		subrec->nmb_sock : subrec->dgram_sock;

	for (subrec = FIRST_SUBNET; subrec != NULL;
	     subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
		if (ip_equal(*local_ip, subrec->myip)) {
			p->fd = (p->packet_type == NMB_PACKET) ?
				subrec->nmb_sock : subrec->dgram_sock;
			break;
		}
	}

	if (p->packet_type == DGRAM_PACKET) {
		p->port = 138;
		p->packet.dgram.header.source_ip.s_addr = local_ip->s_addr;
		p->packet.dgram.header.source_port = 138;
	}

	send_packet(p);
}
示例#8
0
/****************************************************************************
  how many non-loopback interfaces do we have
  **************************************************************************/
int iface_count_nl(void)
{
    int ret = 0;
    struct interface *i;

    for (i=local_interfaces; i; i=i->next) {
        if (ip_equal(i->ip, loopback_ip)) {
            continue;
        }
        ret++;
    }
    return ret;
}
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;
	}
}
示例#10
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(!is_zero_ip(work->dmb_addr) && 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
    zero_ip(&work->dmb_addr);

  /* 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);
}
示例#11
0
/****************************************************************************
load a list of network interfaces
****************************************************************************/
static void
interpret_interfaces (char *s, struct interface **interfaces, const char *description)
{
    char *ptr;
    fstring token;
    struct interface *iface;
    struct in_addr ip;

    ptr = s;
    ipzero = *interpret_addr2 ("0.0.0.0");
    allones_ip = *interpret_addr2 ("255.255.255.255");
    loopback_ip = *interpret_addr2 ("127.0.0.1");

    while (next_token (&ptr, token, NULL, sizeof (token)))
    {
        /* parse it into an IP address/netmasklength pair */
        char *p = strchr (token, '/');
        if (p)
            *p++ = 0;

        ip = *interpret_addr2 (token);

        /* maybe we already have it listed */
        {
            struct interface *i;
            for (i = (*interfaces); i; i = i->next)
                if (ip_equal (ip, i->ip))
                    break;
            if (i)
                continue;
        }

        iface = (struct interface *) malloc (sizeof (*iface));
        if (!iface)
            return;

        iface->ip = ip;

        if (p)
        {
            if (strlen (p) > 2)
                iface->nmask = *interpret_addr2 (p);
            else
                iface->nmask.s_addr = htonl (((ALLONES >> atoi (p)) ^ ALLONES));
        }
        else
        {
            default_netmask (&iface->nmask, &iface->ip);
        }
        iface->bcast.s_addr = MKBCADDR (iface->ip.s_addr, iface->nmask.s_addr);
        iface->next = NULL;

        if (!(*interfaces))
        {
            (*interfaces) = iface;
        }
        else
        {
            last_iface->next = iface;
        }
        last_iface = iface;
        DEBUG (2, ("Added %s ip=%s ", description, inet_ntoa (iface->ip)));
        DEBUG (2, ("bcast=%s ", inet_ntoa (iface->bcast)));
        DEBUG (2, ("nmask=%s\n", inet_ntoa (iface->nmask)));
    }
示例#12
0
/****************************************************************************
interpret a single element from a interfaces= config line

This handles the following different forms:

1) wildcard interface name
2) DNS name
3) IP/masklen
4) ip/mask
5) bcast/mask
****************************************************************************/
static void interpret_interface(char *token)
{
    struct in_addr ip, nmask;
    char *p;
    int i, added=0;

    zero_ip(&ip);
    zero_ip(&nmask);

    /* first check if it is an interface name */
    for (i=0; i<total_probed; i++) {
        if (gen_fnmatch(token, probed_ifaces[i].name) == 0) {
            add_interface(probed_ifaces[i].ip,
                          probed_ifaces[i].netmask);
            added = 1;
        }
    }
    if (added) return;

    /* maybe it is a DNS name */
    p = strchr_m(token,'/');
    if (!p) {
        ip = *interpret_addr2(token);
        for (i=0; i<total_probed; i++) {
            if (ip.s_addr == probed_ifaces[i].ip.s_addr &&
                    !ip_equal(allones_ip, probed_ifaces[i].netmask)) {
                add_interface(probed_ifaces[i].ip,
                              probed_ifaces[i].netmask);
                return;
            }
        }
        DEBUG(2,("can't determine netmask for %s\n", token));
        return;
    }

    /* parse it into an IP address/netmasklength pair */
    *p = 0;
    ip = *interpret_addr2(token);
    *p++ = '/';

    if (strlen(p) > 2) {
        nmask = *interpret_addr2(p);
    } else {
        nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES));
    }

    /* maybe the first component was a broadcast address */
    if (ip.s_addr == MKBCADDR(ip.s_addr, nmask.s_addr) ||
            ip.s_addr == MKNETADDR(ip.s_addr, nmask.s_addr)) {
        for (i=0; i<total_probed; i++) {
            if (same_net(ip, probed_ifaces[i].ip, nmask)) {
                add_interface(probed_ifaces[i].ip, nmask);
                return;
            }
        }
        DEBUG(2,("Can't determine ip for broadcast address %s\n", token));
        return;
    }

    add_interface(ip, nmask);
}
示例#13
0
/************************************************************************** **
reload the list of network interfaces
 ************************************************************************** */
static void reload_interfaces(time_t t)
{
	static time_t lastt;
	int n;
	struct subnet_record *subrec;
	extern BOOL rescan_listen_set;
	extern struct in_addr loopback_ip;

	if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return;
	lastt = t;

	if (!interfaces_changed()) return;

	/* the list of probed interfaces has changed, we may need to add/remove
	   some subnets */
	load_interfaces();

	/* find any interfaces that need adding */
	for (n=iface_count() - 1; n >= 0; n--) {
		struct interface *iface = get_interface(n);

		/*
		 * We don't want to add a loopback interface, in case
		 * someone has added 127.0.0.1 for smbd, nmbd needs to
		 * ignore it here. JRA.
		 */

		if (ip_equal(iface->ip, loopback_ip)) {
			DEBUG(2,("reload_interfaces: Ignoring loopback interface %s\n", inet_ntoa(iface->ip)));
			continue;
		}

		for (subrec=subnetlist; subrec; subrec=subrec->next) {
			if (ip_equal(iface->ip, subrec->myip) &&
			    ip_equal(iface->nmask, subrec->mask_ip)) break;
		}

		if (!subrec) {
			/* it wasn't found! add it */
			DEBUG(2,("Found new interface %s\n", 
				 inet_ntoa(iface->ip)));
			subrec = make_normal_subnet(iface);
			if (subrec) register_my_workgroup_one_subnet(subrec);
		}
	}

	/* find any interfaces that need deleting */
	for (subrec=subnetlist; subrec; subrec=subrec->next) {
		for (n=iface_count() - 1; n >= 0; n--) {
			struct interface *iface = get_interface(n);
			if (ip_equal(iface->ip, subrec->myip) &&
			    ip_equal(iface->nmask, subrec->mask_ip)) break;
		}
		if (n == -1) {
			/* oops, an interface has disapeared. This is
			 tricky, we don't dare actually free the
			 interface as it could be being used, so
			 instead we just wear the memory leak and
			 remove it from the list of interfaces without
			 freeing it */
			DEBUG(2,("Deleting dead interface %s\n", 
				 inet_ntoa(subrec->myip)));
			close_subnet(subrec);
		}
	}
	
	rescan_listen_set = True;
}
示例#14
0
BOOL create_subnets(void)
{    
	int num_interfaces;
	int i;
	struct in_addr unicast_ip, ipzero;

  try_interfaces_again:

	if (iface_count_nl() == 0) {
		DEBUG(0,("create_subnets: No non-loopback local interfaces !\n"));
		DEBUG(0,("create_subnets: Waiting for an interface to appear ...\n"));
	}

	while (iface_count_nl() == 0) {
		void (*saved_handler)(int);

		/* 
		 * Whilst we're waiting for an interface, allow SIGTERM to
		 * cause us to exit.
		 */

		saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );

		sleep(5);
		load_interfaces();

		/* 
		 * We got an interface, restore our normal term handler.
		 */

		CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
	}

	num_interfaces = iface_count();

	/* 
	 * Create subnets from all the local interfaces and thread them onto
	 * the linked list. 
	 */

	for (i = 0 ; i < num_interfaces; i++) {
		struct interface *iface = get_interface(i);

		if (!iface) {
			DEBUG(2,("create_subnets: can't get interface %d.\n", i ));
			continue;
		}

		/*
		 * We don't want to add a loopback interface, in case
		 * someone has added 127.0.0.1 for smbd, nmbd needs to
		 * ignore it here. JRA.
		 */

		if (ip_equal(iface->ip, loopback_ip)) {
			DEBUG(2,("create_subnets: Ignoring loopback interface.\n" ));
			continue;
		}

		if (!make_normal_subnet(iface))
			return False;
	}

        /* We must have at least one subnet. */
	if (subnetlist == NULL) {
		void (*saved_handler)(int);

		DEBUG(0,("create_subnets: Unable to create any subnet from "
				"given interfaces. Is your interface line in "
				"smb.conf correct ?\n"));

		saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );

		sleep(5);
		load_interfaces();

		CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
		goto try_interfaces_again;
	}

	if (lp_we_are_a_wins_server()) {
		/* Pick the first interface ip address as the WINS server ip. */
		struct in_addr *nip = iface_n_ip(0);

		if (!nip) {
			return False;
		}

		unicast_ip = *nip;
	} else {
		/* note that we do not set the wins server IP here. We just
			set it at zero and let the wins registration code cope
			with getting the IPs right for each packet */
		zero_ip(&unicast_ip);
	}

	/*
	 * Create the unicast and remote broadcast subnets.
	 * Don't put these onto the linked list.
	 * The ip address of the unicast subnet is set to be
	 * the WINS server address, if it exists, or ipzero if not.
	 */

	unicast_subnet = make_subnet( "UNICAST_SUBNET", UNICAST_SUBNET, 
				unicast_ip, unicast_ip, unicast_ip);

	zero_ip(&ipzero);

	remote_broadcast_subnet = make_subnet( "REMOTE_BROADCAST_SUBNET",
				REMOTE_BROADCAST_SUBNET,
				ipzero, ipzero, ipzero);

	if((unicast_subnet == NULL) || (remote_broadcast_subnet == NULL))
		return False;

	/* 
	 * If we are WINS server, create the WINS_SERVER_SUBNET - don't put on
	 * the linked list.
	 */

	if (lp_we_are_a_wins_server()) {
		if( (wins_server_subnet = make_subnet( "WINS_SERVER_SUBNET",
						WINS_SERVER_SUBNET, 
						ipzero, ipzero, ipzero )) == NULL )
			return False;
	}

	return True;
}
示例#15
0
文件: ip_input.c 项目: pras710/qemu
/*
 * Ip input routine.  Checksum and byte swap header.  If fragmented
 * try to reassemble.  Process options.  Pass to next level.
 */
void
ip_input(struct mbuf *m)
{
    register struct ip *ip;
    int hlen;

    DEBUG_CALL("ip_input");
    DEBUG_ARG("m = %lx", (long)m);
    DEBUG_ARG("m_len = %d", m->m_len);

    STAT(ipstat.ips_total++);

    if (m->m_len < (int)sizeof (struct ip)) {
        STAT(ipstat.ips_toosmall++);
        return;
    }

    ip = mtod(m, struct ip *);

    if (ip->ip_v != IPVERSION) {
        STAT(ipstat.ips_badvers++);
        goto bad;
    }

    hlen = ip->ip_hl << 2;
    if (hlen < (int)sizeof(struct ip ) || hlen>m->m_len) {/* min header length */
        STAT(ipstat.ips_badhlen++);                     /* or packet too short */
        goto bad;
    }

    /* keep ip header intact for ICMP reply
    * ip->ip_sum = cksum(m, hlen);
     * if (ip->ip_sum) {
     */
    if(cksum(m,hlen)) {
        STAT(ipstat.ips_badsum++);
        goto bad;
    }

    /*
     * Convert fields to host representation.
     */
    NTOHS(ip->ip_len);
    if (ip->ip_len < hlen) {
        STAT(ipstat.ips_badlen++);
        goto bad;
    }
    NTOHS(ip->ip_id);
    NTOHS(ip->ip_off);

    /*
     * Check that the amount of data in the buffers
     * is as at least much as the IP header would have us expect.
     * Trim mbufs if longer than we expect.
     * Drop packet if shorter than we expect.
     */
    if (m->m_len < ip->ip_len) {
        STAT(ipstat.ips_tooshort++);
        goto bad;
    }

    if (slirp_restrict) {
        if (ip_geth(ip->ip_dst) != special_addr_ip) {
            if (ip_getn(ip->ip_dst) == 0xffffffffu && ip->ip_p != IPPROTO_UDP)
                goto bad;
        } else {
            int host = ip_geth(ip->ip_dst) & 0xff;
            struct ex_list *ex_ptr;

            if (host == 0xff)
                goto bad;

            for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
                if (ex_ptr->ex_addr == host)
                    break;

            if (!ex_ptr)
                goto bad;
        }
    }

    /* Should drop packet if mbuf too long? hmmm... */
    if (m->m_len > ip->ip_len)
        m_adj(m, ip->ip_len - m->m_len);

    /* check ip_ttl for a correct ICMP reply */
    if(ip->ip_ttl==0 || ip->ip_ttl==1) {
        icmp_error(m, ICMP_TIMXCEED,ICMP_TIMXCEED_INTRANS, 0,"ttl");
        goto bad;
    }

    /*
     * Process options and, if not destined for us,
     * ship it on.  ip_dooptions returns 1 when an
     * error was detected (causing an icmp message
     * to be sent and the original packet to be freed).
     */
    /* We do no IP options */
    /*	if (hlen > sizeof (struct ip) && ip_dooptions(m))
     *		goto next;
     */
    /*
     * If offset or IP_MF are set, must reassemble.
     * Otherwise, nothing need be done.
     * (We could look in the reassembly queue to see
     * if the packet was previously fragmented,
     * but it's not worth the time; just let them time out.)
     *
     * XXX This should fail, don't fragment yet
     */
    if (ip->ip_off &~ IP_DF) {
        register struct ipq *fp;
        struct qlink *l;
        /*
         * Look for queue of fragments
         * of this datagram.
         */
        for (l = ipq.ip_link.next; l != &ipq.ip_link; l = l->next) {
            fp = container_of(l, struct ipq, ip_link);
            if (ip->ip_id == fp->ipq_id &&
                    ip_equal(ip->ip_src, fp->ipq_src) &&
                    ip_equal(ip->ip_dst, fp->ipq_dst) &&
                    ip->ip_p == fp->ipq_p)
                goto found;
        }
        fp = NULL;
found:

        /*
         * Adjust ip_len to not reflect header,
         * set ip_mff if more fragments are expected,
         * convert offset of this to bytes.
         */
        ip->ip_len -= hlen;
        if (ip->ip_off & IP_MF)
            ip->ip_tos |= 1;
        else
            ip->ip_tos &= ~1;

        ip->ip_off <<= 3;

        /*
         * If datagram marked as having more fragments
         * or if this is not the first fragment,
         * attempt reassembly; if it succeeds, proceed.
         */
        if (ip->ip_tos & 1 || ip->ip_off) {
            STAT(ipstat.ips_fragments++);
            ip = ip_reass(ip, fp);
            if (ip == NULL)
                return;
            STAT(ipstat.ips_reassembled++);
            m = dtom(ip);
        } else if (fp)
            ip_freef(fp);

    } else