Example #1
0
File: PACKET.C Project: barmi/tcpip
int
start_arp(struct TCB *tp, unsigned long addr)
{
    struct TCB *sp;
    int i;

    if ((addr == IP_STUB(tp)->destination) && (tp->status & TCB_ARP_ED))
        return(1);
    if (driver_type == SLIP_DRIVER)		// We dont need ARP
        goto arp_ed;
    if ((tp->option & SO_BROADCAST) && (addr == INADDR_BROADCAST)) {
        // Copy Broadcast Address
        copy_hw_addr(ETH_STUB(tp)->destination, ARP_STUB.ether_pkt.destination);
        goto arp_ed;
    };
    for (sp = tcb, i = 0; i < num_socket; i++, sp++) {
        if ((sp->status & TCB_ARP_ED) &&
                (IP_STUB(sp)->destination == addr)) {
            copy_hw_addr(ETH_STUB(tp)->destination, ETH_STUB(sp)->destination);
arp_ed:
            IP_STUB(tp)->destination = addr;
            set_status(tp, TCB_ARP_ED);
            return(1);
        }
    }
    IP_STUB(tp)->destination = addr;
    arp_target(tp) = samenet(addr) ? addr : tcpipcfg.c_defgw;

    // Failed to find Matched Address, Now do the ARP
    ARP_STUB.his_proto_addr = arp_target(tp);
    clr_status(tp, TCB_ARP_ED);
    set_status(tp, TCB_ARP_ING);
    statistics.arpOutRequests++;
    tp->arp_retrytimer = ONE_SECOND;
    tp->timeout_count = 1;
    //rprintf("[ARP_S]");
    //print_packet(&ARP_STUB, 0);
    snd_packet(&ARP_STUB, ARP_PLEN);
    return(0);
}
Example #2
0
/*
 *  lookup info about a client in the database.  Find an address on the
 *  same net as riip.
 */
int
lookup(Bootp *bp, Info *iip, Info *riip)
{
	Ndbtuple *t, *nt;
	Ndbs s;
	char *hwattr;
	char *hwval, hwbuf[33];
	uchar ciaddr[IPaddrlen];

	if(opendb() == nil){
		warning(1, "can't open db");
		return -1;
	}

	memset(iip, 0, sizeof(*iip));

	/* client knows its address? */
	v4tov6(ciaddr, bp->ciaddr);
	if(validip(ciaddr)){
		if(lookupip(ciaddr, iip, 0) < 0) {
			if (debug)
				warning(0, "don't know %I", ciaddr);
			return -1;	/* don't know anything about it */
		}
		if(!samenet(riip->ipaddr, iip)){
			warning(0, "%I not on %I", ciaddr, riip->ipnet);
			return -1;
		}

		/*
		 *  see if this is a masquerade, i.e., if the ether
		 *  address doesn't match what we expected it to be.
		 */
		if(memcmp(iip->etheraddr, zeroes, 6) != 0)
		if(memcmp(bp->chaddr, iip->etheraddr, 6) != 0)
			warning(0, "ciaddr %I rcvd from %E instead of %E",
				ciaddr, bp->chaddr, iip->etheraddr);

		return 0;
	}

	if(bp->hlen > Maxhwlen)
		return -1;
	switch(bp->htype){
	case 1:
		hwattr = "ether";
		hwval = hwbuf;
		snprint(hwbuf, sizeof(hwbuf), "%E", bp->chaddr);
		break;
	default:
		syslog(0, blog, "not ethernet %E, htype %d, hlen %d",
			bp->chaddr, bp->htype, bp->hlen);
		return -1;
	}

	/*
	 *  use hardware address to find an ip address on
	 *  same net as riip
	 */
	t = ndbsearch(db, &s, hwattr, hwval);
	while(t){
		for(nt = t; nt; nt = nt->entry){
			if(strcmp(nt->attr, "ip") != 0)
				continue;
			parseip(ciaddr, nt->val);
			if(lookupip(ciaddr, iip, 0) < 0)
				continue;
			if(samenet(riip->ipaddr, iip)){
				ndbfree(t);
				return 0;
			}
		}
		ndbfree(t);
		t = ndbsnext(&s, hwattr, hwval);
	}
	return -1;
}