Example #1
0
static void* udpThread(void* data) {
    UNUSED(data);
    int n = 0;

    while (workerRunning) {
        n = udpRecv(&stateLink, &fdmPkt, sizeof(fdm_packet), 100);
        if (n == sizeof(fdm_packet)) {
//            printf("[data]new fdm %d\n", n);
            updateState(&fdmPkt);
        }
    }

    printf("udpThread end!!\n");
    return NULL;
}
Example #2
0
/**
 * Tests UDP
 * @return OK when testing is complete
 */
thread test_udp(bool verbose)
{
#ifdef UDP1
    struct udp *udpptr = NULL;
    ushort pta;
    ushort ptb;
    struct netaddr ipc;
    struct netaddr ipd;
    struct netaddr ipl;
    struct netaddr src;
    struct netaddr dst;
    struct netaddr mask;
    struct netaddr ipzero;
    struct packet *pkt[10];
    struct udpPkt *udppkt;
    struct udpPseudoHdr *pseudo;
    uchar buffera[12];
    uchar bufferb[12];
    uchar bufferc[12];
    uchar bufferd[12];
    uchar bufferp[40];
    bool passed = TRUE;

    /*   struct pcap_pkthdr phdr;
       struct netif *netptr;
       int nproc;
       int i;
       int wait;
       struct packet *pktA;
       uchar buf[100];
       uchar *data;
       uchar *buffer;
     */
    pta = 20000;
    ptb = 30000;

    /* IP address "C" */
    ipc.type = NETADDR_IPv4;
    ipc.len = IPv4_ADDR_LEN;
    ipc.addr[0] = 192;
    ipc.addr[1] = 168;
    ipc.addr[2] = 1;
    ipc.addr[3] = 5;

    /* IP address "D" */
    ipd.type = NETADDR_IPv4;
    ipd.len = IPv4_ADDR_LEN;
    ipd.addr[0] = 192;
    ipd.addr[1] = 168;
    ipd.addr[2] = 1;
    ipd.addr[3] = 7;

    /* "Local" IP address */
    ipl.type = NETADDR_IPv4;
    ipl.len = IPv4_ADDR_LEN;
    ipl.addr[0] = 192;
    ipl.addr[1] = 168;
    ipl.addr[2] = 1;
    ipl.addr[3] = 8;

    /* Source IP address */
    src.type = NETADDR_IPv4;
    src.len = IPv4_ADDR_LEN;
    src.addr[0] = 192;
    src.addr[1] = 168;
    src.addr[2] = 1;
    src.addr[3] = 6;

    /* Destination IP address */
    dst.type = NETADDR_IPv4;
    dst.len = IPv4_ADDR_LEN;
    dst.addr[0] = 192;
    dst.addr[1] = 168;
    dst.addr[2] = 1;
    dst.addr[3] = 1;

    /* Mask */
    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;

    /* Empty address */
    ipzero.type = 0;
    ipzero.len = 0;
    ipzero.addr[0] = 0;
    ipzero.addr[1] = 0;
    ipzero.addr[2] = 0;
    ipzero.addr[3] = 0;
    ipzero.addr[4] = 0;
    ipzero.addr[5] = 0;

    /* Test udpPkt structure */
    //testPrint(verbose, "Header structure");
    /* TODO: Figure out how this should be done */

    /* Test udpOpen */
    testPrint(verbose, "Open UDP devices (NULL local port)");
    if (SYSERR == open(UDP0, &ipl, &ipd, NULL, ptb))
    {
        failif(TRUE, "");
    }

    if (SYSERR == open(UDP1, &ipl, &ipc, NULL, pta))
    {
        failif(TRUE, "");
    }
    failif((udptab[0].localpt == udptab[1].localpt)
           || (udptab[0].localpt < UDP_PSTART)
           || (udptab[0].localpt > UDP_PMAX)
           || (udptab[1].localpt < UDP_PSTART)
           || (udptab[1].localpt > UDP_PMAX), "");
    if (SYSERR == close(UDP0))
    {
        failif(TRUE, "");
    }
    if (SYSERR == close(UDP1))
    {
        failif(TRUE, "");
    }

    /* Test udpOpen */
    testPrint(verbose, "Open UDP device (NULL remote port)");
    if (SYSERR == open(UDP0, &ipl, &ipd, pta, NULL))
    {
        failif(TRUE, "");
    }
    failif(udptab[0].remotept != NULL, "");
    if (SYSERR == close(UDP0))
    {
        failif(TRUE, "");
    }

    /* Test udpOpen */
    testPrint(verbose, "Open UDP device (NULL remote ip)");
    if (SYSERR == open(UDP0, &ipl, NULL, pta, ptb))
    {
        failif(TRUE, "");
    }
    failif(0 == netaddrequal(&udptab[0].remoteip, &ipzero), "");
    if (SYSERR == close(UDP0))
    {
        failif(TRUE, "");
    }


    /* Test udpOpen */
    testPrint(verbose, "Open UDP devices (same local port)");
    if (SYSERR == open(UDP0, &ipl, &ipd, pta, ptb))
    {
        failif(TRUE, "");
    }

    if (SYSERR == open(UDP1, &ipl, &ipd, pta, pta))
    {
        failif(TRUE, "");
    }
    failif(udptab[0].localpt != udptab[1].localpt, "");

    /* Only close the second UDP device this time, we want to test close
     * using UDP0 */
    if (SYSERR == close(UDP1))
    {
        failif(TRUE, "");
    }

    /* Test udpClose */
    testPrint(verbose, "Close UDP device");
    if (SYSERR == close(UDP0))
    {
        failif(TRUE, "");
    }
    failif((udptab[0].dev != 0) || (udptab[0].icount != 0)
           || (udptab[0].istart != 0) || (udptab[0].isem != 0)
           || (udptab[0].localpt != 0) || (udptab[0].remotept != 0)
           || (FALSE == netaddrequal(&udptab[0].localip, &ipzero))
           || (FALSE == netaddrequal(&udptab[0].remoteip, &ipzero))
           || (udptab[0].state != 0) || (udptab[0].flags != 0), "");

    /* Test udpControl */
    testPrint(verbose, "UDP Control: Binding");
    /* Open UDP device to resume testing of that device */
    if (SYSERR == open(UDP0, &ipl, NULL, NULL, NULL))
    {
        failif(TRUE, "");
    }
    control(UDP0, UDP_CTRL_ACCEPT, pta, (long)&ipl);
    control(UDP0, UDP_CTRL_BIND, ptb, (long)&ipc);
    failif((udptab[0].localpt != pta)
           || (FALSE == netaddrequal(&udptab[0].localip, &ipl))
           || (udptab[0].remotept != ptb)
           || (FALSE == netaddrequal(&udptab[0].remoteip, &ipc)), "");

    /* Test udpControl */
    testPrint(verbose, "UDP Control: Flags");
    control(UDP0, UDP_CTRL_SETFLAG, UDP_FLAG_PASSIVE | UDP_FLAG_NOBLOCK
            | UDP_FLAG_BINDFIRST, NULL);
    control(UDP0, UDP_CTRL_CLRFLAG, UDP_FLAG_NOBLOCK, NULL);
    /* At this point NOBLOCK should be the only flag that is off */
    failif((FALSE == (udptab[0].flags & UDP_FLAG_PASSIVE))
           || (udptab[0].flags & UDP_FLAG_NOBLOCK)
           || (FALSE == (udptab[0].flags & UDP_FLAG_BINDFIRST)), "");

    /* Test udpDemux */
    testPrint(verbose, "UDP Demux (2 sockets)");
    open(UDP1, &ipl, NULL, pta, NULL);
    udpptr = udpDemux(pta, ptb, &ipl, &ipc);
    failif((udpptr == &udptab[1]) || (NULL == udpptr), "");

    /* Test udpRecv and udpRead */
    testPrint(verbose, "Receive and read UDP packets");

    control(UDP0, UDP_CTRL_CLRFLAG, UDP_FLAG_PASSIVE
            | UDP_FLAG_BINDFIRST, NULL);

    control(UDP0, UDP_CTRL_ACCEPT, pta, (long)&ipl);
    control(UDP0, UDP_CTRL_BIND, ptb, (long)&ipc);

    pkt[0] = makePkt(ptb, pta, &ipl, &ipc, 5, "ABCDE");
    pkt[1] = makePkt(ptb, pta, &ipl, &ipc, 4, "FGHI");
    pkt[2] = makePkt(ptb, pta, &ipl, &ipc, 3, "JKL");
    pkt[3] = makePkt(ptb, pta, &ipl, &ipc, 2, "MN");
    if (SYSERR == udpRecv(pkt[0], &ipc, &ipl))
    {
        failif(TRUE, "recva");
    }
    if (SYSERR == udpRecv(pkt[1], &ipc, &ipl))
    {
        failif(TRUE, "recvb");
    }
    if (SYSERR == udpRecv(pkt[2], &ipc, &ipl))
    {
        failif(TRUE, "recvc");
    }
    if (SYSERR == udpRecv(pkt[3], &ipc, &ipl))
    {
        failif(TRUE, "recvd");
    }
    if (SYSERR == read(UDP0, buffera, 5))
    {
        failif(TRUE, "reada");
    }
    if (SYSERR == read(UDP0, bufferb, 5))
    {
        failif(TRUE, "readb");
    }
    if (SYSERR == read(UDP0, bufferc, 5))
    {
        failif(TRUE, "readc");
    }
    if (SYSERR == read(UDP0, bufferd, 5))
    {
        failif(TRUE, "readd");
    }
    failif((0 != strncmp((char *)buffera, "ABCDE", 5))
           || (0 != strncmp((char *)bufferb, "FGHI", 4))
           || (0 != strncmp((char *)bufferc, "JKL", 3))
           || (0 != strncmp((char *)bufferd, "MN", 2)), "");

    /* Test udpRecv and udpRead */
    testPrint(verbose, "Two UDP sockets");
    pkt[0] = makePkt(pta, pta, &ipc, &ipl, 9, "ABCDEFGHI");
    udpRecv(pkt[0], &ipc, &ipl);
    read(UDP1, bufferc, 9);
    failif(0 != strncmp((char *)bufferc, "ABCDEFGHI", 9), "");

    /* Test udpRecv and udpRead */
    testPrint(verbose, "Receive and read UDP packets (again)");

    control(UDP0, UDP_CTRL_CLRFLAG, UDP_FLAG_PASSIVE
            | UDP_FLAG_BINDFIRST, NULL);

    control(UDP0, UDP_CTRL_ACCEPT, pta, (long)&ipl);
    control(UDP0, UDP_CTRL_BIND, ptb, (long)&ipc);

    pkt[0] = makePkt(ptb, pta, &ipl, &ipc, 5, "OPQRS");
    pkt[1] = makePkt(ptb, pta, &ipl, &ipc, 3, "TUV");
    pkt[2] = makePkt(ptb, pta, &ipl, &ipc, 2, "WX");
    pkt[3] = makePkt(ptb, pta, &ipl, &ipc, 2, "YZ");
    udpRecv(pkt[0], &ipc, &ipl);
    udpRecv(pkt[1], &ipc, &ipl);
    udpRecv(pkt[2], &ipc, &ipl);
    udpRecv(pkt[3], &ipc, &ipl);
    if (SYSERR == read(UDP0, buffera, 5))
    {
        failif(TRUE, "reada");
    }
    if (SYSERR == read(UDP0, bufferb, 3))
    {
        failif(TRUE, "readb");
    }
    if (SYSERR == read(UDP0, bufferc, 2))
    {
        failif(TRUE, "readc");
    }
    if (SYSERR == read(UDP0, bufferd, 2))
    {
        failif(TRUE, "readd");
    }
    failif(0 != strncmp((char *)buffera, "OPQRS", 5)
           || (0 != strncmp((char *)bufferb, "TUV", 3))
           || (0 != strncmp((char *)bufferc, "WX", 2))
           || (0 != strncmp((char *)bufferd, "YZ", 2)), "");

    /* Test udpRecv and udpRead on multiple sockets */
    testPrint(verbose, "Recv/read with varying sockets (1)");

    /* Test 1 */
    control(UDP0, UDP_CTRL_ACCEPT, pta, (long)&ipl);
    control(UDP0, UDP_CTRL_BIND, NULL, NULL);
    pkt[0] = makePkt(ptb, pta, &ipc, &ipl, 5, "test1");
    udpRecv(pkt[0], &ipc, &ipl);
    read(UDP0, buffera, 5);
    failif(strncmp((char *)buffera, "test1", 5), "");

    /* Test 2 */
    testPrint(verbose, "Recv/read socket test 2");
    control(UDP0, UDP_CTRL_ACCEPT, pta, (long)&ipl);
    control(UDP0, UDP_CTRL_BIND, ptb, NULL);

    control(UDP1, UDP_CTRL_ACCEPT, pta, (long)&ipl);
    control(UDP1, UDP_CTRL_BIND, 0, NULL);

    pkt[0] = makePkt(ptb, pta, &ipc, &ipl, 6, "test2a");
    pkt[1] = makePkt(pta, pta, &ipc, &ipl, 6, "test2b");
    udpRecv(pkt[0], &ipc, &ipl);
    udpRecv(pkt[1], &ipc, &ipl);
    read(UDP0, buffera, 6);
    read(UDP1, bufferb, 6);

    failif(0 != strncmp((char *)buffera, "test2a", 6)
           || (0 != strncmp((char *)bufferb, "test2b", 6)), "");

    /* Test 3 */
    testPrint(verbose, "Recv/read socket test 3");
    control(UDP0, UDP_CTRL_BIND, ptb, (long)&ipc);
    control(UDP1, UDP_CTRL_BIND, ptb, NULL);

    pkt[0] = makePkt(ptb, pta, &ipc, &ipl, 6, "test3a");
    pkt[1] = makePkt(ptb, pta, &ipd, &ipl, 6, "test3b");
    udpRecv(pkt[0], &ipc, &ipl);
    udpRecv(pkt[1], &ipd, &ipl);
    read(UDP0, buffera, 6);
    read(UDP1, bufferb, 6);

    failif((0 != strncmp((char *)buffera, "test3a", 6))
           || (0 != strncmp((char *)bufferb, "test3b", 6)), "");

    /* Test 4 */
    testPrint(verbose, "Recv/read socket test 4");
    control(UDP0, UDP_CTRL_BIND, ptb, (long)&ipc);
    control(UDP1, UDP_CTRL_BIND, ptb, (long)&ipd);

    pkt[0] = makePkt(ptb, pta, &ipc, &ipl, 6, "test4a");
    pkt[1] = makePkt(ptb, pta, &ipd, &ipl, 6, "test4b");
    udpRecv(pkt[0], &ipc, &ipl);
    udpRecv(pkt[1], &ipd, &ipl);
    read(UDP0, buffera, 6);
    read(UDP1, bufferb, 6);

    failif((0 != strncmp((char *)buffera, "test4a", 6))
           || (0 != strncmp((char *)bufferb, "test4b", 6)), "");

    /* Test 5 */
    testPrint(verbose, "Recv/read socket test 5");
    control(UDP0, UDP_CTRL_BIND, 0, NULL);
    control(UDP1, UDP_CTRL_ACCEPT, ptb, (long)&ipl);
    control(UDP1, UDP_CTRL_BIND, 0, NULL);

    pkt[0] = makePkt(ptb, pta, &ipc, &ipl, 6, "test5a");
    pkt[1] = makePkt(pta, ptb, &ipc, &ipl, 6, "test5b");
    udpRecv(pkt[0], &ipc, &ipl);
    udpRecv(pkt[1], &ipc, &ipl);
    read(UDP0, buffera, 6);
    read(UDP1, bufferb, 6);

    failif((0 != strncmp((char *)buffera, "test5a", 6))
           || (0 != strncmp((char *)bufferb, "test5b", 6)), "");

    /* Read entire UDP packet */
    testPrint(verbose, "Read entire UDP packet");
    control(UDP0, UDP_CTRL_SETFLAG, UDP_FLAG_PASSIVE, NULL);
    pkt[0] = makePkt(ptb, pta, &ipc, &ipl, 7, "passive");
    udpRecv(pkt[0], &ipc, &ipl);
    read(UDP0, bufferp, UDP_HDR_LEN + 7 + sizeof(struct udpPseudoHdr));
    pseudo = (struct udpPseudoHdr *)bufferp;
    udppkt = (struct udpPkt *)(pseudo + 1);
    failif((0 != memcmp(pseudo->srcIp, ipc.addr, IPv4_ADDR_LEN))
           || (0 != memcmp(pseudo->dstIp, ipl.addr, IPv4_ADDR_LEN))
           || (udppkt->srcPort != ptb) || (udppkt->dstPort != pta)
           || (udppkt->len != UDP_HDR_LEN + 7)
           || (0 != strncmp((char *)udppkt->data, "passive", 7)), "");

    /* Done testing, attempt to close all UDP devices (MAKE SURE BOTH
     * DEVICES ARE OPEN BEFORE YOU CLOSE THEM!!!) */
    close(UDP0);
    close(UDP1);

    /* Print out the overall test's status (pass or fail) */
    if (passed)
    {
        testPass(TRUE, "");
    }
    else
    {
        testFail(TRUE, "");
    }
#else /* UDP1 */
    testSkip(TRUE, "");
#endif /* !UDP1 */
    return OK;
}
Example #3
0
/**
 * Process an incoming IPv4 packet.
 * @param pkt pointer to the incoming packet
 * @return OK if packet was processed succesfully, otherwise SYSERR
 */
syscall ipv4Recv(struct packet *pkt)
{
    struct ipv4Pkt *ip;
    struct netaddr dst;
    struct netaddr src;
    ushort iplen;

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

    /* Setup pointer to IPv4 header */
    pkt->nethdr = pkt->curr;
    ip = (struct ipv4Pkt *)pkt->curr;

    /* Verify the IP packet is valid */
    if (FALSE == ipv4RecvValid(ip))
    {
        IPv4_TRACE("Invalid packet");
        netFreebuf(pkt);
        return SYSERR;
    }

    /* Obtain destination and source IP addresses */
    dst.type = NETADDR_IPv4;
    dst.len = IPv4_ADDR_LEN;
    memcpy(dst.addr, ip->dst, dst.len);
    src.type = NETADDR_IPv4;
    src.len = IPv4_ADDR_LEN;
    memcpy(src.addr, ip->src, src.len);

    /* If packet is not destined for one of our network interfaces,
     * then attempt to route the packet */
    if (FALSE == ipv4RecvDemux(&dst))
    {
        IPv4_TRACE("Packet sent to routing subsystem");

#if NETEMU
        /* Run the packet through the network emulator if enabled */
        return netemu(pkt);
#else
        return rtRecv(pkt);
#endif
    }

    /* Check if packet is fragmented */
    if ((IPv4_FLAG_MF & net2hs(ip->flags_froff))
        || (0 != (net2hs(ip->flags_froff) & IPv4_FROFF)))
    {
        // TODO: Handle fragmenting of packet
        // TODO: Should send icmp time exceeded
        // return ipRecvSendFrag(pkt, &dst);
        IPv4_TRACE("Packet fragmented");
        netFreebuf(pkt);
        return SYSERR;
    }

    /* The Ethernet driver pads packets less than 60 bytes in length.
     * If the packet length returned from the Ethernet driver (pkt->len)
     * does not agree with the packet headers, adjust the packet length 
     * to remove padding. */
    iplen = net2hs(ip->len);
    if ((pkt->len - pkt->nif->linkhdrlen) > iplen)
    {
        pkt->len = pkt->nif->linkhdrlen + iplen;
    }

    /* Move current pointer to application level header */
    pkt->curr += ((ip->ver_ihl & IPv4_IHL) << 2);

    IPv4_TRACE("IPv4 proto %d", ip->proto);
    /* Switch on packet protocol */
    switch (ip->proto)
    {
        /* ICMP Packet */
    case IPv4_PROTO_ICMP:
        icmpRecv(pkt);
        break;

        /* UDP Packet */
    case IPv4_PROTO_UDP:
#if NUDP
        udpRecv(pkt, &src, &dst);
#endif                          /* NUDP */
        break;

        /* TCP Packet */
    case IPv4_PROTO_TCP:
#if NTCP
        tcpRecv(pkt, &src, &dst);
#endif                          /* NTCP */
        break;

        /* Unknown IP packet protocol */
    default:
#if NRAW
        rawRecv(pkt, &src, &dst, ip->proto);
#endif                          /* NRAW */
        break;
    }

    return OK;
}