Exemplo n.º 1
0
/*------------------------------------------------------------------------
 *  lsr_xmit - transmit pending Link State Request packets
 *------------------------------------------------------------------------
 */
int
lsr_xmit(struct ospf_if *pif, struct ospf_nb *pnb)
{
	struct	ep	*pephead, *pep;
	struct	ip	*pip;
	struct	ospf	*po;
	int		len;

	pephead = (struct ep *)headq(pnb->nb_lsrl);
	if (pephead == 0)
		return OK;
	pep = (struct ep *)getbuf(Net.netpool);
	if ((int)pep == SYSERR)
		return SYSERR;
	/* make a copy */
	pip = (struct ip *)pephead->ep_data;
	po = (struct ospf *)pip->ip_data;
	len = EP_HLEN + IPMHLEN + po->ospf_len;
	memcpy(pep, pephead, len);
	pip = (struct ip *)pep->ep_data;
	po = (struct ospf *)pip->ip_data;
	po->ospf_authtype = hs2net(pif->if_area->ar_authtype);
	memset(po->ospf_auth, 0, AUTHLEN);
	len = po->ospf_len;
	po->ospf_len = hs2net(po->ospf_len);
	pep->ep_order &= ~EPO_OSPF;
	po->ospf_cksum = 0;
	po->ospf_cksum = cksum((WORD *)po, len);
	memcpy(po->ospf_auth, pif->if_area->ar_auth, AUTHLEN);
	pip->ip_src = ip_anyaddr;
	ipsend(pnb->nb_ipa, pep, len, IPT_OSPF, IPP_INCTL, IP_TTL);
	pnb->nb_tlsr = pif->if_rintv;
	return OK;
}
Exemplo n.º 2
0
/*------------------------------------------------------------------------
 *  mkarp  -  allocate and fill in an ARP or RARP packet
 *------------------------------------------------------------------------
 */
static
struct ep *
mkarp(int ifn, short type, short op, IPaddr spa, IPaddr tpa)
{
	register struct	arp	*parp;
	struct	ep		*pep;

	pep = (struct ep *) getbuf(Net.netpool);
	if ((int)pep == SYSERR)
		return (struct ep *)SYSERR;
	memcpy(pep->ep_dst, nif[ifn].ni_hwb.ha_addr, EP_ALEN);
	pep->ep_order = ~0;
	pep->ep_type = type;
	parp = (struct arp *)pep->ep_data;
	parp->ar_hwtype = hs2net(AR_HARDWARE);
	parp->ar_prtype = hs2net(EPT_IP);
	parp->ar_hwlen = EP_ALEN;
	parp->ar_prlen = IP_ALEN;
	parp->ar_op = hs2net(op);
	memcpy(SHA(parp), nif[ifn].ni_hwa.ha_addr, EP_ALEN);
	memcpy(SPA(parp), &spa, IP_ALEN);
	memcpy(THA(parp), nif[ifn].ni_hwa.ha_addr, EP_ALEN);
	memcpy(TPA(parp), &tpa, IP_ALEN);
	return pep;
}
Exemplo n.º 3
0
/*------------------------------------------------------------------------
 *  iph2net - convert an IP packet header from host to net byte order
 *------------------------------------------------------------------------
 */
struct ip *
iph2net(struct ip *pip)
{
	/* NOTE: does not include IP options	*/

	pip->ip_len = hs2net(pip->ip_len);
	pip->ip_id = hs2net(pip->ip_id);
	pip->ip_fragoff = hs2net(pip->ip_fragoff);
	return pip;
}
Exemplo n.º 4
0
/*-------------------------------------------------------------------------
 * mon_bootp_request -
 *-------------------------------------------------------------------------
 */
int mon_bootp_request(int secs)
{
    struct bootp_msg bppacket;
    struct ep *pep;
    struct ip *pip;
    struct udp *pup;

    pep = (struct ep *)getbuf(mon_bufpool);
    if (pep == 0) {
#ifdef PRINTERR
	kprintf("bootp_request: !! no buffer\n");
#endif
	return SYSERR;
    }
    
    pip = (struct ip *)pep->ep_data;
    pup = (struct udp *)pip->ip_data;
   
    make_bootp_packet(&bppacket, secs);

    /* set the BOOTP data */
    blkcopy(pup->u_data, &bppacket, BOOTP_SIZE);

    /* now set the UDP header info */
    pup->u_src = hs2net(BOOTP_CPORT);
    pup->u_dst = hs2net(BOOTP_SPORT);
    pup->u_len = hs2net(U_HLEN + BOOTP_SIZE);
    pup->u_cksum = 0;

    
    /* now set the IP header info */
    pip->ip_proto = IPT_UDP;
    pip->ip_verlen = (IP_VERSION<<4) | IP_MINHLEN;
    pip->ip_tos = 0;
    pip->ip_len = hs2net(IPMHLEN + U_HLEN + BOOTP_SIZE);
    pip->ip_id = 0;
    pip->ip_fragoff = 0;
    pip->ip_ttl = IP_TTL;
    pip->ip_src = 0;
    pip->ip_dst = mon_ip_maskall;
    pip->ip_cksum = 0;
    pip->ip_cksum = mon_cksum(pip, IPMHLEN);

    /* now set the ethernet info */
    blkcopy(pep->ep_eh.eh_dst, EP_BRC, EP_ALEN);
    pep->ep_eh.eh_type = EPT_IP;
    return((mon_nif[0].ni_write)(pep, EP_HLEN+U_HLEN+IPMHLEN+BOOTP_SIZE));
}
Exemplo n.º 5
0
/*------------------------------------------------------------------------
 * ue_write - write a single packet to an SMC Ultra Ethernet
 *------------------------------------------------------------------------
 */
int
ue_write(struct devsw *pdev, unsigned char *pep0, unsigned len)
{
	struct ep	*pep = (struct ep *)pep0;
	struct utdev	*pud;

	pud = (struct utdev *)pdev->dvioblk;
	if (len > EP_MAXLEN) {
		nif[pud->ud_ifnum].ni_odiscard++;
		freebuf(pep);
		return SYSERR;
	}
	/* subtract the local header */
	len -= (int)&pep->ep_eh - (int)pep;
	if (len < EP_MINLEN)
		len = EP_MINLEN;
	memcpy(pep->ep_src, pud->ud_paddr, EP_ALEN);
	pep->ep_len = len;
	pep->ep_type = hs2net(pep->ep_type);
	pep->ep_order &= ~EPO_NET;
		
	if (enq(pud->ud_outq, pep, 0) < 0) {
		nif[pud->ud_ifnum].ni_odiscard++;
		freebuf(pep);
		ue_wstrt(pud);
		return SYSERR;
	}
	ue_wstrt(pud);
	return OK;
}
Exemplo n.º 6
0
/**
 * Send a UDP packet across the network to a certain destination
 * @param udpptr Pointer to UDP control block
 * @param datalen Length of data to be sent
 * @param buf Data to be sent
 * @return OK if packet is sent properly, otherwise SYSERR
 */
syscall udpSend(struct udp *udpptr, ushort datalen, void *buf)
{
    struct packet *pkt;
    struct udpPkt *udppkt = NULL;
    int result;

    pkt = netGetbuf();
    if (SYSERR == (int)pkt)
    {
        return SYSERR;
    }

    /* Set the length of the packet and set the curr pointer back that 
     * length */
    pkt->len = UDP_HDR_LEN + datalen;
    /* Round the datalength to maintain word alignment */
    pkt->curr -= (3 + (ulong)(pkt->len)) & ~0x03;

    /* Set UDP header fields and fill the packet with the data */
    udppkt = (struct udpPkt *)(pkt->curr);
    udppkt->srcPort = hs2net(udpptr->localpt);
    udppkt->dstPort = hs2net(udpptr->remotept);
    udppkt->len = hs2net(pkt->len);
    udppkt->chksum = 0;

    /* Zero out the data buffer so empty space is padded with zeroes */
    bzero(udppkt->data, datalen);
    memcpy(udppkt->data, buf, datalen);

    /* Calculate UDP checksum (which happens to be the same as TCP's) */
    udppkt->chksum = udpChksum(pkt, UDP_HDR_LEN + datalen,
                               &(udpptr->localip), &(udpptr->remoteip));

    /* Send the UDP packet through IP */
    result = ipv4Send(pkt, &(udpptr->localip), &(udpptr->remoteip),
                      IPv4_PROTO_UDP);

    if (SYSERR == netFreebuf(pkt))
    {
        return SYSERR;
    }

    return result;
}
Exemplo n.º 7
0
void udpdump(struct udp *pudp, int dlen, int order)
{
	int	u_sport, u_dport, u_udplen, u_ucksum;

	if (order & EPO_UDP) {
		u_sport = pudp->u_sport;
		u_dport = pudp->u_dport;
		u_udplen = pudp->u_udplen;
		u_ucksum = pudp->u_ucksum;
	} else {
		u_sport = hs2net(pudp->u_sport);
		u_dport = hs2net(pudp->u_dport);
		u_udplen = hs2net(pudp->u_udplen);
		u_ucksum = hs2net(pudp->u_ucksum);
	}
	kprintf("UDP:\tsrc %5u dst %5u len %d cksum %04x\n",
		u_sport, u_dport, u_udplen, u_ucksum);
	hexdump((uint8_t *)pudp+UHLEN, dlen - UHLEN);
}
Exemplo n.º 8
0
/**
 * Send an ICMP Echo (Ping) Request.
 * @param dst destination address
 * @param id  ping stream identifier
 * @param seq sequence number
 * @return OK if packet was sent, otherwise SYSERR
 */
syscall icmpEchoRequest(struct netaddr *dst, ushort id, ushort seq)
{
    struct packet *pkt = NULL;
    struct icmpEcho *echo = NULL;
    int result = OK;
    irqmask im;

    ICMP_TRACE("echo request(%d, %d)", id, seq);
    pkt = netGetbuf();
    if (SYSERR == (int)pkt)
    {
        ICMP_TRACE("Failed to acquire packet buffer");
        return SYSERR;
    }

    pkt->len = sizeof(struct icmpEcho);
    pkt->curr -= pkt->len;

    echo = (struct icmpEcho *)pkt->curr;
    echo->id = hs2net(id);
    echo->seq = hs2net(seq);
    /* Our optional data payload includes room for the departure */
    /*  and arrival timestamps, in seconds, milliseconds, and    */
    /*  clock cycles.                                            */
    im = disable();
    echo->timecyc = hl2net(clkcount());
    echo->timetic = hl2net(clkticks);
    echo->timesec = hl2net(clktime);
    restore(im);
    echo->arrivcyc = 0;
    echo->arrivtic = 0;
    echo->arrivsec = 0;

    ICMP_TRACE("Sending Echo Request id = %d, seq = %d, time = %d.%d",
               net2hs(echo->id), net2hs(echo->seq),
               net2hl(echo->timesec), net2hl(echo->timetic));

    result = icmpSend(pkt, ICMP_ECHO, 0, sizeof(struct icmpEcho), dst);
    netFreebuf(pkt);
    return result;
}
Exemplo n.º 9
0
//------------------------------------------------------------------------
//  udpsend  -  send one UDP datagram to a given (foreign) IP address
//------------------------------------------------------------------------
int
udpsend(IPaddr faddr, int fport, int lport, struct epacket *packet,
	int datalen)
{
	struct udp *udpptr;
	struct ip *ipptr;

	// Fill in UDP header; pass to ipsend to fill in IP header

	ipptr = (struct ip *)packet->ep_data;
	ipptr->i_proto = IPRO_UDP;
	udpptr = (struct udp *)ipptr->i_data;
	udpptr->u_sport = hs2net(lport);
	udpptr->u_dport = hs2net(fport);
	udpptr->u_udplen = hs2net(UHLEN + datalen);
	if (isodd(datalen))
		udpptr->u_data[datalen] = (char)0;
	udpptr->u_ucksum = 0;

	return ipsend(faddr, packet, UHLEN + datalen);
}
Exemplo n.º 10
0
static struct packet *makePkt(ushort localpt, ushort remotept,
                              struct netaddr *localip,
                              struct netaddr *remoteip, ushort datalen,
                              void *buf)
{
    struct packet *pkt;
    struct udpPkt *udppkt = NULL;

    pkt = netGetbuf();

    if (SYSERR == (int)pkt)
    {
        return (struct packet *)SYSERR;
    }

    /* Set the length of the packet and set the curr pointer back that 
     * length */
    pkt->len = UDP_HDR_LEN + datalen;
    /* Round the datalength to maintain word alignment */
    pkt->curr -= (3 + (ulong)(pkt->len)) & ~0x03;

    /* Set UDP header fields and fill the packet with the data */
    udppkt = (struct udpPkt *)(pkt->curr);
    udppkt->srcPort = hs2net(localpt);
    udppkt->dstPort = hs2net(remotept);
    udppkt->len = hs2net(pkt->len);
    udppkt->chksum = 0;

    /* Zero out the data buffer so empty space is padded with zeroes */
    bzero(udppkt->data, datalen);
    memcpy(udppkt->data, buf, datalen);

    udppkt->chksum = udpChksum(pkt, UDP_HDR_LEN + datalen,
                               localip, remoteip);

    return pkt;
}
Exemplo n.º 11
0
/*-------------------------------------------------------------------------
 * make_bootp_packet -
 *-------------------------------------------------------------------------
 */
static int make_bootp_packet(struct bootp_msg *bptr, int secs)
{
    bzero(bptr, BOOTP_SIZE);
    bptr->op = BOOTREQUEST;
    bptr->htype = AR_HARDWARE;
    bptr->hlen = EP_ALEN;
    bptr->xid = 47;             /* just a random number that's nonzero */
    bptr->secs = hs2net(secs);
    blkcopy(bptr->chaddr, (char *)&(mon_eth[0].ed_paddr), EP_ALEN);
    *(int *)bptr->vend = hl2net(RFC1084);
    bptr->vend[5] = 0xff;
#ifdef DEBUG
    kprintf("Using ethernet address %02x:%02x:%02x:%02x:%02x:%02x\n",
            bptr->chaddr[0], bptr->chaddr[1], bptr->chaddr[2],
            bptr->chaddr[3], bptr->chaddr[4], bptr->chaddr[5]);
#endif
    return(OK);
}
Exemplo n.º 12
0
/**
 * Send a TFTP RRQ (Read Request) packet over a UDP connection to the TFTP
 * server.  This instructs the TFTP server to begin sending the contents of the
 * specified file.  Not intended to be used outside of the TFTP code.
 *
 * @param udpdev
 *      Device descriptor for the open UDP device.
 * @param filename
 *      Name of the file to request.
 *
 * @return
 *      OK if packet sent successfully; SYSERR otherwise.
 */
syscall tftpSendRRQ(int udpdev, const char *filename)
{
    char *p;
    uint filenamelen;
    uint pktlen;
    struct tftpPkt pkt;

    /* Do sanity check on filename.  */
    filenamelen = strnlen(filename, 256);
    if (0 == filenamelen || 256 == filenamelen)
    {
        TFTP_TRACE("Filename is invalid.");
        return SYSERR;
    }

    TFTP_TRACE("RRQ \"%s\" (mode: octet)", filename);

    /* Set TFTP opcode to RRQ (Read Request).  */
    pkt.opcode = hs2net(TFTP_OPCODE_RRQ);

    /* Set up filename and mode.  */
    p = pkt.RRQ.filename_and_mode;
    memcpy(p, filename, filenamelen + 1);
    p += filenamelen + 1;
    memcpy(p, "octet", 6);
    p += 6;

    /* Write the resulting packet to the UDP device.  */
    pktlen = p - (char*)&pkt;
    if (pktlen != write(udpdev, &pkt, pktlen))
    {
        TFTP_TRACE("Error sending RRQ");
        return SYSERR;
    }
    return OK;
}
Exemplo n.º 13
0
/*------------------------------------------------------------------------
 *  ip2name  -  return DNS name for a host given its IP address
 *------------------------------------------------------------------------
 */
char	*
ip2name(IPaddr ip, char *nam)
{
	char	tmpstr[20];		/* temporary string buffer	*/
	char	*buf;			/* buffer to hold domain query	*/
	int	dg, i;
	register char	*p;
	register struct	dn_mesg *dnptr;

	dnptr = (struct dn_mesg *) (buf = (char *) getmem(DN_MLEN));
	*nam = NULLCH;
	dnptr->dn_id = 0;
	dnptr->dn_opparm = hs2net(DN_RD);
	dnptr->dn_qcount = hs2net(1);
	dnptr->dn_acount = dnptr->dn_ncount = dnptr->dn_dcount = 0;
	p = dnptr->dn_qaaa;

	/* Fill in question with  ip[3].ip[2].ip[1].ip[0].in-addr.arpa  */

	for (i=3 ; i >= 0 ; i--) {
		sprintf(tmpstr, "%u", ((char *)&ip)[i] & LOWBYTE);
		dn_cat(p, tmpstr);
	}

	dn_cat(p, "in-addr");
	dn_cat(p, "arpa");
	*p++ = NULLCH;	/* terminate name */

	/* Add query type and query class fields to name */

	( (struct dn_qsuf *)p )->dn_type = hs2net(DN_QTPR);
	( (struct dn_qsuf *)p )->dn_clas = hs2net(DN_QCIN);
	p += sizeof(struct dn_qsuf);

	/* Send query */

	dg = open(UDP, NSERVER, ANYLPORT);
	control(dg, DG_SETMODE, DG_DMODE | DG_TMODE);
	if (write (dg, buf, p - buf) == SYSERR)
		panic("ip2name write(%d) failed\n", dg);
	i = read(dg, buf, DN_MLEN);
	if (i == SYSERR)
		panic("ip2name read(%d) failed\n", dg);
	if (i == TIMEOUT) {
		close(dg);
		return ip2dot(nam, ip);
	}
	close(dg);
	if (net2hs(dnptr->dn_opparm) & DN_RESP ||
	    net2hs(dnptr->dn_acount) <= 0) {
		freemem(buf, DN_MLEN);
		return ip2dot(nam, ip);
	}

	/* In answer, skip name and remainder of resource record header	*/

	while (*p != NULLCH)
		if (*p & DN_CMPRS) 	/* compressed section of name	*/
			*++p = NULLCH;
		else
			p += *p + 1;
	p += DN_RLEN + 1;
	/* Copy name to user */
	*nam = NULLCH;
	while (*p != NULLCH) {
		if (*p & DN_CMPRS)
			p = buf + (net2hs(*(int *)p) & DN_CPTR);
		else {
			strncat(nam, p+1, *p);
			strcat(nam, ".");
			p += *p + 1;
		}
	}
	if (strlen(nam))	/* remove trailing dot */
		nam[strlen(nam) - 1] = NULLCH;
	else
		ip2dot(nam, ip);
	freemem(buf, DN_MLEN);
	return nam;
}
Exemplo n.º 14
0
/**
 * Sends a reset in response to an incorrect TCP packet
 * @param pkt incoming packet which requires a reset response
 * @param src source IP address of the packet	
 * @param dst destination IP address of the packet	
 */
int tcpSendRst(struct packet *pkt, struct netaddr *src,
               struct netaddr *dst)
{
    struct packet *out;
    struct tcpPkt *tcp;
    struct tcpPkt *outtcp;
    ushort datalen;
    int result;
    ushort tcplen;

    /* Setup packet pointers */
    tcp = (struct tcpPkt *)pkt->curr;
    tcplen = pkt->len - (pkt->curr - pkt->linkhdr);

    /* Verify not sending a reset in response to a reset */
    if (tcp->control & TCP_CTRL_RST)
    {
        return OK;
    }

    /* Get space to construct packet */
    out = netGetbuf();
    if (SYSERR == (int)out)
    {
        return SYSERR;
    }
    out->curr -= TCP_HDR_LEN;
    out->len += TCP_HDR_LEN;

    /* Set TCP header fields */
    outtcp = (struct tcpPkt *)out->curr;
    outtcp->srcpt = tcp->dstpt;
    outtcp->dstpt = tcp->srcpt;
    outtcp->offset = octets2offset(TCP_HDR_LEN);
    outtcp->control = TCP_CTRL_RST;
    if (tcp->control & TCP_CTRL_ACK)
    {
        outtcp->seqnum = tcp->acknum;
    }
    else
    {
        outtcp->seqnum = 0;
        outtcp->control |= TCP_CTRL_ACK;
    }
    datalen = tcplen - offset2octets(tcp->offset);
    if (tcp->control & TCP_CTRL_SYN)
    {
        datalen++;
    }
    if (tcp->control & TCP_CTRL_FIN)
    {
        datalen++;
    }
    outtcp->acknum = tcp->seqnum + datalen;

    /* Convert TCP header fields to net order */
    outtcp->srcpt = hs2net(outtcp->srcpt);
    outtcp->dstpt = hs2net(outtcp->dstpt);
    outtcp->seqnum = hl2net(outtcp->seqnum);
    outtcp->acknum = hl2net(outtcp->acknum);
    outtcp->window = hs2net(outtcp->window);
    outtcp->urgent = hs2net(outtcp->urgent);

    /* Calculate TCP checksum */
    outtcp->chksum = tcpChksum(out, TCP_HDR_LEN, src, dst);

    /* Send TCP packet */
    result = ipv4Send(out, src, dst, IPv4_PROTO_TCP);

    if (SYSERR == netFreebuf(out))
    {
        return SYSERR;
    }

    return result;
}
Exemplo n.º 15
0
static int ethloopn_test(bool verbose, int dev)
{
    bool passed = TRUE;
    bool subpass;
    uint memsize;
    int i, value, len;
    struct etherGram *inpkt;
    struct etherGram *outpkt;
    char *payload;
    char str[80];
    int devminor;
    struct ethloop *pelp;
    struct netaddr addr;
    device *pdev;

    pdev = (device *)&devtab[dev];
    devminor = pdev->minor;
    pelp = &elooptab[devminor];

    sprintf(str, "%s Open", pdev->name);
    testPrint(verbose, str);
    failif((SYSERR == open(dev)), "");

    /* Allocate temporary buffers.  */
    memsize = sizeof(struct etherGram) + MAX_PAYLOAD - 1;
    inpkt = memget(memsize);
    outpkt = memget(memsize);

    payload = &(outpkt->payload[0]);

    control(dev, NET_GET_HWADDR, (int)&addr, NULL);
    memcpy(outpkt->dst, addr.addr, addr.len);
    memcpy(outpkt->src, addr.addr, addr.len);
    outpkt->type_len = hs2net(ETH_TYPE_ARP);

    /* generate payload content */
    for (i = 0; i < MAX_PAYLOAD; i++)
    {
        /* Cycle through 0x20 to 0x7d (range of 0x5e) */
        value = (i % 0x5e) + 0x20;
        payload[i] = value;
    }

    /* oversized packet (paylod 1502 bytes + 14 byte header) */
    sprintf(str, "%s 1516 byte packet", pelp->dev->name);
    testPrint(verbose, str);
    len = write(dev, outpkt, 1516);
    failif((SYSERR != len), "");

    /* max packet (payload 1500 bytes + 14 byte header) */
    sprintf(str, "%s 1514 byte packet (write)", pelp->dev->name);
    testPrint(verbose, str);
    len = write(dev, outpkt, 1514);
    failif((len != 1514), "");

    sprintf(str, "%s 1514 byte packet (read)", pelp->dev->name);
    testPrint(verbose, str);
    bzero(inpkt, memsize);
    len = read(dev, inpkt, 1514);
    failif((len != 1514) || (0 != memcmp(outpkt, inpkt, 1514)), "");

    /* 'normal' packet (payload 686 bytes + 14 byte header) */
    sprintf(str, "%s  700 byte packet (write)", pelp->dev->name);
    testPrint(verbose, str);
    len = write(dev, outpkt, 700);
    failif((len != 700), "");

    sprintf(str, "%s  700 byte packet (read)", pelp->dev->name);
    testPrint(verbose, str);
    bzero(inpkt, memsize);
    len = read(dev, inpkt, 700);
    failif((len != 700) || (0 != memcmp(outpkt, inpkt, 700)), "");

    /* small packet (payload 16 bytes + 14 byte header) */
    sprintf(str, "%s   30 byte packet (write)", pelp->dev->name);
    testPrint(verbose, str);
    len = write(dev, outpkt, 30);
    failif((len != 30), "");

    sprintf(str, "%s   30 byte packet (read)", pelp->dev->name);
    testPrint(verbose, str);
    bzero(inpkt, memsize);
    len = read(dev, inpkt, 30);
    failif((len != 30) || (0 != memcmp(outpkt, inpkt, 30)), "");

    /* micro packet (12 bytes) */
    sprintf(str, "%s   12 byte packet", pelp->dev->name);
    testPrint(verbose, str);
    len = write(dev, outpkt, 12);
    failif((SYSERR != len), "");

    /* send 512 random sized packets */
    sprintf(str, "%s  512 random-sized packets", pelp->dev->name);
    testPrint(verbose, str);
    subpass = TRUE;

    for (i = 0; i < 512; i++)
    {
        len = 32 + (rand() % 1200);
        value = write(dev, outpkt, len);
        if (value != len)
        {
            subpass = FALSE;
        }

        bzero(inpkt, memsize);
        value = read(dev, inpkt, len);
        if ((value != len) || (0 != memcmp(outpkt, inpkt, len)))
        {
            subpass = FALSE;
        }
    }
    failif((TRUE != subpass), "");

    /* hold packet (payload 686 bytes + 14 byte header) */
    control(dev, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
    sprintf(str, "%s  700 byte packet (write hold)", pelp->dev->name);
    testPrint(verbose, str);
    len = write(dev, outpkt, 700);
    failif((len != 700), "");

    sprintf(str, "%s  700 byte packet (read hold)", pelp->dev->name);
    testPrint(verbose, str);
    bzero(inpkt, memsize);
    len = control(dev, ELOOP_CTRL_GETHOLD, (int)inpkt, 700);
    failif((0 != memcmp(outpkt, inpkt, 700)), "");

    /* drop packet (payload 686 bytes + 14 byte header) */
    control(dev, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_DROPNXT, NULL);
    sprintf(str, "%s  700 byte packet (write drop)", pelp->dev->name);
    testPrint(verbose, str);
    len = write(dev, outpkt, 700);
    failif((len != 700), "");

    sprintf(str, "%s  700 byte packet (write)", pelp->dev->name);
    testPrint(verbose, str);
    outpkt->dst[0] += 1;
    len = write(dev, outpkt, 700);
    failif((len != 700), "");

    sprintf(str, "%s  700 byte packet (read)", pelp->dev->name);
    testPrint(verbose, str);
    bzero(inpkt, memsize);
    len = read(dev, inpkt, 700);
    failif((len != 700) || (0 != memcmp(outpkt, inpkt, 700)), "");

    /* Free temporary buffers. */
    memfree(outpkt, memsize);
    memfree(inpkt, memsize);

    sprintf(str, "%s Close", pdev->name);
    testPrint(verbose, str);
    failif((SYSERR == close(dev)), "");

    return passed;
}
Exemplo n.º 16
0
/**
 * Fragments packet into maximum transmission unit sized chunks.
 * @param pkt the packet to fragment
 * @return OK
 */
syscall ipv4SendFrag(struct packet *pkt, struct netaddr *nxthop)
{
    uint ihl;
    uchar *data;
    uint dRem = 0;              // The amount of data remaining to be fragmented
    ushort froff;
    ushort lastFlag;
    ushort dLen;

    // Incoming packet structures
    struct ipv4Pkt *ip;

    // Outgoing packet structures
    struct ipv4Pkt *outip;
    struct packet *outpkt;

    IPv4_TRACE("Declaration");

    if (NULL == pkt)
    {
        return SYSERR;
    }

    // Setup incoming packet structures
    ip = (struct ipv4Pkt *)pkt->curr;

    if (net2hs(ip->len) <= pkt->nif->mtu)
    {
        IPv4_TRACE("NetSend");

        if (netaddrequal(&pkt->nif->ipbrc, nxthop))
        {
            IPv4_TRACE("Subnet Broadcast");
            return netSend(pkt, &NETADDR_GLOBAL_ETH_BRC,
                           nxthop, ETHER_TYPE_IPv4);
        }
        return netSend(pkt, NULL, nxthop, ETHER_TYPE_IPv4);
    }

    // Verify header does not have DF
    if (net2hs(ip->flags_froff) & IPv4_FLAG_DF)
    {
        IPv4_TRACE("net2hs of froff");
        /* Send ICMP message */
        icmpDestUnreach(pkt, ICMP_FOFF_DFSET);
        return SYSERR;
    }

    ihl = (ip->ver_ihl & IPv4_IHL) * 4;
    data = ((uchar *)ip) + ihl;
    dRem = net2hs(ip->len) - ihl;
    froff = net2hs(ip->flags_froff) & IPv4_FROFF;
    lastFlag = net2hs(ip->flags_froff) & IPv4_FLAGS;

    // Length of data in this packet will be MTU - header length,
    //  rounded down to nearest multiple of 8 bytes.
    dLen = (pkt->nif->mtu - ihl) & ~0x7;

    pkt->len = ihl + dLen;
    ip->len = hs2net(pkt->len);

    // Set more fragments flag
    ip->flags_froff = IPv4_FLAG_MF & froff;
    ip->flags_froff = hs2net(ip->flags_froff);

    ip->chksum = 0;
    ip->chksum = netChksum((uchar *)ip, ihl);

    netSend(pkt, NULL, nxthop, ETHER_TYPE_IPv4);
    dRem -= dLen;
    data += dLen;
    froff += (dLen / 8);

    // Get memory from stack for outgoing fragment
    outpkt = netGetbuf();

    if (SYSERR == (int)outpkt)
    {
        IPv4_TRACE("allocating outpkt");
        return SYSERR;
    }

    // Set up outgoing packet pointers and variables
    outpkt->curr -= pkt->nif->mtu;
    outip = (struct ipv4Pkt *)outpkt->curr;
    outpkt->nif = pkt->nif;

    memcpy(outip, ip, IPv4_HDR_LEN);

    // While packet must be fragmented
    while (dRem > 0)
    {
        if (((dRem + 7) & ~0x7) > pkt->nif->mtu + IPv4_HDR_LEN)
        {
            dLen = (pkt->nif->mtu - IPv4_HDR_LEN) & ~0x7;
        }
        else
        {
            dLen = dRem;
        }
        // Copy data segment
        memcpy(outip->opts, data, dLen);

        // Set more fragments flag
        if (dLen == dRem)
        {
            outip->flags_froff = lastFlag & froff;
        }
        else
        {
            outip->flags_froff = IPv4_FLAG_MF & froff;
        }
        outip->flags_froff = hs2net(outip->flags_froff);

        // Update fields
        outip->len = hs2net(IPv4_HDR_LEN + dLen);
        outip->chksum = 0;
        outip->chksum = netChksum((uchar *)outip, IPv4_HDR_LEN);

        // Update outgoing packet length
        outpkt->len = net2hs(outip->len);

        // Send fragment
        netSend(outpkt, NULL, nxthop, ETHER_TYPE_IPv4);

        dRem -= dLen;
        data += dLen;
        froff += (dLen / 8);
    }

    IPv4_TRACE("freeing outpkt");
    netFreebuf(outpkt);
    return OK;
}
Exemplo n.º 17
0
/**
 * Tests ARP.
 * @return OK when testing is complete
 */
thread test_arp(bool verbose)
{
    bool passed = TRUE;
    int i = 0;
    struct netaddr ip;
    struct netaddr mask;
    struct netaddr praddr;
    struct netaddr hwaddr;
    struct netaddr addrbuf;
    struct pcap_file_header pcap;
    struct pcap_pkthdr phdr;
    struct packet *pkt;
    struct netif *netptr;
    struct ethloop *pelp;
    uchar *data;
    uchar *request;
    struct arpPkt *arp;
    struct arpEntry *entry;
    uchar buf[ELOOP_BUFSIZE];
    int nproc;
    int nout;
    int wait;
    tid_typ tids[ARP_NTHRWAIT];
    tid_typ tid;
    irqmask im;

    enable();

    ip.type = NETADDR_IPv4;
    ip.len = IPv4_ADDR_LEN;
    ip.addr[0] = 192;
    ip.addr[1] = 168;
    ip.addr[2] = 1;
    ip.addr[3] = 6;

    mask.type = NETADDR_IPv4;
    mask.len = IPv4_ADDR_LEN;
    mask.addr[0] = 255;
    mask.addr[1] = 255;
    mask.addr[2] = 255;
    mask.addr[3] = 0;

    /* Initialize loopback ethernet and network interface */
    testPrint(verbose, "Test case initialization");

    data = (uchar *)(&_binary_data_testarp_pcap_start);
    memcpy(&pcap, data, sizeof(pcap));
    data += sizeof(pcap);

    if (SYSERR == open(ELOOP))
    {
        failif(TRUE, "");
    }
    else
    {
        failif((SYSERR == netUp(ELOOP, &ip, &mask, NULL)), "");
    }
    if (!passed)
    {
        testFail(TRUE, "");
        return OK;
    }

    /* Setup pointers to underlying structures */
#if NNETIF
    for (i = 0; i < NNETIF; i++)
    {
        if ((NET_ALLOC == netiftab[i].state)
            && (ELOOP == netiftab[i].dev))
        {
            break;
        }
    }
#endif
    netptr = &netiftab[i];
    pelp = &elooptab[devtab[ELOOP].minor];

    pkt = netGetbuf();
    if ((int)pkt != SYSERR)
    {
        pkt->nif = netptr;
    }

    praddr.type = NETADDR_IPv4;
    praddr.len = IPv4_ADDR_LEN;
    praddr.addr[0] = 192;
    praddr.addr[1] = 168;
    praddr.addr[2] = 1;
    praddr.addr[3] = 3;

    hwaddr.type = NETADDR_ETHERNET;
    hwaddr.len = ETH_ADDR_LEN;
    hwaddr.addr[0] = 0xAA;
    hwaddr.addr[1] = 0xBB;
    hwaddr.addr[2] = 0xCC;
    hwaddr.addr[3] = 0xDD;
    hwaddr.addr[4] = 0xEE;
    hwaddr.addr[5] = 0xFF;

    /* Test arpPkt structure */
    testPrint(verbose, "Header structure (Request)");
    /* Get 1st packet */
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    pkt = netGetbuf();
    pkt->len +=
        ARP_CONST_HDR_LEN + (2 * IPv4_ADDR_LEN) + (2 * ETH_ADDR_LEN);
    pkt->curr -= pkt->len;
    arp = (struct arpPkt *)pkt->curr;
    arp->hwtype = hs2net(ARP_HWTYPE_ETHERNET);
    arp->prtype = hs2net(ARP_PRTYPE_IPv4);
    arp->hwalen = ETH_ADDR_LEN;
    arp->pralen = IPv4_ADDR_LEN;
    arp->op = hs2net(ARP_OP_RQST);
    memcpy(&arp->addrs[ARP_ADDR_SHA(arp)], netptr->hwaddr.addr,
           arp->hwalen);
    memcpy(&arp->addrs[ARP_ADDR_SPA(arp)], netptr->ip.addr, arp->pralen);
    memcpy(&arp->addrs[ARP_ADDR_DPA(arp)], praddr.addr, arp->pralen);
    failif((0 != memcmp(data + ELOOP_LINKHDRSIZE, arp, pkt->len)), "");

    /* Test arpPkt structure */
    testPrint(verbose, "Header structure (Reply)");
    /* Get 2nd packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    arp->op = hs2net(ARP_OP_REPLY);
    memcpy(&arp->addrs[ARP_ADDR_DHA(arp)], &arp->addrs[ARP_ADDR_SHA(arp)],
           arp->hwalen);
    arp->addrs[ARP_ADDR_DHA(arp) + ETH_ADDR_LEN - 1] = 0xCC;
    memcpy(&arp->addrs[ARP_ADDR_DPA(arp)], praddr.addr, arp->pralen);
    memcpy(&arp->addrs[ARP_ADDR_SHA(arp)], netptr->hwaddr.addr,
           arp->hwalen);
    memcpy(&arp->addrs[ARP_ADDR_SPA(arp)], netptr->ip.addr, arp->pralen);
    failif((0 != memcmp(data + ELOOP_LINKHDRSIZE, arp, pkt->len)), "");

    /* Test arpAlloc, free entry exists */
    testPrint(verbose, "Allocate free entry");
    /* Make first entry used */
    arptab[0].state = ARP_USED;
    arptab[0].expires = clktime + ARP_TTL_UNRESOLVED;
    entry = arpAlloc();
    failif(((NULL == entry) || (entry == &arptab[0])
            || (0 == (entry->state & ARP_USED))), "");

    /* Test arpAlloc, free entry exists */
    testPrint(verbose, "Allocate used entry");
    arptab[1].state = ARP_USED;
    arptab[1].expires = clktime + 1;
    /* Make all entries (except the first 2) have ARP_TTL_RESOLVED */
    for (i = 2; i < ARP_NENTRY; i++)
    {
        arptab[i].state = ARP_USED;
        arptab[i].expires = clktime + ARP_TTL_RESOLVED;
    }
    entry = arpAlloc();
    failif(((NULL == entry) || (entry != &arptab[1])
            || (0 == (entry->state & ARP_USED))), "");

    /* Test arpNotify */
    testPrint(verbose, "Notify waiting threads (bad params)");
    failif((SYSERR != arpNotify(NULL, TIMEOUT)), "");

    /* Test arpNotify */
    testPrint(verbose, "Notify waiting threads");
    entry = &arptab[0];
    entry->state = ARP_UNRESOLVED;
    for (i = 0; i < ARP_NTHRWAIT; i++)
    {
        tid =
            create((void *)notifyTest, INITSTK, INITPRIO, "notifyTest",
                   0);
        tids[i] = tid;
        entry->waiting[i] = tid;
        entry->count++;
        ready(tid, RESCHED_NO);
    }
    recvclr();
    arpNotify(entry, ARP_MSG_RESOLVED);
    nout = FALSE;
    nproc = 0;
    tid = recvtime(100);
    while ((tid != TIMEOUT) && (nproc < ARP_NTHRWAIT))
    {
        for (i = 0; i < ARP_NTHRWAIT; i++)
        {
            if (tid == tids[i])
            {
                tids[i] = NULL;
            }
        }
        nproc++;
        tid = recvtime(100);
    }
    for (i = 0; i < ARP_NTHRWAIT; i++)
    {
        if (tids[i] != NULL)
        {
            kill(tids[i]);
            nout = TRUE;
        }
    }
    failif(nout || (entry->count != 0), "");

    /* Test arpFree */
    testPrint(verbose, "Free entry (bad params)");
    failif((SYSERR != arpFree(NULL)), "");

    /* Test arpFree */
    testPrint(verbose, "Free resolved entry");
    entry = &arptab[0];
    entry->state = ARP_RESOLVED;
    entry->expires = clktime;
    failif(((SYSERR == arpFree(entry)) || (entry->expires != 0)), "");

    /* Test arpFree */
    testPrint(verbose, "Free unresolved entry");
    entry = &arptab[0];
    entry->state = ARP_UNRESOLVED;
    for (i = 0; i < ARP_NTHRWAIT; i++)
    {
        tid = create((void *)freeTest, INITSTK, INITPRIO, "freeTest", 0);
        tids[i] = tid;
        entry->waiting[i] = tid;
        entry->count++;
        ready(tid, RESCHED_NO);
    }
    recvclr();
    if (SYSERR == arpFree(entry))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        nout = FALSE;
        nproc = 0;
        tid = recvtime(100);
        while ((tid != TIMEOUT) && (nproc < ARP_NTHRWAIT))
        {
            for (i = 0; i < ARP_NTHRWAIT; i++)
            {
                if (tid == tids[i])
                {
                    tids[i] = NULL;
                }
            }
            nproc++;
            tid = recvtime(100);
        }
        for (i = 0; i < ARP_NTHRWAIT; i++)
        {
            if (tids[i] != NULL)
            {
                kill(tids[i]);
                nout = TRUE;
            }
        }
        failif(nout || (entry->count != 0), "");
    }

    /* Test arpGetEntry */
    testPrint(verbose, "Get entry");
    for (i = 0; i < ARP_NENTRY; i++)
    {
        arpFree(&arptab[i]);
    }
    nout = 4;
    if (ARP_NENTRY < nout)
    {
        nout = ARP_NENTRY;
    }
    for (i = 1; i < nout; i++)
    {
        entry = &arptab[i];
        entry->state = ARP_RESOLVED;
        entry->nif = netptr;
        praddr.addr[3] = i + 1;
        hwaddr.addr[5] = ((i + 0xA) << 4) + (i + 0xA);
        netaddrcpy(&entry->hwaddr, &hwaddr);
        netaddrcpy(&entry->praddr, &praddr);
        entry->expires = clktime + ARP_TTL_RESOLVED;
    }
    for (i = 1; i < nout; i++)
    {
        praddr.addr[3] = i + 1;
        entry = arpGetEntry(&praddr);
        if (entry != &arptab[i])
        {
            break;
        }
    }
    failif((i != nout), "");

    /* Test arpGetEntry with timeout */
    testPrint(verbose, "Get entry (timeout entries)");
    arptab[i].expires = clktime - 1;
    praddr.addr[3] = 2;
    entry = arpGetEntry(&praddr);
    if (entry != &arptab[1])
    {
        failif(TRUE, "Incorrect entry");
    }
    else
    {
        failif((arptab[0].state != ARP_FREE),
               "Did not free expired entry");
    }
    for (i = 0; i < ARP_NENTRY; i++)
    {
        arpFree(&arptab[i]);
    }

    /* Test receive reply for non-existing ARP table entry */
    testPrint(verbose, "Receive ARP reply, new entry");
    /* Get 3rd packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    praddr.addr[3] = 3;
    hwaddr.addr[5] = 0xCC;
    nout = pelp->nout;
    nproc = netptr->nproc;
    write(ELOOP, data, phdr.caplen);
    /* Wait until packet is processed */
    wait = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(10);
    }
    if (MAX_WAIT == wait)
    {
        failif(TRUE, "Wait time expired");
    }
    else
    {
        /* Check entry and ensure reply was not sent */
        entry = NULL;
        for (i = 0; i < ARP_NENTRY; i++)
        {
            if (ARP_RESOLVED == arptab[i].state)
            {
                entry = &arptab[i];
                break;
            }
        }
        if (NULL == entry)
        {
            failif(TRUE, "No entry inserted");
        }
        else if ((FALSE == netaddrequal(&praddr, &entry->praddr))
                 || (FALSE == netaddrequal(&hwaddr, &entry->hwaddr))
                 || (entry->nif != netptr) || (entry->count != 0))
        {
            failif(TRUE, "Entry incorrect");
        }
        else if (pelp->nout > (nout + 1))
        {
            failif(TRUE, "Reply sent to reply");
        }
        else
        {
            failif(FALSE, "");
        }
    }

    /* Test receive request for non-existing ARP table entry */
    testPrint(verbose, "Receive ARP request, new entry");
    /* Get 4th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    praddr.addr[3] = 1;
    hwaddr.addr[5] = 0xAA;
    nout = pelp->nout;
    nproc = netptr->nproc;
    im = disable();
    write(ELOOP, data, phdr.caplen);
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
    restore(im);
    /* Wait until packet is processed */
    wait = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(100);
    }
    if (MAX_WAIT == wait)
    {
        failif(TRUE, "Wait time expired");
    }
    else
    {
        /* Check entry and ensure reply was not sent */
        entry = NULL;
        for (i = 0; i < ARP_NENTRY; i++)
        {
            if ((ARP_RESOLVED == arptab[i].state)
                && (netaddrequal(&praddr, &arptab[i].praddr)))
            {
                entry = &arptab[i];
                break;
            }
        }
        if (NULL == entry)
        {
            failif(TRUE, "No entry inserted");
        }
        else if ((FALSE == netaddrequal(&praddr, &entry->praddr))
                 || (FALSE == netaddrequal(&hwaddr, &entry->hwaddr))
                 || (entry->nif != netptr) || (entry->count != 0))
        {
            failif(TRUE, "Entry incorrect");
        }
        else
        {
            control(ELOOP, ELOOP_CTRL_GETHOLD, (int)buf, ELOOP_BUFSIZE);
            /* Get 5th packet */
            data += phdr.caplen;
            memcpy(&phdr, data, sizeof(phdr));
            data += sizeof(phdr);
            if (PCAP_MAGIC != pcap.magic)
            {
                phdr.caplen = endswap(phdr.caplen);
            }
            failif((memcmp(data, buf, phdr.caplen) != 0),
                   "Invalid reply");
        }
    }

    /* Test receive request for non-supported hardware type */
    testPrint(verbose, "Receive ARP request, bad HW type");
    /* Get 6th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    praddr.addr[3] = 2;
    hwaddr.addr[5] = 0xBB;
    nproc = netptr->nproc;
    write(ELOOP, data, phdr.caplen);
    /* Wait until packet is processed */
    wait = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(100);
    }
    if (MAX_WAIT == wait)
    {
        failif(TRUE, "Wait time expired");
    }
    else
    {
        /* Ensure entry was not added */
        entry = NULL;
        for (i = 0; i < ARP_NENTRY; i++)
        {
            if ((ARP_RESOLVED == arptab[i].state)
                && (netaddrequal(&praddr, &arptab[i].praddr)))
            {
                entry = &arptab[i];
                break;
            }
        }
        failif((entry != NULL), "Entry inserted");
    }

    /* Test receive reply for non-supported protocol type */
    testPrint(verbose, "Receive ARP reply, bad protocol type");
    /* Get 7th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    nproc = netptr->nproc;
    write(ELOOP, data, phdr.caplen);
    /* Wait until packet is processed */
    wait = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(100);
    }
    if (MAX_WAIT == wait)
    {
        failif(TRUE, "Wait time expired");
    }
    else
    {
        /* Ensure entry was not added */
        entry = NULL;
        for (i = 0; i < ARP_NENTRY; i++)
        {
            if ((ARP_RESOLVED == arptab[i].state)
                && (netaddrequal(&praddr, &arptab[i].praddr)))
            {
                entry = &arptab[i];
                break;
            }
        }
        failif((entry != NULL), "Entry inserted");
    }

    /* Test receive reply for existing resolved ARP table entry */
    testPrint(verbose, "Receive ARP reply, resolved entry");
    /* Get 8th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    praddr.addr[3] = 3;
    hwaddr.addr[5] = 0x0C;
    nout = pelp->nout;
    nproc = netptr->nproc;
    write(ELOOP, data, phdr.caplen);
    /* Wait until packet is processed */
    wait = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(100);
    }
    if (MAX_WAIT == wait)
    {
        failif(TRUE, "Wait time expired");
    }
    else
    {
        /* Check entry */
        entry = NULL;
        for (i = 0; i < ARP_NENTRY; i++)
        {
            if ((ARP_RESOLVED == arptab[i].state)
                && (netaddrequal(&praddr, &arptab[i].praddr)))
            {
                entry = &arptab[i];
                break;
            }
        }
        failif((FALSE == netaddrequal(&hwaddr, &entry->hwaddr)),
               "Entry incorrect");
    }

    /* Test receive request not for me */
    testPrint(verbose, "Receive ARP request, not mine");
    /* Get 9th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    praddr.addr[3] = 4;
    hwaddr.addr[5] = 0xDD;
    nproc = netptr->nproc;
    write(ELOOP, data, phdr.caplen);
    /* Wait until packet is processed */
    wait = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(100);
    }
    if (MAX_WAIT == wait)
    {
        failif(TRUE, "Wait time expired");
    }
    else
    {
        /* Ensure entry was not added */
        entry = NULL;
        for (i = 0; i < ARP_NENTRY; i++)
        {
            if ((ARP_RESOLVED == arptab[i].state)
                && (netaddrequal(&praddr, &arptab[i].praddr)))
            {
                entry = &arptab[i];
                break;
            }
        }
        failif((entry != NULL), "Entry inserted");
    }

    /* Test arpSendRequest */
    testPrint(verbose, "Send ARP request (bad params)");
    failif((SYSERR != arpSendRqst(NULL)), "");

    /* Test arpSendRequest */
    testPrint(verbose, "Send ARP request");
    /* Get 10th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    entry = &arptab[0];
    entry->state = ARP_UNRESOLVED;
    entry->nif = netptr;
    praddr.addr[3] = 2;
    hwaddr.addr[5] = 0xBB;
    netaddrcpy(&entry->hwaddr, &hwaddr);
    netaddrcpy(&entry->praddr, &praddr);
    entry->expires = clktime + ARP_TTL_UNRESOLVED;
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
    if (SYSERR == arpSendRqst(entry))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        control(ELOOP, ELOOP_CTRL_GETHOLD, (int)buf, ELOOP_BUFSIZE);
        failif((memcmp(buf, data, phdr.caplen) != 0), "");
    }

    /* Test arpLookup */
    testPrint(verbose, "Lookup address (bad params)");
    failif((SYSERR != arpLookup(NULL, NULL, NULL)), "");

    /* Test arpLookup */
    testPrint(verbose, "Lookup existing resolved address");
    for (i = 0; i < ARP_NENTRY; i++)
    {
        arpFree(&arptab[i]);
    }
    entry = &arptab[0];
    entry->state = ARP_RESOLVED;
    entry->nif = netptr;
    praddr.addr[3] = 1;
    hwaddr.addr[5] = 0xAA;
    netaddrcpy(&entry->hwaddr, &hwaddr);
    netaddrcpy(&entry->praddr, &praddr);
    entry->expires = clktime + ARP_TTL_UNRESOLVED;
    i = arpLookup(netptr, &praddr, &addrbuf);
    if ((SYSERR == i) || (TIMEOUT == i))
    {
        failif(TRUE, "Returned SYSERR or TIMEOUT");
    }
    else
    {
        failif((FALSE == netaddrequal(&addrbuf, &hwaddr)),
               "Wrong address");
    }

    /* Test arpLookup */
    testPrint(verbose, "Lookup existing unresolved address");
    entry = &arptab[1];
    entry->state = ARP_UNRESOLVED;
    entry->nif = netptr;
    praddr.addr[3] = 2;
    hwaddr.addr[5] = 0xBB;
    netaddrcpy(&entry->hwaddr, &hwaddr);
    netaddrcpy(&entry->praddr, &praddr);
    entry->expires = clktime + ARP_TTL_UNRESOLVED;
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
    request = data;
    wait = phdr.caplen;
    /* Get 11th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    tid =
        ready(create
              ((void *)lookupTest, INITSTK, INITPRIO, "lookupTest", 4,
               request, wait, data, phdr.caplen), RESCHED_NO);
    i = arpLookup(netptr, &praddr, &addrbuf);
    if ((SYSERR == i) || (TIMEOUT == i))
    {
        kill(tid);
        failif(TRUE, "Returned SYSERR or TIMEOUT");
    }
    else
    {
        failif((FALSE == netaddrequal(&addrbuf, &hwaddr)),
               "Wrong address");
    }

    /* Test arpLookup */
    testPrint(verbose, "Lookup max threads wait for resolve");
    entry->state = ARP_UNRESOLVED;
    entry->count = ARP_NTHRWAIT;
    failif((arpLookup(netptr, &praddr, &addrbuf) != SYSERR), "");

    /* Test arpLookup */
    testPrint(verbose, "Lookup non-existing unresolved addr");
    praddr.addr[3] = 3;
    hwaddr.addr[5] = 0xCC;
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
    request = data;
    wait = phdr.caplen;
    /* Get 12th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    request = data;
    wait = phdr.caplen;
    /* Get 13th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    tid =
        ready(create
              ((void *)lookupTest, INITSTK, INITPRIO, "lookupTest", 4,
               request, wait, data, phdr.caplen), RESCHED_NO);
    i = arpLookup(netptr, &praddr, &addrbuf);
    if ((SYSERR == i) || (TIMEOUT == i))
    {
        kill(tid);
        failif(TRUE, "Returned SYSERR or TIMEOUT");
    }
    else
    {
        failif((FALSE == netaddrequal(&addrbuf, &hwaddr)),
               "Wrong address");
    }

    /* Test arpLookup */
    testPrint(verbose, "Lookup timeout");
    praddr.addr[3] = 4;
    hwaddr.addr[5] = 0xDD;
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_DROPALL, NULL);
    failif((SYSERR != arpLookup(netptr, &praddr, &addrbuf)), "");

    /* Stop loopback ethernet and network interface */
    testPrint(verbose, "Test case cleanup");
    for (i = 0; i < ARP_NENTRY; i++)
    {
        arpFree(&arptab[i]);
    }
    failif(((SYSERR == netFreebuf(pkt)) || (SYSERR == netDown(ELOOP))
            || (SYSERR == close(ELOOP))), "");

    if (passed)
    {
        testPass(TRUE, "");
    }
    else
    {
        testFail(TRUE, "");
    }

    return OK;
}
Exemplo n.º 18
0
/*------------------------------------------------------------------------
 *  gname  -  use the DNS to look up the name
 *------------------------------------------------------------------------
 */
static IPaddr
gname(char *nam)
{
    IPaddr	ip;
    char	tmpstr[64];		/* temporary string buffer	*/
    char	*buf;			/* buffer to hold domain query	*/
    int	dg, i;
    register char	*p, *p2, *p3;
    register struct	dn_mesg *dnptr;

    dnptr = (struct dn_mesg *) (buf = (char *) getmem(DN_MLEN));
    dnptr->dn_id = 0;
    dnptr->dn_opparm = hs2net(DN_RD);
    dnptr->dn_qcount = hs2net(1);
    dnptr->dn_acount = dnptr->dn_ncount = dnptr->dn_dcount = 0;
    p = dnptr->dn_qaaa;

    strcpy(tmpstr, nam);
    p2 = tmpstr;
    while (p3=index(p2, '.')) {
        *p3 = '\0';
        dn_cat(p, p2);
        p2 = p3+1;
    }
    dn_cat(p, p2);
    *p++ = NULLCH;	/* terminate name */

    /* Add query type and query class fields to name */

    ( (struct dn_qsuf *)p )->dn_type = hs2net(DN_QTHA);
    ( (struct dn_qsuf *)p )->dn_clas = hs2net(DN_QCIN);
    p += sizeof(struct dn_qsuf);

    /* send query */

    dg = open(UDP, NSERVER, ANYLPORT);
    control(dg, DG_SETMODE, DG_DMODE | DG_TMODE);
    write (dg, buf, p - buf);
    if ( (i = read(dg, buf, DN_MLEN)) == SYSERR || i == TIMEOUT) {
        close(dg);
        freemem(buf, DN_MLEN);
        return (IPaddr)SYSERR;
    }
    close(dg);
    if (net2hs(dnptr->dn_opparm) & DN_RESP ||
            net2hs(dnptr->dn_acount) <= 0) {
        freemem(buf, DN_MLEN);
        return (IPaddr)SYSERR;
    }
    /* In answer, skip name and remainder of resource record header	*/

    while (*p != NULLCH)
        if (*p & DN_CMPRS) 	/* compressed section of name	*/
            *++p = NULLCH;
        else
            p += *p + 1;
    p += DN_RLEN + 1;

    /* Copy IP to user */

    for (i=0; i < IP_ALEN; ++i)
        ((char *)&ip)[i] = *p++;
    freemem(buf, DN_MLEN);
    return ip;
}
Exemplo n.º 19
0
/**
 * Sends an ARP request for an ARP table entry over a network interface. 
 * @param entry ARP table entry
 * @return OK if packet was sent, otherwise SYSERR
 */
syscall arpSendRqst(struct arpEntry *entry)
{
    struct netif *netptr = NULL;
    struct packet *pkt = NULL;
    struct arpPkt *arp = NULL;
    int result;

    /* Error check pointers */
    if (NULL == entry)
    {
        return SYSERR;
    }

    ARP_TRACE("Sending ARP request");

    /* Setup pointer to network interface */
    netptr = entry->nif;

    /* Obtain a buffer for the packet */
    pkt = netGetbuf();
    if (SYSERR == (int)pkt)
    {
        ARP_TRACE("Failed to acquire packet buffer");
        return SYSERR;
    }

    /* Place ARP header at end of packet buffer */
    pkt->nif = netptr;
    pkt->len =
        ARP_CONST_HDR_LEN + netptr->hwaddr.len * 2 + netptr->ip.len * 2;
    pkt->curr -= pkt->len;
    arp = (struct arpPkt *)pkt->curr;

    /* Fill in ARP header */
    arp->hwtype = hs2net(netptr->hwaddr.type);
    arp->prtype = hs2net(netptr->ip.type);
    arp->hwalen = netptr->hwaddr.len;
    arp->pralen = netptr->ip.len;
    arp->op = hs2net(ARP_OP_RQST);
    ARP_TRACE("Filled in types, lens, and op");
    memcpy(&arp->addrs[ARP_ADDR_SHA(arp)], netptr->hwaddr.addr,
           arp->hwalen);
    memcpy(&arp->addrs[ARP_ADDR_SPA(arp)], netptr->ip.addr, arp->pralen);
    memcpy(&arp->addrs[ARP_ADDR_DPA(arp)], entry->praddr.addr,
           arp->pralen);
    ARP_TRACE("Filled in addrs");

    /* Send packet */
    result = netSend(pkt, &netptr->hwbrc, NULL, ETHER_TYPE_ARP);

    ARP_TRACE("Sent packet");

    /* Free buffer for the packet */
    if (SYSERR == netFreebuf(pkt))
    {
        ARP_TRACE("Failed to free packet buffer");
        return SYSERR;
    }

    /* Return result of netSend */
    return result;
}
Exemplo n.º 20
0
/* returns 0 upon success; -1 upon error                                  */
int sntp_request_time(PFBYTE ip_sntp_server, int *socket_no, 
                  PNTP_TIME_FORMAT current_timestamp,
                  int version, int mode, dword *ticks_when_sent,
                  PEBSTIME res_ebs_tod)
{
NTP_PKT ntp_request;
struct sockaddr_in sin;
int len;

    /* Allocate a socket   */
    if ( (*socket_no = socket(AF_INET, SOCK_DGRAM, 0)) < 0 )
    {
        DEBUG_ERROR("sntp_request_time: socket failed", EBS_INT1, 
            xn_getlasterror(), 0);
        return(-1);
    }

    /* Bind my ip address port NTP port   */
    sin.sin_family = AF_INET;
#if !CFG_UNIX_COMPLIANT_SOCK_STRUCTS           
    sin.sin_addr = INADDR_ANY;
#else
    sin.sin_addr.s_addr = INADDR_ANY;
#endif
    sin.sin_port = hs2net(NTP_PORT);
    if (bind(*socket_no, (PSOCKADDR)&sin, sizeof(sin)) < 0)
    {
        DEBUG_ERROR("sntp_request_time: bind failed", EBS_INT1, 
            xn_getlasterror(), 0);
        closesocket(*socket_no);
        return(-1);
    }

    /* Connect to remote NTP server   */
    tc_mv4((PFBYTE)&sin.sin_addr, ip_sntp_server, IP_ALEN);
    if (connect(*socket_no, (PSOCKADDR)&sin, sizeof(sin)) < 0)
    {
        DEBUG_ERROR("sntp_request_time: connect failed", EBS_INT1, 
            xn_getlasterror(), 0);
        closesocket(*socket_no);
        return(-1);
    }

    /* format request   */
    tc_memset((PFBYTE)&ntp_request, 0, sizeof(NTP_PKT));
    ntp_request.li_vn_mode = (byte)mode;
    ntp_request.li_vn_mode |= version;
    ntp_request.poll = 6;

    /* get current time of day from ostime.c   */
    convert_ebs_time_to_time(res_ebs_tod, current_timestamp);

    *ticks_when_sent = ks_get_ticks();
#if (DEBUG_DELAY_TICKS)
    DEBUG_ERROR("ticks_when_sent set to : ", DINT1, *ticks_when_sent, 0);
#endif

    /* send request   */
    if ((len=send(*socket_no, (PFCHAR)&ntp_request, sizeof(NTP_PKT), 0)) < 
                  sizeof(NTP_PKT))
    {
        if (len < 0)
        {
            DEBUG_ERROR("sntp_request_time: send failed", EBS_INT1, 
                xn_getlasterror(), 0);
            closesocket(*socket_no);
            return(-1);
        }
        else
        {
            DEBUG_ERROR("sntp_request_time: sent less bytes: exp, act:", EBS_INT2, 
                sizeof(NTP_PKT), len);
        }
    }
    return(0);
}