示例#1
0
static int pico_icmp4_process_in(struct pico_protocol *self, struct pico_frame *f)
{
	struct pico_icmp4_hdr *hdr = (struct pico_icmp4_hdr *) f->transport_hdr;
	IGNORE_PARAMETER(self);

  if (hdr->type == PICO_ICMP_ECHO) {
    hdr->type = PICO_ICMP_ECHOREPLY;
    /* outgoing frames require a f->len without the ethernet header len */
    if (f->dev->eth)
      f->len -= PICO_SIZE_ETHHDR;
    pico_icmp4_checksum(f);
    pico_ipv4_rebound(f);
  } else if (hdr->type == PICO_ICMP_UNREACH) {
    f->net_hdr = f->transport_hdr + PICO_ICMPHDR_UN_SIZE;
    pico_ipv4_unreachable(f, hdr->code);
  } else if (hdr->type == PICO_ICMP_ECHOREPLY) {
#ifdef PICO_SUPPORT_PING
    ping_recv_reply(f);
#endif
    pico_frame_discard(f);
  } else {
    pico_frame_discard(f);
  }
  return 0;
}
END_TEST

START_TEST(tc_pico_frame_copy)
{
    struct pico_frame *f = pico_frame_alloc(FRAME_SIZE);
    struct pico_frame *c1, *c2, *c3;
    (void)c3;
    fail_if(!f);
    fail_if(!f->buffer);
    fail_if(*f->usage_count != 1);

    /* First copy */
    c1 = pico_frame_copy(f);
    fail_if(!c1);
    fail_if(!c1->buffer);
    fail_if(!c1->usage_count);

    fail_if (c1->buffer != f->buffer);
    fail_if(c1->usage_count != f->usage_count);
    fail_if(*c1->usage_count != 2);
    fail_if(*f->usage_count != 2);
    fail_if(c1->start != c1->buffer);
    fail_if(c1->len != c1->buffer_len);
    fail_if(c1->len != FRAME_SIZE);

    /* Second copy */
    c2 = pico_frame_copy(f);
    fail_if (c2->buffer != f->buffer);
    fail_if(c2->usage_count != f->usage_count);
    fail_if(*c2->usage_count != 3);
    fail_if(*f->usage_count != 3);
    fail_if(c2->start != c2->buffer);
    fail_if(c2->len != c2->buffer_len);
    fail_if(c2->len != FRAME_SIZE);


#ifdef PICO_FAULTY
    printf("Testing with faulty memory in frame_copy (1)\n");
    pico_set_mm_failure(1);
    c3 = pico_frame_copy(f);
    fail_if(c3);
    fail_if(!f);
#endif

    /* Discard 1 */
    pico_frame_discard(c1);
    fail_if(*f->usage_count != 2);

    /* Discard 2 */
    pico_frame_discard(c2);
    fail_if(*f->usage_count != 1);

    pico_frame_discard(f);

}
END_TEST

START_TEST(tc_pico_frame_grow)
{
    struct pico_frame *f = pico_frame_alloc(3);
    fail_if(f->buffer_len != 3);
    /* Ensure that the usage_count starts at byte 4, for good alignment */
    fail_if(((void*)f->usage_count - (void *)f->buffer) != 4);

    ((uint8_t *)f->buffer)[0] = 'a';
    ((uint8_t *)f->buffer)[1] = 'b';
    ((uint8_t *)f->buffer)[2] = 'c';
    *f->usage_count = 12;


    /* First, the failing cases. */
    fail_if(pico_frame_grow(NULL, 30) == 0);
    fail_if(pico_frame_grow(f, 2) == 0);
    f->flags = 0;

    pico_set_mm_failure(1);
    fail_if(pico_frame_grow(f, 21) == 0);

    /* Now, the good one. */
    fail_if(pico_frame_grow(f, 21) != 0);
    fail_if(f->buffer_len != 21);
    fail_if(((void *)f->usage_count - (void *)f->buffer) != 24);


    fail_if(((uint8_t *)f->buffer)[0] != 'a');
    fail_if(((uint8_t *)f->buffer)[1] != 'b');
    fail_if(((uint8_t *)f->buffer)[2] != 'c');
    fail_if(*f->usage_count != 12);

    *f->usage_count = 1;
    pico_frame_discard(f);

    f = pico_frame_alloc_skeleton(10, 1);
    fail_if(!f);
    fail_if(f->buffer);
    fail_if(!f->flags);
    f->buffer = PICO_ZALLOC(10);

    fail_if(pico_frame_grow(f, 22) != 0);
    fail_if (f->flags);
    pico_frame_discard(f);

}
示例#4
0
static int fp_drop(struct filter_node *filter, struct pico_frame *f)
{
    IGNORE_PARAMETER(filter);
    ipf_dbg("ipfilter> drop\n");
    pico_frame_discard(f);
    return 1;
}
示例#5
0
/* The pico_ethernet_receive() function is used by
 * those devices supporting ETH in order to push packets up
 * into the stack.
 */
int32_t pico_ethernet_receive(struct pico_frame *f)
{
    struct pico_eth_hdr *hdr;
    if (!f || !f->dev || !f->datalink_hdr)
        goto discard;

    hdr = (struct pico_eth_hdr *) f->datalink_hdr;
    if ((memcmp(hdr->daddr, f->dev->eth->mac.addr, PICO_SIZE_ETH) != 0) &&
#ifdef PICO_SUPPORT_MCAST
            (memcmp(hdr->daddr, PICO_ETHADDR_MCAST, PICO_SIZE_MCAST) != 0) &&
#endif
            (memcmp(hdr->daddr, PICO_ETHADDR_ALL, PICO_SIZE_ETH) != 0))
        goto discard;

    f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);
    if (hdr->proto == PICO_IDETH_ARP)
        return pico_arp_receive(f);

    if ((hdr->proto == PICO_IDETH_IPV4) || (hdr->proto == PICO_IDETH_IPV6))
        return pico_network_receive(f);

discard:
    pico_frame_discard(f);
    return -1;
}
示例#6
0
static int32_t pico_ll_receive(struct pico_frame *f)
{
    struct pico_eth_hdr *hdr = (struct pico_eth_hdr *) f->datalink_hdr;
    f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);

#if (defined PICO_SUPPORT_IPV4) && (defined PICO_SUPPORT_ETH)
    if (hdr->proto == PICO_IDETH_ARP)
        return pico_arp_receive(f);

#endif

#if defined (PICO_SUPPORT_IPV4)
    if (hdr->proto == PICO_IDETH_IPV4)
        return pico_ipv4_ethernet_receive(f);

#endif

#if defined (PICO_SUPPORT_IPV6)
    if (hdr->proto == PICO_IDETH_IPV6)
        return pico_ipv6_ethernet_receive(f);

#endif

    pico_frame_discard(f);
    return -1;
}
示例#7
0
/* This is called by dev loop in order to ensure correct ethernet addressing.
 * Returns 0 if the destination is unknown, and -1 if the packet is not deliverable
 * due to ethernet addressing (i.e., no arp association was possible.
 *
 * Only IP packets must pass by this. ARP will always use direct dev->send() function, so
 * we assume IP is used.
 */
int32_t pico_ethernet_send(struct pico_frame *f)
{
    const struct pico_eth *dstmac = NULL;
    int32_t ret = -1;

    if (IS_IPV6(f)) {
        /*TODO: Neighbor solicitation */
        dstmac = NULL;
    }

    else if (IS_IPV4(f)) {
        if (IS_BCAST(f) || destination_is_bcast(f)) {
            dstmac = (const struct pico_eth *const) PICO_ETHADDR_ALL;
        }

#ifdef PICO_SUPPORT_MCAST
        else if (destination_is_mcast(f)) {
            uint8_t pico_mcast_mac[6] = {
                0x01, 0x00, 0x5e, 0x00, 0x00, 0x00
            };
            dstmac = pico_ethernet_mcast_translate(f, pico_mcast_mac);
        }
#endif
        else {
            dstmac = pico_arp_get(f);
            if (!dstmac)
                return 0;
        }
        /* This sets destination and source address, then pushes the packet to the device. */
        if (dstmac && (f->start > f->buffer) && ((f->start - f->buffer) >= PICO_SIZE_ETHHDR)) {
            struct pico_eth_hdr *hdr;
            f->start -= PICO_SIZE_ETHHDR;
            f->len += PICO_SIZE_ETHHDR;
            f->datalink_hdr = f->start;
            hdr = (struct pico_eth_hdr *) f->datalink_hdr;
            memcpy(hdr->saddr, f->dev->eth->mac.addr, PICO_SIZE_ETH);
            memcpy(hdr->daddr, dstmac, PICO_SIZE_ETH);
            hdr->proto = PICO_IDETH_IPV4;
            if(!memcmp(hdr->daddr, hdr->saddr, PICO_SIZE_ETH)) {
                dbg("sending out packet destined for our own mac\n");
                return pico_ethernet_receive(f);
            } else if(IS_LIMITED_BCAST(f)) {
                ret = pico_device_broadcast(f);
            } else {
                ret = (int32_t)f->dev->send(f->dev, f->start, (int) f->len);
                /* Frame is discarded after this return by the caller */
            }

            if(!ret) pico_frame_discard(f);

            return ret;
        } else {
            return -1;
        }
    } /* End IPV4 ethernet addressing */

    return -1;

}
/* Network layer: interface towards socket for frame sending */
int pico_network_send(struct pico_frame *f)
{
  if (!f || !f->sock || !f->sock->net) {
    pico_frame_discard(f);
    return -1;
  }
  return f->sock->net->push(f->sock->net, f);
}
int pico_transport_send(struct pico_frame *f)
{
  if (!f || !f->sock || !f->sock->proto) {
    pico_frame_discard(f);
    return -1;
  }
  return f->sock->proto->push(f->sock->net, f);
}
示例#10
0
static int fp_reject(struct filter_node *filter, struct pico_frame *f)
{
/* TODO check first if sender is pico itself or not */
    IGNORE_PARAMETER(filter);
    ipf_dbg("ipfilter> reject\n");
    (void)pico_icmp4_packet_filtered(f);
    pico_frame_discard(f);
    return 1;
}
示例#11
0
static int32_t pico_ipv4_ethernet_receive(struct pico_frame *f)
{
    if (IS_IPV4(f)) {
        pico_enqueue(pico_proto_ipv4.q_in, f);
    } else {
        (void)pico_icmp4_param_problem(f, 0);
        pico_frame_discard(f);
        return -1;
    }

    return (int32_t)f->buffer_len;
}
示例#12
0
static int32_t pico_ipv6_ethernet_receive(struct pico_frame *f)
{
    if (IS_IPV6(f)) {
        pico_enqueue(pico_proto_ipv6.q_in, f);
    } else {
        /* Wrong version for link layer type */
        pico_frame_discard(f);
        return -1;
    }

    return (int32_t)f->buffer_len;
}
示例#13
0
static inline int pico_ipv4_crc_check(struct pico_frame *f)
{
    uint16_t checksum_invalid = 1;
    struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;

    checksum_invalid = short_be(pico_checksum(hdr, f->net_len));
    if (checksum_invalid) {
        dbg("IP: checksum failed!\n");
        pico_frame_discard(f);
        return 0;
    }

    return 1;
}
示例#14
0
int32_t pico_ethernet_receive(struct pico_frame *f)
{
    struct pico_eth_hdr *hdr;
    if (!f || !f->dev || !f->datalink_hdr)
    {
        pico_frame_discard(f);
        return -1;
    }

    hdr = (struct pico_eth_hdr *) f->datalink_hdr;
    if ((memcmp(hdr->daddr, f->dev->eth->mac.addr, PICO_SIZE_ETH) != 0) &&
        (memcmp(hdr->daddr, PICO_ETHADDR_MCAST, PICO_SIZE_MCAST) != 0) &&
#ifdef PICO_SUPPORT_IPV6
        (memcmp(hdr->daddr, PICO_ETHADDR_MCAST6, PICO_SIZE_MCAST6) != 0) &&
#endif
        (memcmp(hdr->daddr, PICO_ETHADDR_ALL, PICO_SIZE_ETH) != 0))
    {
        pico_frame_discard(f);
        return -1;
    }

    pico_ll_check_bcast(f);
    return pico_ll_receive(f);
}
static void pico_fragments_empty_tree(struct pico_tree *tree)
{
    struct pico_tree_node *index, *tmp;

    if (!tree)
    {
        return;
    }

    pico_tree_foreach_safe(index, tree, tmp) {
        struct pico_frame * old = index->keyValue;
        pico_tree_delete(tree, old);
        pico_frame_discard(old);
    }

}
示例#16
0
/* Transport layer */
MOCKABLE int32_t pico_transport_receive(struct pico_frame *f, uint8_t proto)
{
    int32_t ret = -1;
    switch (proto) {

#ifdef PICO_SUPPORT_ICMP4
    case PICO_PROTO_ICMP4:
        ret = pico_enqueue(pico_proto_icmp4.q_in, f);
        break;
#endif

#ifdef PICO_SUPPORT_ICMP6
    case PICO_PROTO_ICMP6:
        ret = pico_enqueue(pico_proto_icmp6.q_in, f);
        break;
#endif


#if defined(PICO_SUPPORT_IGMP) && defined(PICO_SUPPORT_MCAST)
    case PICO_PROTO_IGMP:
        ret = pico_enqueue(pico_proto_igmp.q_in, f);
        break;
#endif

#ifdef PICO_SUPPORT_UDP
    case PICO_PROTO_UDP:
        ret = pico_enqueue(pico_proto_udp.q_in, f);
        break;
#endif

#ifdef PICO_SUPPORT_TCP
    case PICO_PROTO_TCP:
        ret = pico_enqueue(pico_proto_tcp.q_in, f);
        break;
#endif

    default:
        /* Protocol not available */
        dbg("pkt: no such protocol (%d)\n", proto);
        pico_notify_proto_unreachable(f);
        pico_frame_discard(f);
        ret = -1;
    }
    return ret;
}
int pico_network_receive(struct pico_frame *f)
{
  if (0) {}
#ifdef PICO_SUPPORT_IPV4
  else if (IS_IPV4(f)) {
    pico_enqueue(pico_proto_ipv4.q_in, f);
  }
#endif
#ifdef PICO_SUPPORT_IPV6
  else if (IS_IPV6(f)) {
    pico_enqueue(pico_proto_ipv6.q_in, f);
  }
#endif
  else {
    dbg("Network not found.\n");
    pico_frame_discard(f);
    return -1;
  }
  return f->buffer_len;
}
示例#18
0
static int pico_ipv4_process_mcast_in(struct pico_frame *f)
{
    struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
    if (pico_ipv4_is_multicast(hdr->dst.addr)) {
#ifdef PICO_SUPPORT_MCAST
        /* Receiving UDP multicast datagram TODO set f->flags? */
        if (hdr->proto == PICO_PROTO_IGMP) {
            ip_mcast_dbg("MCAST: received IGMP message\n");
            pico_transport_receive(f, PICO_PROTO_IGMP);
            return 1;
        } else if ((pico_ipv4_mcast_filter(f) == 0) && (hdr->proto == PICO_PROTO_UDP)) {
            pico_enqueue(pico_proto_udp.q_in, f);
            return 1;
        }

#endif
        pico_frame_discard(f);
        return 1;
    }

    return 0;
}
示例#19
0
END_TEST
START_TEST(tc_pico_eth_receive)
{
    struct pico_frame *f = NULL;
    struct pico_eth_hdr *eth = NULL;
    int ret = 0, count = 0;

    STARTING();

    f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr) + sizeof(struct pico_eth_hdr));
    f->datalink_hdr = f->buffer;
    f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);
    eth = (struct pico_eth_hdr *)f->datalink_hdr;
    ((uint8_t *)(f->net_hdr))[0] = 0x40; /* Ipv4 */

    /* ETHERNET PROTOCOL : IPV6 */
    eth->proto = PICO_IDETH_IPV6;

    TRYING("With wrong network type\n");
    ret = pico_eth_receive(f);
    CHECKING(count);
    fail_unless(ret == -1, "Wrong type should've returned an error\n");
    SUCCESS();

    f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr) + sizeof(struct pico_eth_hdr));
    f->datalink_hdr = f->buffer;
    f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);
    eth = (struct pico_eth_hdr *)f->datalink_hdr;
    ((uint8_t *)(f->net_hdr))[0] = 0x60; /* Ipv6 */

    /* ETHERNET PROTOCOL : IPV6 */
    eth->proto = PICO_IDETH_IPV6;
    TRYING("With correct network type\n");
    ret = pico_eth_receive(f);
    CHECKING(count);
    fail_unless(ret == (int32_t)f->buffer_len, "Was correct frame, should've returned success\n");
    SUCCESS();
    CHECKING(count);
    fail_unless(pico_proto_ipv6.q_in->size == f->buffer_len, "Frame not enqueued\n");
    SUCCESS();

    pico_frame_discard(f);

    f = pico_frame_alloc(sizeof(struct pico_ipv4_hdr) + sizeof(struct pico_eth_hdr));
    f->datalink_hdr = f->buffer;
    f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);
    eth = (struct pico_eth_hdr *)f->datalink_hdr;
    ((uint8_t *)(f->net_hdr))[0] = 0x40; /* Ipv4 */

    TRYING("With wrong frame type\n");
    ret = pico_eth_receive(f);
    CHECKING(count);
    fail_unless(ret == -1, "should've returned -1 wrong ethernet protocol\n");
    SUCCESS();

    f = pico_frame_alloc(sizeof(struct pico_ipv4_hdr) + sizeof(struct pico_eth_hdr));
    f->datalink_hdr = f->buffer;
    f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);
    eth = (struct pico_eth_hdr *)f->datalink_hdr;
    ((uint8_t *)(f->net_hdr))[0] = 0x40; /* Ipv4 */
    eth->proto = PICO_IDETH_IPV4;

    TRYING("With IPv4 frame\n");
    ret = pico_eth_receive(f);
    CHECKING(count);
    fail_unless(ret > 0, "Was correct frame should've returned size of frame\n");
    SUCCESS();
    CHECKING(count);
    fail_unless(pico_proto_ipv4.q_in->size == f->buffer_len, "Frame not enqueued\n");
    SUCCESS();

    ENDING(count);
}
示例#20
0
END_TEST

START_TEST(tc_802154_to_ietf)
{
    int test = 1;
    struct pico_802154 a = {
        .addr.data = { 1,2,3,4,5,6,7,8 },
        .mode = AM_6LOWPAN_EXT
    };
    uint8_t buf[] = {8,7,6,5,4,3,2,1};

    STARTING();

    // TEST 1
    TRYING("Extended address mode\n");
    addr_802154_to_ietf(&a);
    dbg_addr_ext("After", a.addr.data);
    CHECKING(test);
    FAIL_UNLESS(0 == memcmp(a.addr.data, buf, SIZE_6LOWPAN_EXT),
                "Failed converting to IETF endianness\n");

    // TEST 2
    TRYING("Short address mode\n");
    a.mode = AM_6LOWPAN_SHORT;
    addr_802154_to_ietf(&a);
    dbg_addr_ext("After", a.addr.data);
    CHECKING(test);
    FAIL_UNLESS(a.addr._short.addr == short_be(0x0708),
                "Failed converting short to IETF endianness\n");

    // TEST 3
    TRYING("Wrong address mode\n");
    a.mode = AM_6LOWPAN_NONE;
    addr_802154_to_ietf(&a);
    dbg_addr_ext("After", a.addr.data);
    buf[0] = 7;
    buf[1] = 8;
    CHECKING(test);
    FAIL_UNLESS(0 == memcmp(a.addr.data, buf, SIZE_6LOWPAN_EXT),
                "Should've done nothing\n");

    ENDING(test);

}
END_TEST

START_TEST(tc_802154_ll_src)
{
    int test = 1;
    struct pico_ip6 ip = {
        .addr = {0,0,0,0,0,0,0,0, 3,2,3,4,5,6,7,8}
    };
    struct pico_ip6 ip2 = {
        .addr = {0,0,0,0,0,0,0,0, 0,0,0,0xff,0xfe,0,0x12,0x34}
    };
    struct pico_6lowpan_info info = {
        .addr_short.addr = short_be(0x1234),
        .addr_ext.addr = {3,2,3,4,5,6,7,8}
    };
    struct pico_device dev;
    struct pico_802154 addr;
    struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
    struct pico_ipv6_hdr *hdr = (struct pico_ipv6_hdr *)f->buffer;

    STARTING();

    dev.eth = (struct pico_ethdev *)&info;
    f->net_hdr = f->buffer;
    f->dev = &dev;
    dev.hostvars.lowpan_flags = PICO_6LP_FLAG_LOWPAN;

    // TEST 3
    TRYING("With an IPv6 address that is derived from MAC short address\n");
    info.addr_short.addr = short_be(0x1234);
    hdr->src = ip2;
    addr = addr_802154_ll_src(f);
    CHECKING(test);
    FAIL_UNLESS(AM_6LOWPAN_SHORT == addr.mode,
                "Should've returned device's short address \n");
    CHECKING(test);
    FAIL_UNLESS(short_be(0x1234) == addr.addr._short.addr,
                "Should've copied the short address from the device\n");

    // TEST 4
    TRYING("With an IPv6 address that is derived from MAC extended address\n");
    ip.addr[8] = 1;
    hdr->src = ip;
    addr = addr_802154_ll_src(f);
    CHECKING(test);
    FAIL_UNLESS(AM_6LOWPAN_EXT == addr.mode,
                "Should've returned device's extended address\n");
    CHECKING(test);
    FAIL_UNLESS(0 == memcmp(info.addr_ext.addr, addr.addr._ext.addr, SIZE_6LOWPAN_EXT),
                "Should've copied device's extended address\n");

    ENDING(test);
}
END_TEST

START_TEST(tc_802154_ll_dst)
{
    int test = 1;
    struct pico_ip6 ip;
    struct pico_ip6 local;
    struct pico_ip6 local2;
    struct pico_802154 addr;
    struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
    struct pico_ipv6_hdr *hdr = (struct pico_ipv6_hdr *)f->buffer;
    struct pico_device dev;
    uint8_t buf[] = {3,2,3,4,5,6,7,8};
    pico_string_to_ipv6("ff00:0:0:0:0:0:e801:100", ip.addr);
    pico_string_to_ipv6("fe80:0:0:0:0102:0304:0506:0708", local.addr);
    pico_string_to_ipv6("fe80:0:0:0:0:0ff:fe00:1234", local2.addr);

    STARTING();

    f->net_hdr = f->buffer;
    f->dev = &dev;
    dev.hostvars.lowpan_flags = PICO_6LP_FLAG_LOWPAN;

    // TEST 1
    TRYING("With a MCAST IPv6 address, should return 0xFFFF\n");
    hdr->dst = ip;
    addr = addr_802154_ll_dst(f);
    CHECKING(test);
    FAIL_UNLESS(AM_6LOWPAN_SHORT == addr.mode,
                "Should've set address mode to SHORT\n");
    CHECKING(test);
    FAIL_UNLESS(short_be(ADDR_802154_BCAST) == addr.addr._short.addr,
                "Should've set address to BCAST\n");

    // TEST 2
    TRYING("With a link local IPv6 address derived from an extended L2 address\n");
    hdr->dst = local;
    addr = addr_802154_ll_dst(f);
    dbg_addr_ext("After:", addr.addr._ext.addr);
    CHECKING(test);
    FAIL_UNLESS(AM_6LOWPAN_EXT == addr.mode,
                "Should've set address mode to EXTENDED\n");
    CHECKING(test);
    FAIL_UNLESS(0 == memcmp(buf, addr.addr._ext.addr, SIZE_6LOWPAN_EXT),
                "Should've copied the extended address from the IP address\n");

    // TEST 3
    TRYING("With a link local IPv6 address derived from a short L2 address\n");
    hdr->dst = local2;
    addr = addr_802154_ll_dst(f);
    CHECKING(test);
    FAIL_UNLESS(AM_6LOWPAN_SHORT == addr.mode,
                "Should've set address mode to SHORT\n");
    CHECKING(test);
    FAIL_UNLESS(short_be(0x1234) == addr.addr._short.addr,
                "Should've copied the short address from the IP address\n");

    /* TODO: Test getting address from neighbour table */

    ENDING(test);
}
END_TEST

/*******************************************************************************
 *  FRAME
 ******************************************************************************/

/* Frame (123 bytes) */
static uint8_t pkt[] = {
0x41, 0xcc, 0xa6, 0xff, 0xff, 0x8a,       /*   A..... */
0x18, 0x00, 0xff, 0xff, 0xda, 0x1c, 0x00, 0x88, /* ........ */
0x18, 0x00, 0xff, 0xff, 0xda, 0x1c, 0x00, 0xc1, /* ........ */
0x09, 0x00, 0x02, 0x42, 0xfa, 0x40, 0x04, 0x01, /* ...B.@.. */
0xf0, 0xb1, 0x01, 0x06, 0x6f, 0xaf, 0x48, 0x65, /* ....o.He */
0x6c, 0x6c, 0x6f, 0x20, 0x30, 0x30, 0x36, 0x20, /* llo 006  */
0x30, 0x78, 0x46, 0x46, 0x33, 0x43, 0x0a, 0x00, /* 0xFF3C.. */
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, /* ........ */
0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, /* ...... ! */
0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, /* "#$%&'() */
0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, /* *+,-./01 */
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, /* 23456789 */
0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, /* :;<=>?@A */
0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, /* BCDEFGHI */
0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, /* JKLMNOPQ */
0x52, 0x53, 0x54, 0x68, 0x79                    /* RSThy */
};

START_TEST(tc_dst_am)
{
    int test = 1;
    int ret = 0;

    STARTING();

    // TEST 1
    TRYING("Trying to determine AM of destination addr from buffer \n");
    ret = dst_am((struct pico_802154_hdr *)pkt);
    DBG("ret = %d\n", ret);
    CHECKING(test);
    FAIL_UNLESS(AM_6LOWPAN_EXT == ret,
                "Should've returned the AM of an extended address\n");

    ENDING(test);
}
END_TEST

START_TEST(tc_src_am)
{
    int test = 1;
    int ret = 0;

    STARTING();

    // TEST 1
    TRYING("Trying to determine AM of source addr from buffer \n");
    ret = src_am((struct pico_802154_hdr *)pkt);
    DBG("ret = %d\n", ret);
    CHECKING(test);
    FAIL_UNLESS(AM_6LOWPAN_EXT == ret,
                "Should've returned the AM of an extended address\n");

    ENDING(test);
}
END_TEST

START_TEST(tc_802154_hdr_len)
{
    int test = 1;
    int ret = 0;

    STARTING();

    // TEST 1
    TRYING("Trying to determine length of the header from buffer\n");
    ret = frame_802154_hdr_len((struct pico_802154_hdr *)pkt);
    DBG("ret = %d\n", ret);
    CHECKING(test);
    FAIL_UNLESS(21 == ret,
                "Should've returned the correct length of the header\n");

    ENDING(test);
}
END_TEST

START_TEST(tc_802154_src)
{
    int test = 1;
    struct pico_802154_hdr *hdr;
    struct pico_802154 addr;
    uint8_t src[] = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x88};
    STARTING();

    hdr = (struct pico_802154_hdr *)pkt;

    // TEST 1
    TRYING("To receive the source address from a mapped buffer\n");
    addr = frame_802154_src(hdr);
    CHECKING(test);
    FAIL_UNLESS(AM_6LOWPAN_EXT == addr.mode,
                "Should've returned an extended address\n");
    CHECKING(test);
    FAIL_UNLESS(0 == memcmp(src, addr.addr._ext.addr, SIZE_6LOWPAN_EXT),
                "Should've copied the extended source address\n");

    ENDING(test);
}
END_TEST

START_TEST(tc_802154_dst)
{
    int test = 1;
    struct pico_802154_hdr *hdr;
    struct pico_802154 addr;
    uint8_t dst[] = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x8a};

    STARTING();
    hdr = (struct pico_802154_hdr *)pkt;

    // TEST 1
    TRYING("To receive the source address from a mapped buffer\n");
    addr = frame_802154_dst(hdr);
    CHECKING(test);
    FAIL_UNLESS(AM_6LOWPAN_EXT == addr.mode,
                "Should've returned an extended address\n");
    CHECKING(test);
    FAIL_UNLESS(0 == memcmp(dst, addr.addr._ext.addr, SIZE_6LOWPAN_EXT),
                "Should've copied the extended source address\n");

    ENDING(test);
}
END_TEST

START_TEST(tc_802154_format)
{
    int test = 1;
    struct pico_802154 src = {
        .addr.data = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x88},
        .mode = AM_6LOWPAN_EXT
    };
    struct pico_802154 dst = {
        .addr.data = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x8a},
        .mode = AM_6LOWPAN_EXT
    };
    struct pico_6lowpan_short pan = { .addr = short_be(0xffff) };
    uint8_t buf[127] = {0};
    int i = 0;

    STARTING();

    // TEST 1
    TRYING("To format a frame like sample capture\n");
    frame_802154_format(buf, 166, FCF_INTRA_PAN, FCF_NO_ACK_REQ,
                        FCF_NO_SEC, pan, src, dst);
    printf("Buffer:");
    for (i = 0; i < 21; i++) {
        if (i % 8 != 0)
            printf("%02x ", buf[i]);
        else {
            printf("\n%02x ", buf[i]);
        }
    }
    printf("\n");
    CHECKING(test);
    FAIL_UNLESS(21 == frame_802154_hdr_len((struct pico_802154_hdr *)buf),
                "Failed to correctly set the frame header, the length isn't right\n");
    CHECKING(test);
    FAIL_UNLESS(0 == memcmp(pkt, buf, 21),
                "Failed to correctly format IEEE802.15.4 frame\n");

    ENDING(test);
}
END_TEST
START_TEST(tc_802154_process_out)
{
    int i = 0;
    int ret = 0;
    int test = 1;
    struct pico_802154 src = {
        .addr.data = {3,2,3,4,5,6,7,8},
        .mode = AM_6LOWPAN_EXT
    };
    struct pico_802154 dst = {
        .addr.data = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x8a},
        .mode = AM_6LOWPAN_EXT
    };
    struct pico_frame *f = pico_frame_alloc(0);
    struct pico_6lowpan_info info = {
        .addr_short.addr = short_be(0x1234),
        .addr_ext.addr = {3,2,3,4,5,6,7,8},
        .pan_id.addr = short_be(0x1234)
    };
    struct pico_device dev;
    uint8_t buf[] = {0x41,0xcc,0x00,0x34,0x12,0x8a,0x18,0x00,
                     0xff,0xff,0xda,0x1c,0x00,0x08,0x07,0x06,
                     0x05,0x04,0x03,0x02,0x03};
    dev.eth = (struct pico_ethdev *)&info;
    dev.q_out = PICO_ZALLOC(sizeof(struct pico_queue));
    f->dev = &dev;
    dev.hostvars.lowpan_flags = PICO_6LP_FLAG_LOWPAN;

    STARTING();
    pico_stack_init();

    // TEST 1
    TRYING("Trying with bare frame\n");
    f->src.pan = src;
    f->dst.pan = dst;
    ret = pico_802154_process_out(f);
    printf("Buffer:");
    for (i = 0; i < 21; i++) {
        if (i % 8 != 0)
            printf("%02x ", f->datalink_hdr[i]);
        else {
            printf("\n%02x ", f->datalink_hdr[i]);
        }
    }
    printf("\n");
    CHECKING(test);
    FAIL_UNLESS(0 < ret, "Shouldn't have returned an error\n");
    CHECKING(test);
    FAIL_UNLESS(0 == memcmp(buf, f->datalink_hdr, 21),
                "Frame isn't correctly formatted\n");

    pico_frame_discard(f);

    ENDING(test);
}
END_TEST
START_TEST(tc_802154_process_in)
{
    int ret = 0;
    int test = 1;
    struct pico_802154 src = {
        .addr.data = {3,2,3,4,5,6,7,8},
        .mode = AM_6LOWPAN_EXT
    };
    struct pico_802154 dst = {
        .addr.data = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x8a},
        .mode = AM_6LOWPAN_EXT
    };
    struct pico_frame *f = pico_frame_alloc(22);
    uint8_t buf[] = {0x41,0xcc,0x00,0x34,0x12,0x8a,0x18,0x00,
                     0xff,0xff,0xda,0x1c,0x00,0x08,0x07,0x06,
                     0x05,0x04,0x03,0x02,0x03,0x60};
    memcpy(f->buffer, buf, 22);
    f->src.pan = src;
    f->dst.pan = dst;

    STARTING();
    pico_stack_init();

    TRYING("Apply processing function on predefined buffer\n");
    ret = pico_802154_process_in(f);
    CHECKING(test);
    FAIL_UNLESS(0 < ret, "Should not return failure\n");
}
END_TEST
static Suite *pico_suite(void)
{
    Suite *s = suite_create("PicoTCP");

    TCase *TCase_swap = tcase_create("Unit test for pico_swap");
    TCase *TCase_802154_to_ietf = tcase_create("Unit test for 802154_to_ietf");
    TCase *TCase_802154_ll_src = tcase_create("Unit test for 802154_ll_src");
    TCase *TCase_802154_ll_dst = tcase_create("Unit test for 802154_ll_dst");
    TCase *TCase_802154_hdr_len = tcase_create("Unit test for 802154_hdr_len");
    TCase *TCase_src_am = tcase_create("Unit test for src_am");
    TCase *TCase_dst_am = tcase_create("Unit test for dst_am");
    TCase *TCase_802154_src = tcase_create("Unit test for 802154_src");
    TCase *TCase_802154_dst = tcase_create("Unit test for 802154_dst");
    TCase *TCase_802154_format = tcase_create("Unit test for 802154_format");
    TCase *TCase_802154_process_out = tcase_create("Unit test for 802154_process_out");
    TCase *TCase_802154_process_in = tcase_create("Unit test for 802154_process_in");

/*******************************************************************************
 *  ADDRESSES
 ******************************************************************************/
    tcase_add_test(TCase_swap, tc_swap);
    suite_add_tcase(s, TCase_swap);
    tcase_add_test(TCase_802154_to_ietf, tc_802154_to_ietf);
    suite_add_tcase(s, TCase_802154_to_ietf);
    tcase_add_test(TCase_802154_ll_src, tc_802154_ll_src);
    suite_add_tcase(s, TCase_802154_ll_src);
    tcase_add_test(TCase_802154_ll_dst, tc_802154_ll_dst);
    suite_add_tcase(s, TCase_802154_ll_dst);

/*******************************************************************************
 *  FRAME
 ******************************************************************************/
    tcase_add_test(TCase_802154_hdr_len, tc_802154_hdr_len);
    suite_add_tcase(s, TCase_802154_hdr_len);
    tcase_add_test(TCase_src_am, tc_src_am);
    suite_add_tcase(s, TCase_src_am);
    tcase_add_test(TCase_dst_am, tc_dst_am);
    suite_add_tcase(s, TCase_dst_am);
    tcase_add_test(TCase_802154_src, tc_802154_src);
    suite_add_tcase(s, TCase_802154_src);
    tcase_add_test(TCase_802154_dst, tc_802154_dst);
    suite_add_tcase(s, TCase_802154_dst);
    tcase_add_test(TCase_802154_format, tc_802154_format);
    suite_add_tcase(s, TCase_802154_format);
    tcase_add_test(TCase_802154_process_out, tc_802154_process_out);
    suite_add_tcase(s, TCase_802154_process_out);
    tcase_add_test(TCase_802154_process_in, tc_802154_process_in);
    suite_add_tcase(s, TCase_802154_process_in);

    return s;
}

int main(void)
{
    int fails;
    Suite *s = pico_suite();
    SRunner *sr = srunner_create(s);
    srunner_run_all(sr, CK_NORMAL);
    fails = srunner_ntests_failed(sr);
    srunner_free(sr);
    return fails;
}
示例#21
0
END_TEST
START_TEST(tc_destination_is_mcast)
{
    struct pico_ip6 addr = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 }};
    struct pico_ip6 mcast = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 }};
    struct pico_ip4 addr4 = {0};
    struct pico_ip4 mcast4 = {0};
    struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
    struct pico_ipv6_hdr *h = (struct pico_ipv6_hdr *)f->buffer;
    struct pico_ipv4_hdr *h4 = (struct pico_ipv4_hdr *)f->buffer;
    /* Test parameters */
    int ret = 0, count = 0;

    f->net_hdr = (uint8_t*) h;
    f->buffer[0] = 0x60; /* Ipv6 */

    STARTING();

    pico_string_to_ipv4("232.1.1.0", &(mcast4.addr)); /* 0 */
    pico_string_to_ipv4("10.20.0.1", &(addr4.addr));

    pico_string_to_ipv6("ff00:0:0:0:0:0:e801:100", (mcast.addr)); /* 0 */
    pico_string_to_ipv6("fe80:0:0:0:0:0:a28:100", (addr.addr)); /* 0 */

    TRYING("With IPv6 unicast addr\n");
    memcpy(h->dst.addr, addr.addr, PICO_SIZE_IP6);
    ret = destination_is_mcast(f);
    CHECKING(count);
    fail_unless(0 == ret, "Should've returned 0 since not an IPv6 multicast\n");
    SUCCESS();

    TRYING("With IPv6 multicast addr\n");
    memcpy(h->dst.addr, mcast.addr, PICO_SIZE_IP6);
    ret = destination_is_mcast(f);
    CHECKING(count);
    fail_unless(1 == ret, "Should've returned 1 since an IPv6 multicast\n");
    SUCCESS();

    pico_frame_discard(f);
    f = pico_frame_alloc(sizeof(struct pico_ipv4_hdr));
    h4 = (struct pico_ipv4_hdr *)f->buffer;
    f->net_hdr = (uint8_t *)h4;
    f->buffer[0] = 0x40; /* IPv4 */

    TRYING("With IPv4 unicast addr\n");
    h4->dst = addr4;
    ret = destination_is_bcast(f);
    CHECKING(count);
    fail_unless(0 == ret, "Should've returned 0 since not an IPv4 mcast address\n");
    SUCCESS();

    TRYING("With IPv4 multicast addr\n");
    h4->dst = mcast4;
    ret = destination_is_mcast(f);
    CHECKING(count);
    fail_unless(1 == ret, "Should've returned 1 since an IPv4 multicast\n");
    SUCCESS();

    BREAKING();
    ret = destination_is_bcast(NULL);
    CHECKING(count);
    fail_unless(0 == ret, "Should've returned 0 since NULL-pointer\n");
    SUCCESS();

    ENDING(count);
}