示例#1
0
/**
 * Shell command (netdown) to stop a network interface.
 * @param nargs  number of arguments in args array
 * @param args   array of arguments
 * @return OK for success, SYSERR for syntax error
 */
shellcmd xsh_netdown(int nargs, char *args[])
{
    int descrp;

    /* Enable interrupts */
    enable();

    /* Help */
    if ((2 == nargs) && (0 == strncmp(args[1], "--help", 7)))
    {
        printf("Usage:\n");
        printf("\t%s <DEVICE>\n", args[0]);
        printf("Description:\n");
        printf
            ("\tStops a network interface on the specified underlying\n");
        printf("\tdevice.\n");
        printf("Options:\n");
        printf("\t<DEVICE>\tunderlying device (ex. ETH0)\n");
        printf("\t--help\t\tdisplay this help and exit\n");
        return SHELL_OK;
    }

    /* Verify number of arguments */
    if (nargs != 2)
    {
        fprintf(stderr, "Invalid number of arguments\n");
        return SHELL_ERROR;
    }

    /* Parse device */
    descrp = getdev(args[1]);
    if (SYSERR == descrp)
    {
        fprintf(stderr, "%s is not a valid device.\n", args[1]);
        return SHELL_ERROR;
    }

    if (SYSERR == netDown(descrp))
    {
        fprintf(stderr, "Failed to stop network interface on %s\n",
                args[1]);
        return SHELL_ERROR;
    }

    return SHELL_OK;
}
示例#2
0
文件: test_ip.c 项目: JamesLinus/xinu
thread test_ip(bool verbose)
{
#if NETHER
    struct netaddr dst;
    struct netaddr src;
    struct netaddr mask;
    struct netif *netptr;
    struct pcap_file_header pcap;
    struct pcap_pkthdr phdr;
    struct packet *pktA;
    struct packet *pktB;
    uchar *data;
    uchar buf[500];
    int i;
    int nproc;
    int wait;
    bool passed = TRUE;

    src.type = NETADDR_IPv4;
    src.len = IPv4_ADDR_LEN;
    dst.type = NETADDR_IPv4;
    dst.len = IPv4_ADDR_LEN;
    mask.type = NETADDR_IPv4;
    mask.len = IPv4_ADDR_LEN;

    src.addr[0] = 192;
    src.addr[1] = 168;
    src.addr[2] = 1;
    src.addr[3] = 6;

    dst.addr[0] = 192;
    dst.addr[1] = 168;
    dst.addr[2] = 1;
    dst.addr[3] = 1;

    mask.addr[0] = 255;
    mask.addr[1] = 255;
    mask.addr[2] = 255;
    mask.addr[3] = 0;

    testPrint(verbose, "Initialization");
    sleep(500);
    if (SYSERR == open(ELOOP))
    {
        failif(TRUE, "Open returned SYSERR");
    }
    else
    {
        if (SYSERR == netUp(ELOOP, &src, &mask, &dst))
        {
            failif(TRUE, "netUp returned SYSERR");
        }
        else
        {
            netptr = NULL;
            for (i = 0; i < NNETIF; i++)
            {
                if (ELOOP == netiftab[i].dev)
                {
                    netptr = &netiftab[i];
                    break;
                }
            }
            pktA = netGetbuf();
            pktB = netGetbuf();
            failif(((NULL == netptr)
                    || (SYSERR == (int)pktA)
                    || (SYSERR == (int)pktB)),
                   "Buffer allocation failed");
        }
    }
    if (!passed)
    {
        testFail(TRUE, "");
        return OK;
    }

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

    testPrint(verbose, "Ipv4Send");
    /* Get 1st Packet */
    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 = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(10);
    }
    if (MAX_WAIT == wait)
    {
        failif(TRUE, "Wait time expired");
    }
    else
    {
        /* Get 2nd Packet */
        data += phdr.caplen;
        memcpy(&phdr, data, sizeof(phdr));
        data += sizeof(phdr);
        if (PCAP_MAGIC != pcap.magic)
        {
            phdr.caplen = endswap(phdr.caplen);
        }
        memcpy(pktA->data, data, phdr.caplen);
        pktA->len = phdr.caplen;
        pktA->nif = netptr;
        pktA->linkhdr = pktA->data;
        pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
        pktA->curr = pktA->nethdr + IPv4_HDR_LEN;

        pktB->curr -= UDP_HDR_LEN + 4;
        pktB->len += UDP_HDR_LEN + 4;
        memcpy(pktB->curr, pktA->curr, pktB->len);

        control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);

        if (OK != ipv4Send(pktB, &src, &dst, IPv4_PROTO_UDP))
        {
            failif(TRUE, "ipv4Send didn't return okay");
        }
        else
        {
            control(ELOOP, ELOOP_CTRL_GETHOLD, (long)buf, 500);
            failif(0 != memcmp(buf, pktA->linkhdr, pktA->len), "");
        }
    }

    /* ipv4Recv Testing */
    //TODO: Finish ipv4Recv
/*	testPrint(verbose, "ipv4Recv");
	pktA->curr -= IPv4_HDR_LEN;

	if (SYSERR == rawOpen(RAW0, IPv4_PROTO_UDP, ))
    {
        failif(TRUE, "Open returned SYSERR");
    }

	

	if (OK != ipv4Recv(pktA))
	{
		failif(TRUE, "Didn't return okay");
	}
	else
	{
	}
*/
    netDown(ELOOP);
    close(ELOOP);

    /* always print out the overall tests status */
    if (passed)
    {
        testPass(TRUE, "");
    }
    else
    {
        testFail(TRUE, "");
    }
#else /* NETHER */
    testSkip(TRUE, "");
#endif /* NETHER == 0 */
    return OK;
}
示例#3
0
/**
 * Test for snoop.
 */
thread test_snoop(bool verbose)
{
    bool passed = TRUE;
    struct snoop cap;
    struct netaddr dst;
    struct netaddr src;
    struct netaddr mask;
    struct netif *netptr;
    struct pcap_file_header pcap;
    struct pcap_pkthdr phdr;
    struct packet *pktA;
    struct packet *pktB;
    uchar *data;
    int i;
    uint nmatch;

    src.len = IPv4_ADDR_LEN;
    src.type = NETADDR_IPv4;
    dst.len = IPv4_ADDR_LEN;
    dst.type = NETADDR_IPv4;
    mask.len = IPv4_ADDR_LEN;
    mask.type = NETADDR_IPv4;

    src.addr[0] = 192;
    src.addr[1] = 168;
    src.addr[2] = 1;
    src.addr[3] = 6;

    dst.addr[0] = 192;
    dst.addr[1] = 168;
    dst.addr[2] = 1;
    dst.addr[3] = 1;

    /* Initialization */
    testPrint(verbose, "Test case initialization");
    pktA = netGetbuf();
    failif((SYSERR == (int)pktA), "Failed get buffer");
    if (!passed)
    {
        testFail(TRUE, "");
        return OK;
    }

    /* Test filter */

    /* Filter type */
    testPrint(verbose, "Filter type");
    bzero(&cap, sizeof(struct snoop));
    cap.caplen = USHRT_MAX;
    cap.type = SNOOP_FILTER_ARP;
    failif((7 != filterTest(&cap, pktA)), "");

    /* Test open */
    testPrint(verbose, "Open capture (bad params)");
    bzero(&cap, sizeof(struct snoop));
    failif((SYSERR != snoopOpen(NULL, NULL)), "");

    testPrint(verbose, "Open capture (bad device)");
    failif((SYSERR != snoopOpen(&cap, "crap")), "");

    testPrint(verbose, "Open capture all (no netif)");
    failif((SYSERR != snoopOpen(&cap, "ALL")), "");

    src.addr[0] = 192;
    src.addr[1] = 168;
    src.addr[2] = 1;
    src.addr[3] = 6;

    dst.addr[0] = 192;
    dst.addr[1] = 168;
    dst.addr[2] = 1;
    dst.addr[3] = 1;

    mask.addr[0] = 192;
    mask.addr[1] = 168;
    mask.addr[2] = 1;
    mask.addr[3] = 1;

    open(ELOOP);
    netUp(ELOOP, &src, &dst, &mask);

    testPrint(verbose, "Open capture all");
    if (SYSERR == snoopOpen(&cap, "ALL"))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        for (i = 0; i < NNETIF; i++)
        {
            if ((NET_ALLOC == netiftab[i].state)
                && (NULL == netiftab[i].capture))
            {
                break;
            }
        }
        failif((i < NNETIF), "Not attached to all");
    }

    testPrint(verbose, "Close capture (bad params)");
    failif((SYSERR != snoopClose(NULL)), "");

    testPrint(verbose, "Close capture");
    if (SYSERR == snoopClose(&cap))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        for (i = 0; i < NNETIF; i++)
        {
            if (&cap == netiftab[i].capture)
            {
                break;
            }
        }
        failif((i < NNETIF), "Not removed from all");
    }
    testPrint(verbose, "Open capture on ELOOP");
    bzero(&cap, sizeof(struct snoop));
    netptr = NULL;
    if (SYSERR == snoopOpen(&cap, "ELOOP"))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        for (i = 0; i < NNETIF; i++)
        {
            if (ELOOP == netiftab[i].dev)
            {
                netptr = &netiftab[i];
                break;
            }
        }
        failif(((NULL == netptr) || (&cap != netptr->capture)),
               "Not attached to ELOOP");
    }

    testPrint(verbose, "Capture (bad params)");
    failif((SYSERR != snoopCapture(NULL, NULL)), "");

    /* Reset data stream to beginning of PCAP file */
    data = (uchar *)(&_binary_data_testsnoop_pcap_start);
    memcpy(&pcap, data, sizeof(pcap));
    data += sizeof(pcap);
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }

    testPrint(verbose, "Capture no match");
    memcpy(pktA->data, data, phdr.caplen);
    pktA->len = phdr.caplen;
    pktA->nif = netptr;
    pktA->curr = pktA->data;
    cap.caplen = USHRT_MAX;
    cap.type = SNOOP_FILTER_IPv4;
    failif(((SYSERR == snoopCapture(&cap, pktA))
            || (0 != cap.nmatch) || (mailboxCount(cap.queue) > 0)), "");

    testPrint(verbose, "Capture match");
    cap.type = SNOOP_FILTER_ALL;
    nmatch = cap.nmatch;
    if (SYSERR == snoopCapture(&cap, pktA))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else if (1 != cap.nmatch)
    {
        failif(TRUE, "Packet did not match");
    }
    else if (mailboxCount(cap.queue) != 1)
    {
        failif(TRUE, "Packet not enqueued");
    }
    else
    {
        pktB = (struct packet *)mailboxReceive(cap.queue);
        failif((0 !=
                memcmp(pktB->data, pktA->data, phdr.caplen)),
               "Dequeued packet doesn't match");
    }

    testPrint(verbose, "Capture overrun");
    cap.type = SNOOP_FILTER_ALL;
    for (i = 0; i < SNOOP_QLEN; i++)
    {
        if (SYSERR == snoopCapture(&cap, pktA))
        {
            break;
        }
    }
    if (i < SNOOP_QLEN)
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        failif(((SYSERR != snoopCapture(&cap, pktA)) || (1 != cap.novrn)),
               "Packet did not overrun");
    }

    testPrint(verbose, "Close capture");
    failif((SYSERR == snoopClose(&cap)), "Returned SYSERR");

    /* TODO: RESUME HERE */

    netDown(ELOOP);
    close(ELOOP);

    /* always print out the overall tests status */
    if (passed)
    {
        testPass(TRUE, "");
    }
    else
    {
        testFail(TRUE, "");
    }

    return OK;
}
示例#4
0
/**
 * Tests raw sockets.
 * @return OK when testing is complete
 */
thread test_raw(bool verbose)
{
#if RAW0
    /* the failif macro depends on 'passed' and 'verbose' vars */
    bool passed = TRUE;
    device *devptr;
    struct raw *rawptr;
    struct netif *netptr;
    struct netaddr lip;
    struct netaddr rip;
    struct netaddr mask;
    struct packet *pkt;
    struct packet *pktA;
    struct pcap_pkthdr phdr;
    struct pcap_file_header pcap;
    uchar *data;
    uchar buf[500];
    int nproc;
    int wait;
    int i;

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

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

    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;

    /* Initialization */
    testPrint(verbose, "Test case initialization");
    data = (uchar *)(&_binary_data_testraw_pcap_start);
    memcpy(&pcap, data, sizeof(pcap));
    data += sizeof(pcap);
    if (SYSERR == open(ELOOP))
    {
        failif(TRUE, "");
    }
    else
    {
        if (SYSERR == netUp(ELOOP, &lip, &mask, NULL))
        {
            close(ELOOP);
            failif(TRUE, "");
        }
        else
        {
            netptr = NULL;
            for (i = 0; i < NNETIF; i++)
            {
                if (ELOOP == netiftab[i].dev)
                {
                    netptr = &netiftab[i];
                    break;
                }
            }
            pkt = netGetbuf();
            failif(((NULL == netptr) || (SYSERR == (int)pkt)), "");
        }
    }
    if (!passed)
    {
        testFail(TRUE, "");
        return OK;
    }

    /* Test Open */
    testPrint(verbose, "Open RAW (Proto Only)");
    rawptr = NULL;
    if (SYSERR == open(RAW0, NULL, NULL, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        devptr = (device *)&devtab[RAW0];
        rawptr = &rawtab[devptr->minor];
        failif(((rawptr->state != RAW_ALLOC)
                || (rawptr->dev != devptr)
                || (rawptr->proto != IPv4_PROTO_ICMP)
                || (rawptr->localip.type != NULL)
                || (rawptr->remoteip.type != NULL)
                || (rawptr->icount != 0)
                || (rawptr->istart != 0)
                || (semcount(rawptr->isema) != 0)
                || (rawptr->flags != 0)), "Incorrect control block");
    }

    testPrint(verbose, "Open RAW (Already Open)");
    failif((SYSERR != open(RAW0, NULL, NULL, IPv4_PROTO_ICMP)),
           "Double open() succeeded");

    /* Test Control */
    testPrint(verbose, "Control (Closed Socket)");
    failif((control(RAW1, RAW_CTRL_SETFLAG, NULL, NULL) != SYSERR), "");

    testPrint(verbose, "Control (Bad Params)");
    failif((control(RAW0, -1, NULL, NULL) != SYSERR), "");

    testPrint(verbose, "Control (Set Flag)");
    failif(((NULL != control(RAW0, RAW_CTRL_SETFLAG,
                             (RAW_IACCEPT | RAW_IHDR), NULL))
            || (0 == (rawptr->flags & RAW_IACCEPT))
            || (0 == (rawptr->flags & RAW_IHDR))), "");

    testPrint(verbose, "Control (Clear Flag)");
    failif(((RAW_IHDR != control(RAW0, RAW_CTRL_CLRFLAG,
                                 RAW_IHDR, NULL))
            || (0 == (rawptr->flags & RAW_IACCEPT))
            || (1 == (rawptr->flags & RAW_IHDR))), "");

    /* Test Close */
    testPrint(verbose, "Close RAW");
    if (SYSERR == close(RAW0))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        devptr = (device *)&devtab[RAW0];
        rawptr = &rawtab[devptr->minor];
        failif(((rawptr->state != RAW_FREE)
                || (rawptr->dev != NULL)), "Control block not clear");
    }

    testPrint(verbose, "Close RAW (Already Closed)");
    failif((SYSERR != close(RAW0)), "Did not SYSERR");

    /* Test demux */
    testPrint(verbose, "Demulitplexing (No sockets)");
    failif((NULL != rawDemux(&rip, &lip, IPv4_PROTO_ICMP)), "");

    testPrint(verbose, "Demulitplexing (All Protos)");
    if ((SYSERR == open(RAW0, &lip, &rip, IPv4_PROTO_IGMP))
        || (SYSERR == open(RAW1, NULL, NULL, NULL)))
    {
        failif(TRUE, "Open failed");
    }
    else
    {
        devptr = (device *)&devtab[RAW1];
        rawptr = &rawtab[devptr->minor];
        if (rawptr != rawDemux(&rip, &lip, IPv4_PROTO_ICMP))
        {
            failif(TRUE, "Incorrect socket");
        }
        else
        {
            failif(((SYSERR == close(RAW0)) || (SYSERR == close(RAW1))),
                   "Close failed");
        }
    }

    testPrint(verbose, "Demulitplexing (Proto)");
    if ((SYSERR == open(RAW0, NULL, NULL, IPv4_PROTO_ICMP))
        || (SYSERR == open(RAW1, NULL, NULL, IPv4_PROTO_IGMP)))
    {
        failif(TRUE, "Open failed");
    }
    else
    {
        devptr = (device *)&devtab[RAW0];
        rawptr = &rawtab[devptr->minor];
        if (rawptr != rawDemux(&rip, &lip, IPv4_PROTO_ICMP))
        {
            failif(TRUE, "Incorrect socket");
        }
        else
        {
            failif(((SYSERR == close(RAW0)) || (SYSERR == close(RAW1))),
                   "Close failed");
        }
    }

    testPrint(verbose, "Demulitplexing (Remote IP)");
    if ((SYSERR == open(RAW0, NULL, NULL, IPv4_PROTO_ICMP))
        || (SYSERR == open(RAW1, NULL, &rip, IPv4_PROTO_ICMP)))
    {
        failif(TRUE, "Open failed");
    }
    else
    {
        devptr = (device *)&devtab[RAW1];
        rawptr = &rawtab[devptr->minor];
        if (rawptr != rawDemux(&rip, &lip, IPv4_PROTO_ICMP))
        {
            failif(TRUE, "Incorrect socket");
        }
        else
        {
            failif(((SYSERR == close(RAW0)) || (SYSERR == close(RAW1))),
                   "Close failed");
        }
    }

    testPrint(verbose, "Demulitplexing (Local IP)");
    if ((SYSERR == open(RAW0, NULL, &rip, IPv4_PROTO_ICMP))
        || (SYSERR == open(RAW1, &lip, &rip, IPv4_PROTO_ICMP)))
    {
        failif(TRUE, "Open failed");
    }
    else
    {
        devptr = (device *)&devtab[RAW1];
        rawptr = &rawtab[devptr->minor];
        if (rawptr != rawDemux(&rip, &lip, IPv4_PROTO_ICMP))
        {
            failif(TRUE, "Incorrect socket");
        }
        else
        {
            failif(((SYSERR == close(RAW0)) || (SYSERR == close(RAW1))),
                   "Close failed");
        }
    }

    /* Test Open */
    testPrint(verbose, "Open RAW (Full Spec)");
    if (SYSERR == open(RAW0, &lip, &rip, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        devptr = (device *)&devtab[RAW0];
        rawptr = &rawtab[devptr->minor];
        failif(((rawptr->state != RAW_ALLOC)
                || (rawptr->dev != devptr)
                || (rawptr->proto != IPv4_PROTO_ICMP)
                || (FALSE == netaddrequal(&lip, &rawptr->localip))
                || (FALSE == netaddrequal(&rip, &rawptr->remoteip))
                || (rawptr->icount != 0)
                || (rawptr->istart != 0)
                || (semcount(rawptr->isema) != 0)
                || (rawptr->flags != 0)), "Incorrect control block");
    }

    /* Test receive */
    testPrint(verbose, "Receive (Bad Params)");
    /* Get 1st packet */
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    pkt->len = phdr.caplen;
    memcpy(pkt->data, data, phdr.caplen);
    pkt->linkhdr = pkt->data;
    pkt->nethdr = pkt->linkhdr + ETH_HDR_LEN;
    pkt->curr = pkt->nethdr + IPv4_HDR_LEN;
    failif(((SYSERR != rawRecv(NULL, NULL, NULL, NULL))
            || (SYSERR != rawRecv(pkt, &rip, NULL, NULL))), "");

    testPrint(verbose, "Receive (No Match)");
    pktA = netGetbuf();
    memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
    pktA->linkhdr = pktA->data;
    pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
    pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
    if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_IGMP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        failif(((rawptr->icount != 0)
                || (semcount(rawptr->isema) != 0)
                || (TRUE == netaddrequal(&rawptr->src[0], &rip))
                || (rawptr->in[0] == pktA)), "Packet enqueued");

    }

    testPrint(verbose, "Receive (One Pkt)");
    pktA = netGetbuf();
    memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
    pktA->linkhdr = pktA->data;
    pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
    pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
    if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        failif(((rawptr->istart != 0)
                || (rawptr->icount != 1)
                || (semcount(rawptr->isema) != 1)
                || (FALSE == netaddrequal(&rawptr->src[0], &rip))
                || (rawptr->in[0] != pktA)), "Incorrectly enqueued");
    }

    testPrint(verbose, "Read (Closed socket)");
    failif((SYSERR != read(RAW1, buf, 500)), "");

    testPrint(verbose, "Read (One Pkt)");
    failif(((read(RAW0, buf, 500) != 8)
            || (memcmp(buf, (pkt->data + ETH_HDR_LEN + IPv4_HDR_LEN), 8)
                != 0)
            || (rawptr->icount != 0)
            || (rawptr->istart != 1)
            || (semcount(rawptr->isema) != 0)
            || (rawptr->in[0] != NULL)), "");

    testPrint(verbose, "Read (Include header)");
    pktA = netGetbuf();
    memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
    pktA->linkhdr = pktA->data;
    pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
    pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
    rawptr->flags = RAW_IHDR;
    if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Recv returned SYSERR");
    }
    else
    {
        failif(((read(RAW0, buf, 500) != (IPv4_HDR_LEN + 8))
                ||
                (memcmp(buf, (pkt->data + ETH_HDR_LEN), IPv4_HDR_LEN + 8)
                 != 0) || (rawptr->icount != 0) || (rawptr->istart != 2)
                || (semcount(rawptr->isema) != 0)
                || (rawptr->in[0] != NULL)), "");
    }


    testPrint(verbose, "Read (Accept)");
    pktA = netGetbuf();
    memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
    pktA->linkhdr = pktA->data;
    pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
    pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
    rawptr->flags = RAW_IACCEPT;
    rawptr->remoteip.type = NULL;
    if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Recv returned SYSERR");
    }
    else
    {
        failif(((read(RAW0, buf, 500) != 8)
                || (FALSE == netaddrequal(&rawptr->remoteip, &rip))), "");
    }

    testPrint(verbose, "Read (Small buf)");
    pktA = netGetbuf();
    memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
    pktA->linkhdr = pktA->data;
    pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
    pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
    if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Recv returned SYSERR");
    }
    else
    {
        failif(((read(RAW0, buf, 2) != 2)
                ||
                (memcmp(buf, (pkt->data + ETH_HDR_LEN + IPv4_HDR_LEN), 2)
                 != 0)), "");
    }

    testPrint(verbose, "Receive (Full buf)");
    for (i = 0; i < RAW_IBLEN; i++)
    {
        memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
        pktA->linkhdr = pktA->data;
        pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
        pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
        if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP))
        {
            break;
        }
    }
    if (i < RAW_IBLEN)
    {
        failif(TRUE, "Unable to fill buffer");
    }
    else
    {
        memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
        pktA->linkhdr = pktA->data;
        pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
        pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
        failif((SYSERR != rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP)),
               "Did not return SYSERR");
    }

    testPrint(verbose, "Close RAW");
    failif((SYSERR == close(RAW0)), "");

    /* Test Write/Send */
    testPrint(verbose, "Open RAW");
    if (SYSERR == open(RAW0, &lip, NULL, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        devptr = (device *)&devtab[RAW0];
        rawptr = &rawtab[devptr->minor];
        failif(FALSE, "");
    }

    testPrint(verbose, "Send (Bad Params)");
    failif((rawSend(NULL, NULL, 0) != SYSERR), "");

    testPrint(verbose, "Send (Incomplete Spec)");
    failif((rawSend(rawptr, pkt->curr, 8) != SYSERR), "");

    testPrint(verbose, "Send (Incomplete Spec Hdr Inc)");
    rawptr->flags = RAW_OHDR;
    failif((rawSend(rawptr, pkt->curr, 8) != SYSERR), "");

    testPrint(verbose, "Send (Net Hdr Included)");
    /* Add ARP entry */
    /* Get 2nd 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);
    /* Get 3rd Packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    memcpy(pkt->data, data, phdr.caplen);
    pkt->len = phdr.caplen;
    pkt->linkhdr = pkt->data;
    pkt->nethdr = pkt->linkhdr + ETH_HDR_LEN;
    pkt->curr = pkt->nethdr + IPv4_HDR_LEN;
    /* Wait for ARP entry to be added */
    wait = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(10);
    }
    if (MAX_WAIT == wait)
    {
        failif(MAX_WAIT, "ARP entry failed");
    }
    else
    {
        netaddrcpy(&rawptr->remoteip, &rip);
        control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
        if (SYSERR == rawSend(rawptr, pkt->nethdr, IPv4_HDR_LEN + 8))
        {
            failif(TRUE, "Returned SYSERR");
        }
        else
        {
            control(ELOOP, ELOOP_CTRL_GETHOLD, (long)buf, 500);
            failif((memcmp(pkt->data, buf, pkt->len) != 0),
                   "Incorrect Packet");
        }
    }

    testPrint(verbose, "Send");
    rawptr->flags = NULL;
    netaddrcpy(&rawptr->remoteip, &rip);
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
    if (SYSERR == rawSend(rawptr, pkt->curr, 8))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        control(ELOOP, ELOOP_CTRL_GETHOLD, (long)buf, 500);
        failif((memcmp(pkt->data, buf, pkt->len) != 0),
               "Incorrect Packet");
    }

    testPrint(verbose, "Write");
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
    if (SYSERR == write(RAW0, pkt->curr, 8))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        control(ELOOP, ELOOP_CTRL_GETHOLD, (long)buf, 500);
        failif((memcmp(pkt->data, buf, pkt->len) != 0),
               "Incorrect Packet");
    }

    close(RAW0);
    netDown(ELOOP);
    close(ELOOP);

    /* always print out the overall tests status */
    if (passed)
    {
        testPass(TRUE, "");
    }
    else
    {
        testFail(TRUE, "");
    }
#endif                          /* RAW0 */
    return OK;
}
示例#5
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;
}
示例#6
0
/**
 * Tests the network interfaces.
 * @return OK when testing is complete
 */
thread test_netif(bool verbose)
{
    bool passed = TRUE;
    int i = 0;
    struct netaddr ip;
    struct netaddr mask;
    struct netaddr gate;
    struct netaddr hw;
    struct netaddr brc;
    struct pcap_file_header pcap;
    struct pcap_pkthdr phdr;
    struct packet *pkt;
    struct netif *netptr;
    uchar *data;

    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;

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

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

    testPrint(verbose, "Open loopback ethernet device");
    failif((SYSERR == open(ELOOP)), "");

    testPrint(verbose, "Start network interface");
    if (SYSERR == netUp(ELOOP, &ip, &mask, &gate))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        for (i = 0; i < NNETIF; i++)
        {
            if ((NET_ALLOC == netiftab[i].state)
                && (ELOOP == netiftab[i].dev))
            {
                break;
            }
        }

        netptr = &netiftab[i];
        if ((i >= NNETIF)
            || (netptr->state != NET_ALLOC)
            || (netptr->mtu != ELOOP_MTU)
            || (netptr->linkhdrlen != ELOOP_LINKHDRSIZE)
            || (FALSE == netaddrequal(&netptr->ip, &ip))
            || (FALSE == netaddrequal(&netptr->mask, &mask))
            || (FALSE == netaddrequal(&netptr->gateway, &gate)))
        {
            failif(TRUE, "Incorrect structure setup");
        }
        else
        {
            for (i = 0; i < NET_NTHR; i++)
            {
                if (isbadtid(netptr->recvthr[i]))
                {
                    failif(TRUE, "Bad recvthr");
                    break;
                }
            }
            if (NET_NTHR == i)
            {
                failif(FALSE, "");
            }
        }
    }

    testPrint(verbose, "Stop network interface");
    failif((SYSERR == netDown(ELOOP)), "");

    testPrint(verbose, "Start network interface (no gateway)");
    failif((SYSERR == netUp(ELOOP, &ip, &mask, NULL)), "");
    for (i = 0; i < NNETIF; i++)
    {
        if ((NET_ALLOC == netiftab[i].state)
            && (ELOOP == netiftab[i].dev))
        {
            break;
        }
    }

    /* Kill receiver threads */
    netptr = &netiftab[i];
    for (i = 0; i < NET_NTHR; i++)
    {
        kill(netptr->recvthr[i]);
        netptr->recvthr[i] = BADTID;
    }

    testPrint(verbose, "Get packet buffer");
    pkt = netGetbuf();
    failif((SYSERR == (int)pkt), "");

    data = (uchar *)&_binary_data_testnetif_pcap_start;
    memcpy(&pcap, data, sizeof(pcap));
    data += sizeof(pcap);
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    pkt->nif = netptr;
    pkt->len = phdr.caplen - netptr->linkhdrlen;
    pkt->curr = pkt->curr - pkt->len;
    memcpy(pkt->curr, data + netptr->linkhdrlen, pkt->len);

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

    testPrint(verbose, "Send packet (known hardware address)");
    if (SYSERR == netSend(pkt, &hw, NULL, ETHER_TYPE_ARP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        if ((SYSERR == read(netptr->dev, pkt, phdr.caplen))
            || (memcmp(pkt, data, phdr.caplen) != 0))
        {
            failif(TRUE, "Packet did not match");
        }
        else
        {
            failif(FALSE, "");
        }
    }

    testPrint(verbose, "Free packet buffer");
    failif((SYSERR == netFreebuf(pkt)), "");

    testPrint(verbose, "Stop network interface");
    failif(((SYSERR == netDown(ELOOP)) || (SYSERR == close(ELOOP))), "");

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

    return OK;
}
示例#7
0
static void kexec_from_network(int netdev, char *boot)
{
#if defined(WITH_DHCPC) && NETHER != 0
    struct dhcpData data;
    int result;
    const struct netaddr *gatewayptr;
    struct netif *nif;
    void *kernel;
    uint size;
    char str_ip[20];
    char str_mask[20];
    char str_gateway[20];
    const char *netdevname = devtab[netdev].name;

    /* Bring network interface (if any) down.  */
    netDown(netdev);

    /* Run DHCP client on the device for at most 10 seconds.  */
    printf("Running DHCP on %s\n", netdevname);
    result = dhcpClient(netdev, 10, &data);
    if (OK != result)
    {
        fprintf(stderr, "ERROR: DHCP failed.\n");
        return;
    }

    /* Ensure the DHCP server provided the boot filename and TFTP server IP
     * address.  */
    if (('\0' == data.bootfile[0] || 0 == data.next_server.type) && boot == NULL)
    {
        fprintf(stderr, "ERROR: DHCP server did not provide boot file "
                "and TFTP server address.\n");
        return;
    }

    /* Bring up the network interface.  */
    netaddrsprintf(str_ip, &data.ip);
    netaddrsprintf(str_mask, &data.mask);
    if (0 != data.gateway.len)
    {
        netaddrsprintf(str_gateway, &data.gateway);
        printf("Bringing up %s as %s with mask %s (gateway %s)\n",
               netdevname, str_ip, str_mask, str_gateway);
        gatewayptr = &data.gateway;
    }
    else
    {
        printf("Bringing up %s as %s with mask %s (no gateway)\n",
               netdevname, str_ip, str_mask);
        gatewayptr = NULL;
    }
    result = netUp(netdev, &data.ip, &data.mask, gatewayptr);
    if (OK != result)
    {
        fprintf(stderr, "ERROR: failed to bring up %s.\n", netdevname);
        return;
    }
    nif = netLookup(netdev);

    /* Download new kernel using TFTP.  */
    netaddrsprintf(str_ip, &data.next_server);
	 if (boot == NULL) {
    	printf("Downloading bootfile \"%s\" from TFTP server %s\n",
      	     data.bootfile, str_ip);
    	kernel = (void*)tftpGetIntoBuffer(data.bootfile, &nif->ip,
                                        &data.next_server, &size);
	 }else {
    	printf("Downloading bootfile \"%s\" from TFTP server %s\n",
      	     boot, str_ip);
    	kernel = (void*)tftpGetIntoBuffer(boot, &nif->ip,
                                        &data.next_server, &size);
	 }

    if (SYSERR == (int)kernel)
    {
        fprintf(stderr, "ERROR: TFTP failed.\n");
        return;
    }

    /* Execute the new kernel.  */
    printf("Executing new kernel (size=%u)\n", size);
    sleep(100);  /* Wait just a fraction of a second for printf()s to finish
                    (no guarantees though).  */
    kexec(kernel, size);

    fprintf(stderr, "ERROR: kexec() returned!\n");

#else /* WITH_DHCPC && NETHER != 0 */
    fprintf(stderr,
            "ERROR: Network boot is not supported in this configuration.\n"
            "       Please make sure you have enabled one or more network\n"
            "       devices, along with the DHCP and TFTP clients.\n");
#endif /* !(WITH_DHCPC && NETHER != 0) */
}