int send_packet(struct sr_instance* sr, char* iface, uint8_t* dstMAC, uint8_t* payload, unsigned int len, uint16_t type) { assert(sr); assert(payload); assert(iface); uint8_t* packet = (uint8_t*)malloc_or_die(len + 14); struct sr_ethernet_hdr* tmpHdr = (struct sr_ethernet_hdr*) malloc_or_die(14* sizeof(uint8_t)); struct sr_vns_if* interface = sr_get_interface(sr, iface); mac_copy(dstMAC, tmpHdr->ether_dhost); mac_copy(interface->addr, tmpHdr->ether_shost); tmpHdr->ether_type = htons(type); memcpy(packet, tmpHdr, 14); packet = packet + 14; memcpy(packet, payload, len); packet = packet - 14; if((sr_integ_low_level_output(sr, packet, (unsigned int)(len + 14), iface)) == 0) { printf("********** %s successfully sent a packet reply\n", __func__); return 1; } else { printf("\n @@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@ %s sending packet failed?\n", __func__); return 0; } return -1; }
/* set up link-level communication from eth_mac_addr (my end) to * client_mac_addr (his end). interface has already been opened, * with raw socket "socket" and interface index if_index. * if pio is non-null, use pipe-based communication in simulation environment. */ void com_util_init(int socket, int if_index, pio_t *pio, mac_address_t eth_mac_addr, mac_address_t client_mac_addr) { if (pio != NULL) { out_pio = pio; have_out_pio = 1; } packet_socket = socket; eth_if_index = if_index; mac_copy(my_mac_addr, eth_mac_addr); mac_copy(dest_mac_addr, client_mac_addr); }
/* someone sent a cloud ping message to us. we send a ping response back. */ void process_ping_msg(message_t *message, int device_index) { mac_address_ptr_t sender; message_t response; memset(&response, 0, sizeof(response)); sender = get_name(device_index, message->eth_header.h_source); if (db[7].d) { ddprintf("got ping from "); if (sender == NULL) { ddprintf(" <NULL> (from get_name)\n"); } else { mac_dprint(eprintf, stderr, sender); } } if (sender != NULL) { if (db[7].d) { ddprintf("send response..\n"); } response.message_type = ping_response_msg; mac_copy(response.dest, sender); send_cloud_message(&response); } else { ddprintf("process_ping_msg; get_name could not find mac address " "of sender\n"); } }
/* initialize internal mac_list of other boxes we see eth_beacons from, * our internal LAN mac address, and our wireless mac address. (we send * the latter out in the eth_beacons, because the wireless mac address is * considered the "name" or identifier of each cloud box.) */ void eth_util_init(char *beacon_file, int socket, int if_index, pio_t *pio, mac_address_t eth_mac_addr, mac_address_t box_wlan_mac_addr) { mac_list_init(&beacons, beacon_file, mac_list_beacon_name, ETH_TIMEOUT_USEC, true); if (pio != NULL) { out_pio = pio; use_pipe = 1; } packet_socket = socket; eth_if_index = if_index; mac_copy(my_mac_addr, eth_mac_addr); mac_copy(name_mac_addr, box_wlan_mac_addr); }
/* we've received a message from the other side. look at the protocol * byte in the message and decide what to do with it based on that. * * if it's a shell command, write the command to our local interactive * shell. * * if its part of the protocol to send or receive a file, do that. */ int com_util_process_message(unsigned char *buf) { message_t *message = (message_t *) buf; mac_copy(dest_mac_addr, *(mac_address_t *) message->eth_header.h_source); if (db[6].d) { fprintf(stderr, "processing message type %s; set dest_mac_addr to ", com_util_message_string(message->msg_type)); mac_print(stderr, dest_mac_addr); } if (message->msg_type == shell_cmd_msg) { if (-1 == write(new_stdin[1], message->msg_body, message->msg_body_len)) { perror("write to stdout of shell failed"); return -1; } } else if (message->msg_type == start_shell_msg) { byte recv_buf[8]; int int_buf; seq = 1; int_buf = htonl(message->msg_body_len - 4); memcpy(&recv_buf[0], (char *) &int_buf, 4); int_buf = htonl(seq); memcpy(&recv_buf[4], (char *) &int_buf, 4); send_message(recv_buf, 8, recv_ok_msg); } else if (message->msg_type == put_name_msg) { start_receiving_file(message); } else if (message->msg_type == transfer_cont_msg) { continue_receiving_file(message); } else if (message->msg_type == transfer_end_msg) { end_receiving_file(message); } else if (message->msg_type == get_name_msg) { start_sending_file(message); } else if (message->msg_type == recv_ok_msg || message->msg_type == recv_err_msg || message->msg_type == recv_err_stop_msg) { continue_sending_file(message); } return 0; }
/* send an eth_beacon out our cat-5 internal LAN interface via using a * link-level raw socket. the message contains this box's "name" * (wireless interface mac address), and in the packet header it contains * our LAN interface mac address and the eth_beacon protocol short int. */ static void send_beacon() { int result; #if DEBUG0 printf("hi from send_beacon..\n"); #endif mac_copy((mac_address_ptr_t) &buf[sizeof(struct ethhdr)], my_mac_addr); mac_copy((mac_address_ptr_t) &buf[sizeof(struct ethhdr) + sizeof(mac_address_t)], name_mac_addr); ethhdr_p->h_proto = htons(0x2984); mac_copy(ethhdr_p->h_dest, other_mac_addr); mac_copy(ethhdr_p->h_source, my_mac_addr); if (cooked_out_file == NULL) { memset(&send_arg, 0, sizeof(send_arg)); send_arg.sll_family = AF_PACKET; send_arg.sll_ifindex = eth_if_index; send_arg.sll_halen = 6; mac_copy(send_arg.sll_addr, other_mac_addr); result = sendto(packet_socket, buf, sizeof(struct ethhdr) + 12, 0, (struct sockaddr *) &send_arg, sizeof(send_arg)); } else { result = pio_write(out_pio, buf, sizeof(struct ethhdr) + 12); } if (result == -1) { fprintf(stderr, "sendto errno %d(%s)\n", errno, strerror(errno)); } else { #if DEBUG0 printf("sendto result %d\n", result); #endif } }
/* broadcast a ping message so that other cloud boxes can see that we are * still alive. these messages are received via cloud protocol interface, * so they are more reliable than 802.11 beacons. * we just want to send them a little keep-alive message, and don't need * a response. So we send ping_response_msg. */ void do_ping_neighbors() { message_t message; memset(&message, 0, sizeof(message)); got_interrupt[ping_neighbors] = 0; if (!db[46].d) { return; } message.message_type = ping_response_msg; mac_copy(message.dest, mac_address_bcast); send_cloud_message(&message); set_next_ping_alarm(); }
/* send a sequence number message. this is an addition to the protocol * to attempt to improve message delivery robustness at the link level, * at the expense of bandwidth. */ void send_seq(int stp_ind, byte *message, int msg_len) { message_t seq_msg; if (!db[22].d) { return; } if (db[23].d) { ddprintf("send_seq sending <%d %d> to ", stp_list[stp_ind].box.send_sequence, msg_len); mac_dprint(eprintf, stderr, stp_list[stp_ind].box.name); } #if 0 /* test-harness code; don't send a sequence message, to test the * protocol when a sequence message gets dropped. */ if (db[24].d) { ddprintf("send_seq intentionally dropping packet..\n"); db[24].d = false; return; } #endif seq_msg.message_type = sequence_msg; seq_msg.v.seq.sequence_num = stp_list[stp_ind].box.send_sequence; stp_list[stp_ind].box.awaiting_ack = true; if (msg_len > CLOUD_BUF_LEN) { seq_msg.v.seq.message_len = 0; stp_list[stp_ind].box.message_len = 0; ddprintf("send_seq got message with invalid length %d\n", msg_len); } else { seq_msg.v.seq.message_len = msg_len; stp_list[stp_ind].box.message_len = msg_len; memmove((void *) &stp_list[stp_ind].box.message, message, msg_len); } mac_copy(seq_msg.dest, stp_list[stp_ind].box.name); send_cloud_message(&seq_msg); update_ack_timer(); } /* send_seq */
/* if the status array does not have an entry with mac address mac, add * one, with the given device type */ int status_add_by_mac(status_t *status, int *status_count, mac_address_t mac, device_type_t type) { int result; result = status_find_by_mac(status, *status_count, mac); if (result != -1) { return result; } if (*status_count >= MAX_CLOUD) { return -1; } memset(&status[*status_count], 0, sizeof(status[*status_count])); mac_copy(status[*status_count].name, mac); status[*status_count].device_type = type; (*status_count)++; return *status_count - 1; }
/* 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); }
/* debugging (non-protocol) routine to send a ping message to every * neighbor box */ void send_nbr_pings() { int i; message_t message; memset(&message, 0, sizeof(message)); memset(&message, 0, sizeof(message)); message.message_type = ping_msg; for (i = 0; i < nbr_device_list_count; i++) { if (db[7].d) { ddprintf("send ping to "); mac_dprint(eprintf, stderr, nbr_device_list[i].name); } mac_copy(message.dest, nbr_device_list[i].name); send_cloud_message(&message); } }
/* 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 */
void pb_push_packet(mac_addr dhost_ether, dessert_msg_t* msg, struct timeval* timestamp) { pb_cleanup(timestamp); pb_el_t* pb_el; HASH_FIND(hh, pbt.entries, dhost_ether, ETH_ALEN, pb_el); if(pb_el == NULL) { pb_el = malloc(sizeof(pb_el_t)); if(pb_el == NULL) { dessert_msg_destroy(msg); return; } mac_copy(pb_el->dhost_ether, dhost_ether); pb_el->fl.head = pb_el->fl.tail = NULL; pb_el->fl.size = 0; HASH_ADD_KEYPTR(hh, pbt.entries, pb_el->dhost_ether, ETH_ALEN, pb_el); } fl_push_packet(&pb_el->fl, msg); timeslot_addobject(pbt.ts, timestamp, pb_el); }
/* for interface "device_name" (i.e., eth0 etc.), open a raw socket to * the interface and get a file descriptor for the socket. add the * interface (file descriptor and all) to device_list[]. * * as a special case, if the device type is an ad-hoc, that means this * is a description of another cloud box that we are communicating with * in ad-hoc mode. in that case, find and copy the device_list[] entry * for our wireless lan interface. */ void add_device(char *device_name, mac_address_t mac_address, device_type_t device_type) { device_t *device; static struct ifreq get_index; int result; struct sockaddr_ll bind_arg; mac_address_t mac_addr; int i; device_t *wlan; if (device_list_count >= MAX_CLOUD) { ddprintf("add_device: too many devices.\n"); goto finish; } device = &device_list[device_list_count]; device->sim_device = 0; device->expect_k = 0; device->expect_n = -1; // if (db[0].d) { ddprintf("hi from add_device(%s)..\n", device_name); // } if (strstr(device_name, "wds") != NULL && device_type == device_type_wds) { device->device_type = device_type_wds; } else if (strstr(device_name, "wds") != NULL && device_type == device_type_cloud_wds) { device->device_type = device_type_cloud_wds; } else if (strcmp(device_name, wlan_device_name) == 0 && device_type == device_type_wlan) { device->device_type = device_type_wlan; } else if (eth_device_name != NULL && strcmp(device_name, eth_device_name) == 0) { device->device_type = device_type_eth; } else if (have_mon_device && strcmp(device_name, wlan_mon_device_name) == 0) { device->device_type = device_type_wlan_mon; } else if (ad_hoc_mode && device_type == device_type_ad_hoc) { bool_t found = false; device->device_type = device_type_ad_hoc; for (i = 0; i < device_list_count; i++) { if (device_list[i].device_type == device_type_wlan) { found = true; wlan = &device_list[i]; break; } } if (!found) { ddprintf("add_device; couldn't find wireless device in ad_hoc mode"); goto finish; } } else if (/*ad_hoc_mode &&*/ device_type == device_type_cloud_wlan) { device->device_type = device_type_cloud_wlan; } else if (/*ad_hoc_mode &&*/ device_type == device_type_cloud_eth) { device->device_type = device_type_cloud_eth; } else { ddprintf("add_device; unknown device_type '%s'\n", device_name); goto finish; } if (mac_address == 0) { result = mac_get(mac_addr, device_name); if (result != 0) { ddprintf("add_device: mac_get on %s failed.\n", device_name); goto finish; } } else { mac_copy(mac_addr, mac_address); } if (ad_hoc_mode && device_type == device_type_ad_hoc) { sprintf(device->device_name, wlan_device_name); } else { sprintf(device->device_name, device_name); } mac_copy(device->mac_address, mac_addr); if (use_pipes) { char fname[PATH_MAX]; int fd; sprintf(fname, "%s/%s.cloud", pipe_directory, device_name); fd = repeat_open(fname, O_RDWR); ddprintf("opening wlan input device %s; fd %d\n", fname, fd); if (fd == -1) { ddprintf("add_device; could not open pipe %s: %s\n", fname, strerror(errno)); goto finish; } device->fd = fd; pio_init_from_fd(&device->in_pio, fname, fd); ddprintf("done..\n"); sprintf(fname, "%s/%s.cooked", pipe_directory, device_name); fd = repeat_open(fname, O_RDWR); ddprintf("opening wlan output device %s; fd %d\n", fname, fd); if (fd == -1) { ddprintf("add_device; could not open pipe %s: %s\n", fname, strerror(errno)); goto finish; } device->out_fd = fd; pio_init_from_fd(&device->out_pio, fname, fd); ddprintf("done..\n"); } else if (ad_hoc_mode && device_type == device_type_ad_hoc) { device->fd = wlan->fd; device->if_index = wlan->if_index; } else { device->fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (device->fd == -1) { ddprintf("add_device: socket failed\n"); goto finish; } /* after a change of wep key, this fails. may need to delete and * re-create wds interface? */ sprintf(get_index.ifr_name, device_name); result = ioctl(device->fd, SIOCGIFINDEX, &get_index); if (result == -1) { ddprintf("add_device: could not get device index\n"); goto finish; } device->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; if (device_type == device_type_cloud_wlan || device_type == device_type_cloud_eth || device_type == device_type_cloud_wds) { bind_arg.sll_protocol = htons(CLOUD_MSG); } else if (db[47].d && ((ad_hoc_mode && !db[50].d && device_type == device_type_wlan) || device_type == device_type_wds)) { bind_arg.sll_protocol = htons(WRAPPED_CLIENT_MSG); } else { bind_arg.sll_protocol = htons(ETH_P_ALL); } result = bind(device->fd, (struct sockaddr *) &bind_arg, sizeof(bind_arg)); if (result == -1) { ddprintf("add_device: bind failed\n"); goto finish; } } if (db[50].d && device_type == device_type_ad_hoc) { ad_hoc_client_add(device->mac_address); } add_io_stat(device); device_list_count++; finish : // if (db[0].d) { ddprintf("this device:\n"); print_device(eprintf, stderr, &device_list[device_list_count - 1]); ddprintf("all devices:\n"); print_devices(); // } } /* add_device */
/* 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; }
/* 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); } }
/* 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"); } } }
/* read the mac_list in from its associated file. * return 0 on success, -1 on failure. * read up to a maximum of MAX_CLOUD mac addresses, * and read the extra info associated with each mac address, based on * the type of the mac_list. * initialize the mac address times to "now". */ int mac_list_read(mac_list_t *mac_list) { int result = 0; struct timeval tv; struct timezone tz; FILE *f; if (gettimeofday(&tv, &tz)) { fprintf(stderr, "mac_list_read; gettimeofday failed\n"); return -1; } f = fopen(mac_list->fname, "r"); if (f == NULL) { perror("mac_list_read fopen failed"); fprintf(stderr, " could not open %s\n", mac_list->fname); result = -1; goto done; } mac_list->next_beacon = 0; while (1) { mac_address_t mac_addr; if (1 != mac_read(f, mac_addr)) { break; } if (mac_list->next_beacon >= MAX_CLOUD) { fprintf(stderr, "mac_list_read: too many entries in file\n"); result = -1; goto done; } mac_copy(mac_list->beacons[mac_list->next_beacon].mac_addr, mac_addr); mac_list->beacons[mac_list->next_beacon].tv_sec = tv.tv_sec; mac_list->beacons[mac_list->next_beacon].tv_usec = tv.tv_usec; /* check scanf results etc. to bullet-proof */ switch (mac_list->type) { case mac_list_beacon_desc : fscanf(f, "%s", mac_list->desc[mac_list->next_beacon]); break; case mac_list_beacon_name : mac_read(f, mac_list->names[mac_list->next_beacon]); break; case mac_list_beacon_signal_strength : fscanf(f, " %d\n", &mac_list->signal_strength[mac_list->next_beacon]); break; case mac_list_beacon : break; default : fprintf(stderr, "mac_list_read: invalid type %d\n", mac_list->type); break; } mac_list->next_beacon++; } done: if (f != NULL) { fclose(f); } return result; }
/* send buf to the other side. if we are using a link-level raw socket, * set up the "sendto" arguments to shove * the bits through the raw socket interface. * if an IP connection, do the "write()". * if a pipe, send the bytes through the pipe. * * if the buffer is too * long to fit in one sendto message, break the * buffer up into multiple chunks and send them separately. */ static void send_message(unsigned char *buf, int buflen, msg_type_t msg_type) { int result; message_t msg; if (db[1].d) { printf("hi from send_message.. sending %d bytes\n", buflen); } if (cooked_out_file == NULL) { memset(&send_arg, 0, sizeof(send_arg)); send_arg.sll_family = AF_PACKET; send_arg.sll_ifindex = eth_if_index; send_arg.sll_halen = 6; mac_copy(send_arg.sll_addr, dest_mac_addr); } msg.eth_header.h_proto = htons(0x2985); mac_copy(msg.eth_header.h_dest, dest_mac_addr); mac_copy(msg.eth_header.h_source, my_mac_addr); while (buflen > 0) { int next_gulp; if (buflen > BUF_LEN) { next_gulp = BUF_LEN; } else { next_gulp = buflen; } memcpy((void *) msg.msg_body, buf, next_gulp); msg.msg_body_len = next_gulp; msg.msg_type = msg_type; buf += next_gulp; buflen -= next_gulp; if (db[1].d) { fprintf(stderr, "sending %ld bytes..\n", (unsigned long) &(msg.msg_body[next_gulp]) - (unsigned long) &msg); } if (cooked_out_file == NULL) { result = sendto(packet_socket, (void *) &msg, (char *) &(msg.msg_body[next_gulp]) - (char *) &msg, 0, (struct sockaddr *) &send_arg, sizeof(send_arg)); } else if (have_out_pio) { result = pio_write(out_pio, (void *) &msg, (char *) &(msg.msg_body[next_gulp]) - (char *) &msg); } else { result = write(out_fd, (void *) &msg, (char *) &(msg.msg_body[next_gulp]) - (char *) &msg); } if (result == -1) { com_errors++; if (db[5].d) { fprintf(stderr, "sendto/write errno %d (%s)\n", errno, strerror(errno)); } } else { #if DEBUG0 printf("sendto result %d\n", result); #endif } } }