Exemplo n.º 1
0
u08 eth_find_interface( mac_addr dest )
{
	if (mac_equal( dest, get_macaddr() ))
		return IFACE_INTERNAL;

	if (mac_equal( dest, broadcast_mac ))
		return IFACE_BROADCAST;

	return IFACE_WAN;
}
Exemplo n.º 2
0
/* if there was a timeout waiting for an acknowledgement of a sequence
 * packet we sent out, resend it.
 */
void resend_packets()
{
    int i, j;

    if (db[23].d) {
        ddprintf("resend_packets..\n");
    }

    for (i = 0; i < stp_list_count; i++) {
        if (!stp_list[i].box.awaiting_ack) { continue; }

        for (j = 0; j < device_list_count; j++) {
            if (device_list[j].device_type != device_type_wds
                || !mac_equal(stp_list[i].box.name, device_list[j].mac_address))
            {
                continue;
            }
            if (db[23].d) { ddprintf("resend_packets doing send_seq..\n"); }
            stp_list[i].box.send_error++;
            // stp_list[i].delayed_cloud_packets++;
            send_seq(i, stp_list[i].box.message, stp_list[i].box.message_len);

            if (db[23].d) { ddprintf("resend_packets sending message..\n"); }
            send_message((message_t *) stp_list[i].box.message,
                    stp_list[i].box.message_len,
                    &device_list[j]);
        }
    }
} /* resend_packets */
Exemplo n.º 3
0
/*
 * 过滤得到登录成功包
 * @return: 0: 成功获取
 *          -1: 超时
 *          -2: 服务器中止登录,密码错误吧
 */
static int filte_success(pcap_t *skfd)
{
    int stime = time((time_t*)NULL);
    struct pcap_pkthdr *pkt_hd;
    const uchar *recvbuff;
    int timeout;
    for (; time((time_t*)NULL)-stime <= TIMEOUT;) {
        timeout = pcap_next_ex(skfd, &pkt_hd, &recvbuff);
        if (0 >= timeout) return -1;
        FORMAT_RECVPKT(recvbuff);
        if (recvethii->type == htons(ETHII_8021X)
                && mac_equal(recvethii->dst_mac, client_mac)
                && recveapol->type == EAPOL_PACKET ) {
            if (recveap->id == sendeap->id
                    && recveap->code == EAP_CODE_SUCS) {
                _D("id: %d login success.\n", sendeap->id);
                return 0;
            } else if (recveap->id == sendeap->id
                    && recveap->code == EAP_CODE_FAIL) {
                _D("id: %d fail.\n", sendeap->id);
                return -2;
            }
        }
    }
    return -1;
}
Exemplo n.º 4
0
/* print our model of the current topology of the cloud */
void dprint_cloud_stats(ddprintf_t *fn, FILE *f)
{
    bool_t first = true;
    int i, j;

    // status_dprint_title(fn, f, strlen("                        "));

    for (i = 0; i < cloud_stp_list_count; i++) {
        if (first) {
            first = false;
        } else {
            fn(f, "\n");
        }
        mac_dprint(fn, f, cloud_stp_list[i].v.stp_beacon.originator);

        fn(f, "stp connections:\n");
        for (j = 0; j < cloud_stp_list[i].v.stp_beacon.status_count; j++) {
            status_t *s = &cloud_stp_list[i].v.stp_beacon.status[j];
            if (s->device_type == device_type_wds
                && s->neighbor_type == STATUS_CLOUD_NBR
                && !mac_equal(s->name,
                    cloud_stp_list[i].v.stp_beacon.originator))
            {
                fn(f, "    ");
                mac_dprint(fn, f, s->name);
            }
        }

        fn(f, "outgoing arc values:\n");
        status_dprint_short_array(fn, f,
                cloud_stp_list[i].v.stp_beacon.status,
                cloud_stp_list[i].v.stp_beacon.status_count);
    }
}
Exemplo n.º 5
0
/* we got an acknowledgement of our sequence message from another cloud box. */
void process_ack_sequence_msg(message_t *message, int d)
{
    int i;

    if (db[23].d) {
        ddprintf("process_ack_sequence_msg processing <%d %d>\n",
                message->v.seq.sequence_num,
                message->v.seq.message_len);
    }

    for (i = 0; i < stp_list_count; i++) {
        if (!stp_list[i].box.awaiting_ack) { continue; }

        if (stp_list[i].box.has_eth_mac_addr
            || !mac_equal(stp_list[i].box.name, device_list[d].mac_address))
        {
            continue;
        }
        if (db[23].d) { ddprintf("   found it; bumping send_sequence..\n"); }
        stp_list[i].box.awaiting_ack = false;
        stp_list[i].box.send_sequence++;

        // stp_list[i].box.non_cloud_packets++;
    }

    /* maybe we only have at most one box awaiting an ack.  right now we
     * may cause the whole cloud to operate in lock step.
     */
    turn_off_ack_timer();
}
Exemplo n.º 6
0
/* debug-print the cloud box, and if we think it is a neighbor
 * (i.e., if we can directly see 802.11 beacons from it) print out
 * the signal strength to it.
 */
void cloud_box_print(ddprintf_t *fn, FILE *f, cloud_box_t *cloud_box, int indent)
{
    int i;
    char found = 0;

    print_space(fn, f, indent);
    fn(f, "one true name (wifi interface):  ");
    mac_dprint_no_eoln(fn, f, cloud_box->name);

    for (i = 0; i < nbr_device_list_count; i++) {
        if (mac_equal(cloud_box->name, nbr_device_list[i].name)) {
            found = 1;
            break;
        }
    }
    if (found) {
        fn(f, "; strength %d", nbr_device_list[i].signal_strength);
    } else {
        fn(f, "; (no signal strength)");
    }
    if (cloud_box->has_eth_mac_addr) {
        fn(f, "; eth address ");
        mac_dprint_no_eoln(fn, f, cloud_box->eth_mac_addr);
    }

    fn(f, "\n");
}
Exemplo n.º 7
0
dessert_cb_result_t lsr_loopback(dessert_msg_t *msg, uint32_t len, dessert_msg_proc_t *proc, dessert_sysif_t *sysif, dessert_frameid_t id) {
	struct ether_header* l25h = dessert_msg_getl25ether(msg);
	
	if(mac_equal(l25h->ether_dhost, dessert_l25_defsrc)) {
		dessert_syssend_msg(msg);
		return DESSERT_MSG_DROP;
	}
	return DESSERT_MSG_KEEP;
}
Exemplo n.º 8
0
/* see if mac address "src" is the "name" field of any element in the
 * status array of the stp beacon.
 */
static bool_t in_status_list(mac_address_t src, stp_beacon_t *stp_beacon)
{
    int i;

    for (i = 0; i < stp_beacon->status_count; i++) {
        if (mac_equal(stp_beacon->status[i].name, src)) {
            return true;
        }
    }

    return false;
}
Exemplo n.º 9
0
/* find the index of the status struct in the array that has mac address mac */
int status_find_by_mac(status_t *s, int status_count, mac_address_t mac)
{
    int i;

    for (i = 0; i < status_count; i++) {
        if (mac_equal(s[i].name, mac)) {
            return i;
        }
    }

    return -1;
}
Exemplo n.º 10
0
/* see if mac address "name" is the originator field of an element of
 * the array "new_stp_list".
 */
static bool_t in_mac_list(message_t *new_stp_list, int new_stp_list_count,
        mac_address_t name)
{
    int i;

    for (i = 0; i < new_stp_list_count; i++) {
        if (mac_equal(new_stp_list[i].v.stp_beacon.originator, name)) {
            return true;
        }
    }

    return false;
}
Exemplo n.º 11
0
/* we have an arc <src -> dest>.  wish to see if <dest -> src> is also
 * valid.  we do this by finding a node whose originator is dest, and
 * which has src among the names in its status records.
 * valid places to look for dest are my_beacon (we never get here or
 * try this if we don't yet have a beacon), beacon, as long as have_beacon
 * is true, and entries in cloud_stp_list that are not shadowed by
 * those first two options.
 */
static bool_t has_valid_back_pointer(mac_address_t src, mac_address_t dest)
{
    int i;

    if (mac_equal(dest, my_wlan_mac_address)) {
        return in_status_list(src, &my_beacon.v.stp_beacon);

    } else if (have_beacon
        && mac_equal(dest, beacon.v.stp_beacon.originator))
    {
        return in_status_list(src, &beacon.v.stp_beacon);
    }

    /* else, look through cloud_stp_list */

    for (i = 0; i < cloud_stp_list_count; i++) {
        if (mac_equal(dest, cloud_stp_list[i].v.stp_beacon.originator)) {
            return in_status_list(src, &cloud_stp_list[i].v.stp_beacon);
        }
    }

    return false;
}
Exemplo n.º 12
0
/* put mac into mac_list if it's not already there. */
static void add_mac_addr(mac_address_t mac)
{
    int i;

    for (i = 0; i < mac_count; i++) {
        if (mac_equal(mac, mac_list[i])) {
            ddprintf("add_mac_addr warning: duplicat mac addresses.\n");
            // return;
        }
    }

    if (mac_count >= MAX_CLOUD) {
        ddprintf("add_mac_addr; too many mac addresses.\n");
        return;
    }

    mac_copy(mac_list[mac_count++], mac);
}
Exemplo n.º 13
0
/* print the cloud boxes in our cloud, and for each one print
 * the boxes it can see 802.11 beacons for, i.e., its wireless neighbors.
 */
void dprint_cloud_stats_short(ddprintf_t *fn, FILE *f)
{
    bool_t first = true;
    int i, j;
    int sent = 0, dropped = 0;
    float fraction;

    for (i = 0; i < cloud_stp_list_count; i++) {
        if (first) {
            first = false;
        } else {
            fn(f, "\n");
        }
        mac_dprint_no_eoln(fn, f, cloud_stp_list[i].v.stp_beacon.originator);

        for (j = 0; j < cloud_stp_list[i].v.stp_beacon.status_count; j++) {
            // status_t *s = &cloud_stp_list[i].v.stp_beacon.status[j];
            // sent += s->noncloud_packets_sent;
            // dropped += s->dropped_noncloud_packets;
        }

        if (sent == 0 && dropped == 0) {
            fraction = 1.;
        } else {
            fraction = 1. - ((float) dropped) / (float) (dropped + sent);
        }

        fn(f, "; %.1f percent of packets delivered; stp connections:\n",
                fraction * 100.);

        for (j = 0; j < cloud_stp_list[i].v.stp_beacon.status_count; j++) {
            status_t *s = &cloud_stp_list[i].v.stp_beacon.status[j];
            if (!mac_equal(s->name,
                    cloud_stp_list[i].v.stp_beacon.originator)
                && s->device_type != device_type_wlan
                && s->device_type != device_type_eth)
            {
                fn(f, "    ");
                mac_dprint(fn, f, s->name);
            }
        }
    }
}
Exemplo n.º 14
0
/* is it ok to read from the current file descriptor, which gives us
 * data received from another cloud box?  if we are awaiting an
 * acknowledgement of a sequence packet we sent to another box, we
 * don't want to read from other devices until we get it.
 */
bool_t ack_read_ok(int d)
{
    int i;

    /* if we're not doing flow control, just go for it. */
    if (!db[22].d) { return true; }

    /* if we're not waiting for any ack's, it's ok to read input */
    if (!awaiting_ack()) { return true; }

    /* if we are pretending we have no ethernet connection and this is an
     * ethernet connection, it's ok to read input
     */
    if (device_list[d].device_type == device_type_eth && db[20].d) {
        return true;
    }

    /* if this isn't a wds device, it won't be giving us an ack.
     * don't read anything from any upstream devices if we are awaiting an
     * ack from a downstream wds device.
     */
    if (device_list[d].device_type != device_type_wds) {
        return false;
    }

    /* see if we can find the stp node for this device, and if we are
     * awaiting an ack from that stp node.  if so, it's ok to read from
     * this device, because we may get the ack we are hoping for.
     */
    for (i = 0; i < stp_list_count; i++) {

        if (!stp_list[i].box.has_eth_mac_addr
            && mac_equal(stp_list[i].box.name, device_list[d].mac_address)
            && stp_list[i].box.awaiting_ack)
        {
            return true;
        }
    }

    return false;
}
Exemplo n.º 15
0
/* used to add wds or ad-hoc devices.  uses cloud_box_t, which would cause
 * circularities in .h files, so leave it here.
 */
void add_perm_io_stat_index(int *nbr_perm_io_stat_index,
        mac_address_t neighbor_name, device_type_t type)
{
    int i;
    bool_t found;
    status_t *p;

    ddprintf("\n\n ADD_PERM_IO_STAT_INDEX \n\n");
    found = false;
    for (i = 0; i < perm_io_stat_count; i++) {
        if (mac_equal(perm_io_stat[i].name, neighbor_name)) {
            *nbr_perm_io_stat_index = i;
            found = true;
            break;
        }
    }

    if (!found) {
        if (perm_io_stat_count >= MAX_CLOUD) {
            ddprintf("add_perm_io_stat_index; too many perm_io_stat's\n");
            /* at some point, garbage collect perm_io_stat with oldest
             * last-update time
             */
            goto done;
        }

        p = &perm_io_stat[perm_io_stat_count++];
        status_init(p);
        mac_copy(p->name, neighbor_name);
        p->device_type = type;

        *nbr_perm_io_stat_index = perm_io_stat_count - 1;
    }

    done : ;

    status_dprint_short_array(eprintf, stderr, perm_io_stat, perm_io_stat_count);
    ddprintf("perm_io_stat_count:  %d\n", perm_io_stat_count);

} /* add_perm_io_stat_index */
Exemplo n.º 16
0
/*
 * 过滤得到eap-request-identity包
 * @return: 0: 成功获取
 *          -1: 超时
 */
static int filte_req_identity(pcap_t *skfd)
{
    int stime = time((time_t*)NULL);
    struct pcap_pkthdr *pkt_hd;
    const uchar *recvbuff;
    int timeout;

    for (; time((time_t*)NULL)-stime <= TIMEOUT;) {
        timeout = pcap_next_ex(skfd, &pkt_hd, &recvbuff);
        if (0 >= timeout) return -1;
        FORMAT_RECVPKT(recvbuff);
        /* eap包且是request */
        if (recvethii->type == htons(ETHII_8021X)
                && mac_equal(recvethii->dst_mac, client_mac)
                && recveapol->type == EAPOL_PACKET
                && recveap->code == EAP_CODE_REQ
                && recveap->type == EAP_TYPE_IDEN) {
            return 0;
        }
    }
    return -1;
}
Exemplo n.º 17
0
/* see if there is any output available on fd using select, and if so
 * read it and send it as a verified message to the other side.
 */
static void read_and_fwd_shell_output(int fd)
{
    while (true) {
        byte buf[1024];
        fd_set read_set;
        struct timeval timer = {0, 0};
        int result;

        FD_ZERO(&read_set);
        FD_SET(fd, &read_set);
        result = select(fd + 1, &read_set, 0, 0, &timer);
        if (result == -1) {
            fprintf(stderr, "read_and_fwd_shell_output; select error %s\n",
                    strerror(errno));
        }

        if (result == 0) { break; }

        result = read(fd, (char *) &(buf[4]), 1020);

        if (db[2].d) {
            fprintf(stderr, "read_and_fwd_shell_output message from fd %d:\n",
                    fd);
            print_message(stderr, (unsigned char *) &buf, result);
        }

        if (result == 0) { break; }

        if (result == -1) {
            perror("read of stdin failed");
        } else if (!mac_equal(dest_mac_addr, zero_mac_addr)) {
            if (state != state_receiving_shell_output) {
                state = state_receiving_shell_output;
                seq = 1;
            }
            verified_send_message(buf, result, shell_response_msg);
        }
    }
}
Exemplo n.º 18
0
/*
 * 过滤得到eap-request-md5clg包
 * @return: 0: 成功获取
 *          -1: 超时
 *          -2: 服务器中止登录,用户名不存在
 */
static int filte_req_md5clg(pcap_t *skfd)
{
    int stime = time((time_t*)NULL);
    struct pcap_pkthdr *pkt_hd;
    const uchar *recvbuff;
    int timeout;
    for (; time((time_t*)NULL)-stime <= TIMEOUT;) {
        timeout = pcap_next_ex(skfd, &pkt_hd, &recvbuff);
        if (0 >= timeout) return -1;
        FORMAT_RECVPKT(recvbuff);
        /* 是request且是eap-request-md5clg */
        if (recvethii->type == htons(ETHII_8021X)
                && mac_equal(recvethii->dst_mac, client_mac)
                && recveapol->type == EAPOL_PACKET ) {
            if (recveap->code == EAP_CODE_REQ
                    && recveap->type == EAP_TYPE_MD5) {
#ifdef DEBUG
                _M("id: %d\n", sendeap->id);
                _M("md5: ");
                for (int i = 0; i < recveapbody->md5size; ++i)
                    _M("%.2x", recveapbody->md5value[i]);
                _M("\n");
                _M("ex-md5: ");
                for (int i = 0; i < ntohs(recveap->len) - recveapbody->md5size - 2; ++i)
                    _M("%.2x", recveapbody->md5exdata[i]);
                _M("\n");
#endif
                return 0;
            } else if (recveap->id == sendeap->id
                    && recveap->code == EAP_CODE_FAIL) {
                _D("id: %d fail.\n", sendeap->id);
                return -2;
            }
        }
    }
    return -1;
}
Exemplo n.º 19
0
/* write an html page to /tmp/cloud.tmp giving an ascii-art representation
 * of the entire cloud, and two matrices giving packets received and lost,
 * and signal strengths among the boxes in the cloud.
 */
void do_print_cloud(void)
{
    int i, j, k, r;

    FILE *f = fopen("/tmp/cloud.tmp", "w");
    if (f == NULL) {
        ddprintf("do_print_cloud; could not open /tmp/cloud.tmp:  %s\n",
                strerror(errno));
        goto done;
    }

    fprintf(f, "<html>\n");
    fprintf(f, "<head>\n");
    fprintf(f, "<SCRIPT language=JavaScript>\n");
    fprintf(f, "function init()\n");
    fprintf(f, "{\n");
    fprintf(f, "    x = '<%c set_merge_cloud_db(\"d 2038\"); %c>';\n", '%',
            '%');
    fprintf(f, "}\n");
    fprintf(f, "</SCRIPT>\n");
    fprintf(f, "<META HTTP-EQUIV=\"refresh\" CONTENT=\"5\">\n");
    fprintf(f, "</head>\n");
    fprintf(f, "<body onload=init()>\n");
    fprintf(f, "<p>\n");

    fprintf(f, "<h3>\n");
    fprintf(f, "Cloud connectivity\n");
    fprintf(f, "</h3>\n");

    fprintf(f, "<pre>\n");
    graphit_dprint(eprintf, f, &cloud_stp_tree[0]);

    fprintf(f, "</pre>\n");

    if (!db[38].d) { goto almost_done; }

    /* add all of the cloud_stp_list entries to mac_list, a temporary
     * array giving mac addresses of rows and columns.
     */
    mac_count = 0;

    for (i = 0; i < cloud_stp_list_count; i++) {
        stp_beacon_t *beacon = &cloud_stp_list[i].v.stp_beacon;
        add_mac_addr(beacon->originator);
    }

    /* do the two matrices (packets sent and signal strength) */
    for (r = 0; r < 2; r++) {
        /* print the title of the packet matrix */
        fprintf(f, "<p>\n");
        fprintf(f, "<h3>\n");

        if (r == 0) {
            fprintf(f, "Packets received, packets dropped, "
                    "percent packets received\n");
            fprintf(f, "<br>\n");
            fprintf(f, "(sender at top of column, receiver at start of row)\n");
        } else {
            fprintf(f, "Signal strength\n");
            fprintf(f, "<br>\n");
            fprintf(f, "(how strongly each row entry sees each column entry)\n"
            );
        }

        fprintf(f, "</h3>\n");

        if (cloud_stp_list_count <= 1) { goto almost_done; }

        fprintf(f, "<table frame=box rules=all>\n");

        /* top row; empty first cell, then mac addresses */
        fprintf(f, "    <tr>\n");
        fprintf(f, "        <td> </td>");

        for (j = 0; j < mac_count; j++) {
            /* skip ad-hoc clients for column headers of first matrix */
            if (r == 0 && node_names[j][0] == '(') { continue; }

            fprintf(f, " <td> ");
            //mac_dprint_no_eoln(eprintf, f, mac_list[j]);
            fprintf(f, "%s", node_names[j]);
            fprintf(f, " </td> ");
        }
        fprintf(f, "\n");
        fprintf(f, "    </tr>\n");

        for (i = 0; i < mac_count; i++) {
            stp_beacon_t *src = NULL;

            /* for row entries, ignore ad-hoc clients */
            if (node_names[i][0] == '(') { continue; }

            for (j = 0; j < cloud_stp_list_count; j++) {
                stp_beacon_t *beacon = &cloud_stp_list[j].v.stp_beacon;
                if (mac_equal(mac_list[i], beacon->originator)) {
                    src = beacon;
                    break;
                }
            }
            fprintf(f, "    <tr>\n");

            fprintf(f, "        <td> ");
            // mac_dprint_no_eoln(eprintf, f, mac_list[i]);
            fprintf(f, "%s", node_names[i]);
            fprintf(f, " </td> ");

            for (j = 0; j < mac_count; j++) {
                bool_t did_something = false;

                /* for column entries, ignore ad-hoc clients in first matrix */
                if (r == 0 && node_names[j][0] == '(') { continue; }

                if (src != NULL) {
                    for (k = 0; k < src->status_count; k++) {
                        status_t *s = &src->status[k];

                        if (s->device_type != device_type_wds) { continue; }

                        if (mac_equal(mac_list[j], s->name)) {
                            if (r == 0) {
                                float den = s->packets_received
                                        + s->packets_lost
                                        + s->ping_packets_received
                                        + s->ping_packets_lost;
                                int percent;
                                if (den == 0) {
                                    percent = 100;
                                } else {
                                    float fpct;
                                    fpct = ((float) (s->packets_received
                                                + s->ping_packets_received))
                                            / den;
                                    percent = (int) (.5 + 100. * fpct);
                                }
                                fprintf(f, " <td> %d %d %d%c </td> ",
                                        s->packets_received
                                                + s->ping_packets_received,
                                        s->packets_lost + s->ping_packets_lost,
                                        percent, '%');
                                did_something = true;
                                break;
                            } else {
                                fprintf(f, " <td> %d </td> ", s->sig_strength);
                                did_something = true;
                                break;
                            }
                        }
                    }
                }

                if (!did_something) {
                    fprintf(f, " <td> </td> ");
                }
            }

            fprintf(f, "\n    </tr>\n");
        }

        fprintf(f, "</table>\n");
    }

    almost_done:

    fprintf(f, "</body>\n");
    fprintf(f, "</html>\n");

    if (fclose(f) != 0) {
        ddprintf("do_print_cloud; could not fclose /tmp/cloud.tmp:  %s\n",
                strerror(errno));
        goto done;
    }

    if (rename("/tmp/cloud.tmp", "/tmp/cloud.asp") != 0) {
        ddprintf("do_print_cloud; unable to rename %s to %s:  %s\n",
                "/tmp/cloud.tmp", "/tmp/cloud.asp", strerror(errno));
        goto done;
    }

    done:

    set_next_cloud_print_alarm();

} /* do_print_cloud */
Exemplo n.º 20
0
/* just got a message from raw device d.  if d is not a wds device, the
 * message is ok.  (for now we are just doing flow control over wds
 * connections.)  if it is a wds device, find the corresponding stp link
 * and return true iff we have gotten a sequence packet and are expecting
 * a message.
 */
bool_t message_ok(int d, int message_len)
{
    int i;

    if (!db[22].d) { return true; }

    if (db[23].d) { ddprintf("message_ok;\n"); }

    if (device_list[d].device_type != device_type_wds) {
        if (db[23].d) { ddprintf("    not wds; returning true\n"); }
        return true;
    }

    for (i = 0; i < stp_list_count; i++) {

        if (stp_list[i].box.has_eth_mac_addr
            || !mac_equal(stp_list[i].box.name, device_list[d].mac_address))
        {
            continue;
        }

        if (stp_list[i].box.expect_seq) {
            if (db[23].d) { ddprintf("    !expect_seq; "
                    "returning false\n"); }
            stp_list[i].box.recv_error++;
            return false;
        }

        if (stp_list[i].box.recv_message_len != message_len) {
            if (db[23].d) { ddprintf("    bad message_len; "
                    "returning false\n"); }
            stp_list[i].box.recv_error++;
            return false;
        }

        {
            message_t response;
            memset(&response, 0, sizeof(response));
            response.message_type = ack_sequence_msg;
            response.v.seq.sequence_num = stp_list[i].box.recv_sequence;
            response.v.seq.message_len = stp_list[i].box.recv_message_len;

            if (db[23].d) {
                ddprintf("    sending ack_sequence_msg <%d %d>\n",
                        stp_list[i].box.recv_sequence,
                        stp_list[i].box.recv_message_len);
            }
            mac_copy(response.dest, stp_list[i].box.name);
            if (db[24].d) {
                ddprintf("    not sending ack message..\n");
                db[24].d = false;
            } else {
                send_cloud_message(&response);
            }

            stp_list[i].box.expect_seq = true;

            if (!stp_list[i].box.received_duplicate) {
                stp_list[i].box.recv_sequence++;
            } else {
                stp_list[i].box.received_duplicate = false;
                if (db[23].d) { ddprintf("    received_duplicate; "
                        "returning false\n"); }
                return false;
            }
        }

        if (db[23].d) { ddprintf("    found it; returning true\n"); }
        return true;
    }

    if (db[23].d) { ddprintf("    didn't find it; returning false\n"); }
    return false;
}
Exemplo n.º 21
0
/* we have received a sequence message from another cloud box.  see if
 * it is the sequence message we expected.  tally any errors we detect
 * if we weren't expecting a sequence message, if we got one that didn't
 * agree with what we expected, etc.  if everything is fine, update our
 * state to indicate that we are not expecting a sequence number from
 * the cloud box that sent it any more.
 */
void process_sequence_msg(message_t *message, int d)
{
    int i;

    if (db[23].d) {
        ddprintf("process_sequence_msg processing <%d %d>\n",
                message->v.seq.sequence_num,
                message->v.seq.message_len);
    }

    if ((!ad_hoc_mode && device_list[d].device_type != device_type_wds)
        || (ad_hoc_mode && device_list[d].device_type != device_type_ad_hoc))
    {
        ddprintf("process_sequence_msg:  message from non-wds device.\n");
        return;
    }

    for (i = 0; i < stp_list_count; i++) {

        if (stp_list[i].box.has_eth_mac_addr
            || !mac_equal(stp_list[i].box.name, device_list[d].mac_address))
        {
            continue;
        }

        if (!stp_list[i].box.expect_seq) {
            ddprintf("process_sequence_msg:  stp device not expecting seq.\n");
            stp_list[i].box.recv_error++;
            return;
        }

        /* is this a duplicate? */
        if (stp_list[i].box.recv_sequence
            == (byte) (message->v.seq.sequence_num + 1))
        {
            ddprintf("process_sequence_msg:  got duplicate message.\n");
            stp_list[i].box.received_duplicate = true;
            stp_list[i].box.recv_error++;

        } else if (stp_list[i].box.recv_sequence
                != message->v.seq.sequence_num
                && stp_list[i].box.recv_sequence_error < MAX_SEQUENCE_ERROR)
        {
            ddprintf("process_sequence_msg:  expecting sequence num %d, "
                    "got %d.\n",
                    stp_list[i].box.recv_sequence,
                    message->v.seq.sequence_num);
            stp_list[i].box.recv_sequence_error++;
            stp_list[i].box.recv_error++;
            return;

        } else if (stp_list[i].box.recv_sequence
                != message->v.seq.sequence_num
                && stp_list[i].box.recv_sequence_error >= MAX_SEQUENCE_ERROR)
        {
            ddprintf("process_sequence_msg:  expecting sequence num %d, "
                    "got %d.  but, sequence_error threshold exceeded.\n"
                    "resetting recv_sequence.\n",
                    stp_list[i].box.recv_sequence,
                    message->v.seq.sequence_num);
            stp_list[i].box.recv_sequence = message->v.seq.sequence_num;
            stp_list[i].box.recv_error++;

        } else {
            stp_list[i].box.recv_sequence_error = 0;
            if (db[23].d) {
                ddprintf("process_sequence_msg:  got sequence num %d, "
                        "which we expected.\n",
                        message->v.seq.sequence_num);
            }
        }

        stp_list[i].box.expect_seq = false;
        stp_list[i].box.recv_message_len = message->v.seq.message_len;

        break;
    }
}
Exemplo n.º 22
0
/* expire any stale mac addresses from the mac_list.
 * add mac_address to the list, or if it's already there refresh its
 * time to "now".
 *
 * include name, signal_strength, and desc in the record for this mac address.
 */
void mac_list_add(mac_list_t *mac_list, mac_address_t mac_addr,
        mac_address_t name, int signal_strength, char *desc, bool_t write_um)
{
    int i, this_beacon;
    struct timeval tv;
    struct timezone tz;

    if (gettimeofday(&tv, &tz)) {
        fprintf(stderr, "mac_list_add; gettimeofday failed\n");
        return;
    }

    if (mac_list_expire_timed_macs(mac_list)) {
        fprintf(stderr, "mac_list_add; mac_list_expire_timed_macs failed\n");
        return;
    }

    this_beacon = -1;
    for (i = 0; i < mac_list->next_beacon; i++) {
        if (mac_equal(mac_addr, mac_list->beacons[i].mac_addr)) {
            this_beacon = i;
            break;
        }
    }
    if (this_beacon == -1) {
        if (mac_list->next_beacon == MAX_CLOUD) {
            fprintf(stderr, "mac_list_add; too many mac addresses\n");
            return;
        }

        mac_copy(mac_list->beacons[mac_list->next_beacon].mac_addr, mac_addr);
        this_beacon = mac_list->next_beacon;
        mac_list->next_beacon++;
    }

    mac_copy(mac_list->names[this_beacon], name);
    if (desc != NULL) {
        strncpy(mac_list->desc[this_beacon], desc, MAX_DESC);
    }
    if (signal_strength != NO_SIGNAL_STRENGTH) {
        mac_list->signal_strength[this_beacon] = signal_strength;
    }

    mac_list->beacons[this_beacon].tv_sec = tv.tv_sec;
    mac_list->beacons[this_beacon].tv_usec = tv.tv_usec;

    #ifdef DEBUG
        if (debug_file_inited) {
            fprintf(debug_file, "%s; time update ", mac_list->fname);
            mac_print_no_eoln(debug_file,
                    mac_list->beacons[this_beacon].mac_addr);
            fprintf(debug_file, " at ");
            util_print_time(debug_file, &tv);
            fprintf(debug_file, "\n");
            fflush(debug_file);
        }
    #endif

    if (write_um) {
        if (mac_list_write(mac_list)) {
            fprintf(stderr, "mac_list_add; write_beacons failed\n");
        }
    }
}
Exemplo n.º 23
0
/* we have an incoming message from another cloud box.
 * see if the message has a sequence number, and compare it to our
 * own sequence number for that box.  this allows us to see if we
 * got missing packets or duplicate packets from the other box.
 *
 * broadcast pings are treated specially; they have type "ping_response_msg"
 * and broadcast mac address as destination.  so, we keep track of pings
 * from all cloud boxes.
 *
 * otherwise, use the dest mac address to find the index of the sender
 * among our neighbors.
 *
 * tally received packet count and error count (number of packets missed
 * or duplicated) in three categories:
 *
 *  - broadcast pings
 *  - cloud protocol messages (received via a separate set of interfaces
 *        (eth0.1 etc.)
 *  - raw client data packets received
 */
void sequence_check(message_t *message, int device_index, int dev_index)
{
    int pind;
    int diff;
    byte last_recvd, incoming;
    mac_address_ptr_t neighbor;
    bool_t have_recv_seq;
    bool_t bcast_ping = false;

    neighbor = get_name(device_index, message->eth_header.h_source);
    if (neighbor == NULL) {
        ddprintf("sequence_check; couldn't find neighbor for ");
        mac_dprint(eprintf, stderr, message->eth_header.h_source);
    }

    if (mac_equal(message->eth_header.h_dest, mac_address_bcast)
        && message->message_type == ping_response_msg)
    {
        bcast_ping = true;
    }

    if ((!bcast_ping
        && mac_equal(message->eth_header.h_dest, mac_address_bcast))
        || mac_equal(message->eth_header.h_dest, mac_address_zero))
    {
        return;
    }

    pind = status_find_by_mac(perm_io_stat, perm_io_stat_count, neighbor);

    if (pind == -1) {
        if (db[48].d) {
            ddprintf("sequence_check; no pind; returning.\n");
        }
        return;
    }

    if (bcast_ping) {
        perm_io_stat[pind].ping_packets_received++;
        have_recv_seq = have_recv_ping_sequence[pind];
        last_recvd = recv_ping_sequence[pind];

    } else if (message->eth_header.h_proto == htons(CLOUD_MSG)) {
        perm_io_stat[pind].packets_received++;
        have_recv_seq = have_recv_sequence[pind];
        last_recvd = recv_sequence[pind];

    } else {
        perm_io_stat[pind].data_packets_received++;
        have_recv_seq = have_recv_data_sequence[pind];
        last_recvd = recv_data_sequence[pind];
    }

    incoming = message->sequence_num;

    #ifdef DEBUG_48
    if (db[48].d) {
        ddprintf("sequence_check; seq got <%d %d %d> "
                "expected <%d %d %d>\n",
                incoming, device_index, dev_index,
                last_recvd, db_i[pind], db_dev_index[pind]);
    }
    #endif

    if (have_recv_seq) {

        if (incoming != (last_recvd + 1) % 256) {
            diff = ((int) incoming) - ((int) last_recvd);

            if (diff != 0) {
                if (diff < 0) { diff += 256; }
                if (bcast_ping) {
                    perm_io_stat[pind].ping_packets_lost += diff;

                } else if (message->eth_header.h_proto == htons(CLOUD_MSG)) {
                    perm_io_stat[pind].packets_lost += diff;

                } else {
                    perm_io_stat[pind].data_packets_lost += diff;
                }
            }

            if (db[48].d) {
                ddprintf("seq error; diff %d\n", diff);
            }
        }
    }

    if (bcast_ping) {
        have_recv_ping_sequence[pind] = true;
        recv_ping_sequence[pind] = incoming;

    } else if (message->eth_header.h_proto == htons(CLOUD_MSG)) {
        have_recv_sequence[pind] = true;
        recv_sequence[pind] = incoming;

    } else {
        have_recv_data_sequence[pind] = true;
        recv_data_sequence[pind] = incoming;
    }

    #ifdef DEBUG_48
        memcpy(&db_messages[pind], message, sizeof(message));
        db_i[pind] = device_index;
        db_dev_index[pind] = dev_index;
    #endif

} /* sequence_check */
Exemplo n.º 24
0
/* add children of new_stp_list[ind].  we do this by looking at
 * the status array of new_stp_list[ind].  for each of those, we see
 * if we have a valid back pointer, based on my_beacon, beacon if we have
 * a new one, or cloud_stp_list.  for valid dest nodes we find, see which
 * ones are not yet in new_stp_list, and add those as children.  the
 * new_stp_list entries we copy will be beacon if we have it and the
 * dest matches beacon's originator field, or from cloud_stp_list, our
 * old version of this data structure that contains most recent beacons
 * from all nodes we were connected to the last time this set of routines
 * was run.
 */
static void add_children(int ind)
{
    int i, j;
    int prev_new_stp_list_count, next_new_stp_list_count;
    stp_beacon_t *node = &new_stp_list[ind].v.stp_beacon;
    char buf[20];

    if (db[32].d) { ddprintf("add_children..\n"); }

    prev_new_stp_list_count = new_stp_list_count;

    new_stp_child_start[ind] = new_stp_list_count;
    new_stp_child_count[ind] = 0;

    mac_sprintf(new_node_names[ind], node->originator);
    if (db[32].d) {
        ddprintf("added new_node_names[%d]:  %s\n", ind,
                mac_sprintf(buf, node->originator));
    }

    for (i = 0; i < node->status_count; i++) {
        status_t *s = &node->status[i];
        message_t *new_node = NULL;

        if (s->device_type != device_type_wds) { continue; }

        if (s->neighbor_type != STATUS_CLOUD_NBR) { continue; }

        if (in_mac_list(new_stp_list, new_stp_list_count, s->name)) {
            continue;
        }

        if (!has_valid_back_pointer(node->originator, s->name)) {
            continue;
        }

        if (have_beacon
            && mac_equal(s->name, beacon.v.stp_beacon.originator))
        {
            new_node = &beacon;

        } else {
            for (j = 0; j < cloud_stp_list_count; j++) {
                if (mac_equal(s->name,
                    cloud_stp_list[j].v.stp_beacon.originator))
                {
                    new_node = &cloud_stp_list[j];
                    break;
                }
            }
        }

        if (new_node == NULL || new_stp_list_count >= MAX_CLOUD) { break; }

        new_stp_list[new_stp_list_count] = *new_node;
        new_stp_child_count[new_stp_list_count] = 0;
        new_stp_list_count++;

        new_stp_child_count[ind]++;

        if (db[32].d) {
            ddprintf("add ");
            mac_dprint(eprintf, stderr,
                    new_stp_list[new_stp_list_count - 1]
                            .v.stp_beacon.originator);
        }
    }

    next_new_stp_list_count = new_stp_list_count;

    /* add any ad-hoc clients that this box serves */
    for (i = 0; i < node->status_count; i++) {
        status_t *s = &node->status[i];
        char buf[20];

        if (s->neighbor_type != STATUS_NON_CLOUD_CLIENT) { continue; }

        if (in_mac_list(new_stp_list, new_stp_list_count, s->name))
        { continue; }

        if (new_stp_list_count >= MAX_CLOUD) { break; }

        new_stp_child_count[ind]++;

        /* not really necessary since we now init new_node_names[i] here */
        mac_copy(new_stp_list[new_stp_list_count].v.stp_beacon.originator,
                s->name);

        new_stp_child_count[new_stp_list_count] = 0;

        sprintf(new_node_names[new_stp_list_count], "(%s)",
                mac_sprintf(buf, s->name));

        new_stp_list_count++;
    }

    for (i = prev_new_stp_list_count; i < next_new_stp_list_count; i++) {
        add_children(i);
    }

    if (db[32].d) {
        ddprintf("done add_children(%d)..\n", ind);
        dprint_db_cloud_stats(eprintf, stderr, new_stp_list,
                new_stp_child_start, new_stp_child_count,
                new_stp_list_count);
    }
}
Exemplo n.º 25
0
/* see which wds devices we are getting beacons from.  (this routine doesn't
 * look at the ethernet connection or the wlan connection.  those devices
 * are added at startup, the latter only if we were told to do so from the
 * command line.  they don't come and go.  only the wds devices
 * come and go.)
 *
 * this routine manages the device_list array, which includes if_index,
 * file descriptor, etc. to support actual low-level communication.
 */
char check_devices(void)
{
    char result = 0;
    int retval;
    static struct ifreq get_index;
    struct sockaddr_ll bind_arg;
    char wds_devices[MAX_CLOUD][64];
    mac_address_t wds_macs[MAX_CLOUD];
    int wds_count = 0;
    int w, d;
    char buf[64];

    FILE *wds = fopen(wds_file, "r");
    if (wds == NULL) {
        ddprintf("check_devices; fopen failed:  %s\n", strerror(errno));
        ddprintf("    file:  '%s'\n", wds_file);
        goto finish;
    }

    /* read the mac addresses of the wds devices into
     * local array wds_devices
     */
    while (1) {
        if (wds_count >= MAX_CLOUD) {
            ddprintf("check_devices:  too many wds devices\n");
            break;
        }

        if (skip_comment_line(wds) != 0) {
            ddprintf("check_devices; problem reading file.\n");
            break;
        }


        #ifdef WRT54G
            retval = mac_read(wds, wds_macs[wds_count]);
        #else
            retval = fscanf(wds, "%s", wds_devices[wds_count]);
        #endif

        if (retval != 1) { break; }

        #ifdef WRT54G
            retval = fscanf(wds, "%s", wds_devices[wds_count]);
        #else
            retval = mac_read(wds, wds_macs[wds_count]);
        #endif

        if (retval != 1) {
            ddprintf("check_devices; could not read device name from wds\n");
            goto finish;
        }
        wds_count++;
    }

    top :
    /* see if every wds device in our list matches current truth */
    for (d = 0; d < device_list_count; d++) {
        int found = 0;

        if (device_list[d].device_type != device_type_wds
            && device_list[d].device_type != device_type_cloud_wds)
        { continue; }
        
        for (w = 0; w < wds_count; w++) {
            if (mac_equal(device_list[d].mac_address, wds_macs[w])) {
                found = 1;
                break;
            }
        }

        if (!found
            || strstr(device_list[d].device_name, wds_devices[w]) == NULL)
        {
            result = 1;
            delete_device(d);
            goto top;
        }

        if (!use_pipes) {
            /* check to see that the if_index is still the same.
             * (if "wds0.2" gets deleted and then re-created, it probably
             * has a different if_index.)
             */
            sprintf(get_index.ifr_name, device_list[d].device_name);
            retval = ioctl(device_list[d].fd, SIOCGIFINDEX, &get_index);
            if (retval == -1) {
                ddprintf("check_devices; could not get device index:  %s\n",
                        strerror(errno));
                goto finish;
            }
            if (device_list[d].if_index != get_index.ifr_ifindex) {
                device_list[d].if_index = get_index.ifr_ifindex;
                memset(&bind_arg, 0, sizeof(bind_arg));
                bind_arg.sll_family = AF_PACKET;
                bind_arg.sll_ifindex = get_index.ifr_ifindex;
                bind_arg.sll_protocol = htons(ETH_P_ALL);

                retval = bind(device_list[d].fd, (struct sockaddr *) &bind_arg,
                        sizeof(bind_arg));
                if (retval == -1) {
                    ddprintf("check_devices; bind failed:  %s\n",
                            strerror(errno));
                    goto finish;
                }
                result = 1;
                goto top;
            }
        }
    }

    /* see if every device out there is in our local table */
    for (w = 0; w < wds_count; w++) {
        int found = 0;

        for (d = 0; d < device_list_count; d++) {
            if (mac_equal(device_list[d].mac_address, wds_macs[w])) {
                found = 1;
                break;
            }
        }

        if (!found) {
            result = 1;
            add_device(
                    ad_hoc_mode ? "ad-hoc device" : wds_devices[w],
                    wds_macs[w],
                    ad_hoc_mode ? device_type_ad_hoc : device_type_wds);

            if (!ad_hoc_mode && db[47].d) {
                sprintf(buf, "%s:1", wds_devices[w]);
                add_device(buf, wds_macs[w], device_type_cloud_wds);
            }
        }
    }

    finish :

    if (wds != NULL) { fclose(wds); }

    return result;

} /* check_devices */
Exemplo n.º 26
0
/* accept this node iff it is not equal to "delete_me". */
char delete_node(node_t *node)
{
    return (!mac_equal(node->box.name, delete_me));
}