Esempio n. 1
0
static int receive_msg(int fd, char *rx, size_t size,
			unsigned int timeout, bool debug)
{
	fd_set fds;
	struct timeval tv;
	int ret;
	unsigned int count;

	/* Initialize structures for select */
	FD_ZERO(&fds);
	FD_SET(fd, &fds);

	/*
	 * Microcontrolle answers very fast,
	 * Timeout is just to take care if no answer is
	 * sent
	 */
	tv.tv_sec = timeout;
	tv.tv_usec = 0; /* Check for not more as 10 mSec */

	ret = select(fd + 1, &fds, NULL, NULL, &tv);
	if (ret == 0) {
		ERROR("Timeout, no answer from microcontroller");
		return -EPROTO;
	}

	ret = read(fd, rx, size);
	if (ret < 3) {
		ERROR("Error in read: %d", ret);
		return -EBADMSG;
	}
	count = ret;

	if (debug)
		dump_ascii(true, rx, count);

	/*
	 * Try some syntax check
	 */
	if (rx[0] != '$') {
		ERROR("First byte is not '$' but '%c'", rx[0]);
		return -EBADMSG;
	}

	if (!verify_chksum(rx, &count)) {
		return -EBADMSG;
	}

	return 0;
}
Esempio n. 2
0
char* layer2(char* in, char dir) {
	debug("********** LAYER 2 **********");
	size_t len = strlen(in);
	debug("%zi bytes, direction: %c ", len, dir);
	char *out = NULL;
	if (dir == 's') { 	// Send data
		int nfrm = len/(FS-FSH) + (len % (FS-FSH) ? 1 : 0);
		debug("%i frame(s) detected", nfrm);

		// Allocate twice the frame size for max amount of DLEs
		if(!(out = calloc((nfrm)*FS*2, sizeof(char)))) {
			perror("Could not allocate memory for transmission "
			"buffer");
			exit(2);
		};

		int opos = 0;
		for (int seg = 0, addcount = 0; seg < nfrm; seg++) { // Construct ech frame
			size_t count = seg < nfrm -1 || !(len % (FS-FSH))  ? FS : seg == 0 ? len + FSH : (len % (FS-FSH))+FSH;
			out[opos] = STX; opos++;			//STX
			int countpos = opos; opos += 3;
			out[opos] = '0'; opos++;			//ACK
			sprintf(out+opos,"%1i",seg % 10); opos++;	//Seq#
			out[opos] = seg < nfrm -1 ? '0' : '1'; opos++;	//LFrame
			for (int ipos = 0; ipos < count-FSH; ipos++) {
				char c = in[seg*(FS-FSH)+ipos];
				if (c == STX || c == ETX || c == DLE) {
					out[opos++] = DLE; addcount++;
				}
				out[opos++] = c;
			}
			
			// Now put the real count in
			char c = out[countpos+3];
			sprintf(out+countpos,"%03li", count+addcount);	//Count
			out[countpos+3] = c;
			
			sprintf(out+opos, "%04x", chksum(out+countpos, out+opos)); opos += 4; //Chksum
			out[opos] = ETX; opos++;		//ETX
			//debug("%zi, %i, %s", count, addcount, out);
			addcount = 0;
		}

	} else {		// Receive data
		ptrdiff_t off = 0, count; // Beginning of frame (STX)
		while(in[off] == STX){
			if ((count = verify_chksum(in+off)) < 0) exit(1);
			else off+= count;
		}
		
		char* destuff = calloc(len + 1, sizeof(char));
		int opos;
		char c;
		for (int ipos = opos = 0; ipos < len; ipos++) {
			if ((c = in[ipos]) == DLE) {
				if (in[ipos+1] == DLE) {
					destuff[opos] = c;
					opos++; ipos++;
				}
				continue;
			}
			else {
				destuff[opos] = c;
				opos++;
			}
		}
		
		len = strlen(destuff);
		
		int nfrm = len/FS + (len % FS ? 1 : 0);
		debug("%i frame(s) detected", nfrm);
		out = calloc(nfrm*FS, sizeof(char));
		for (int seg = 0; seg < nfrm; seg++) {
			size_t count = seg < nfrm -1 || !(len % FS) ? (MSS+SSH) : seg == 0 ? len - FSH : (len % FS) - FSH;
			strncpy(out+seg*(FS-FSH),destuff+seg*FS+7, count);	// Strip header, trailer
		}
		free(destuff);
	}

	free(in);

	debug("Current buffer '''%s'''", out);
	debug("*****************************");
	return out;
}
Esempio n. 3
0
/**
 * get_packet()
 * ------------
 * a wrapper function for the pkt_card_* interface, returning the
 * packet information about packet size, mac, network, transport layer
 * info, as well as error status.
 * returns: struct packet_info *
 **/
struct packet_info *get_packet (struct SETTINGS *mySettings)
{
  struct sockaddr_ll ifinfo; // interface info
  int wlan_ng_hdr_len = sizeof(wlan_ng_hdr_t);
  int pream_size = sizeof(struct airids_frame_info);
  int wlan_hdr_len = sizeof(wlan_hdr_t);
  int prism2_hdr_len = sizeof(prism2_hdr_t);
  int recvlen = 0;
  int ip_len = 0;
  int tcp_len = 0;
  int offset = 0;

  int total_hlen = 0;
  
  char proto[2];
  
  memset(msgbuf, 0, MAX_BUFFER_SIZE);
  memset(packet, 0, sizeof(struct packet_info));
	 
  recvlen = pkt_card_sock_read(mySettings->sniff_socket, msgbuf, MAX_BUFFER_SIZE, &ifinfo);
  if (DEBUG) fprintf(stderr,"total packet size: %d\n",recvlen);

  if (recvlen < 1){
    return (NULL);
  }

  if(mySettings->signal_support){
    packet->driver_proto = AIRONET_MOD;
    packet->packet_size = recvlen - pream_size;
    /* cast into airids_frame_info  */
    packet->driver_pkt = (struct airids_frame_info *)msgbuf; 
    
    if(packet->driver_pkt->fcs_error){
      packet->error_status = FCS_ERR;
      return (packet);
    }
    offset = pream_size;
  }
  else{
    packet->packet_size = recvlen;
    offset = 0;
  }

  if(mySettings->card_type == AIRONET){  
    packet->mac_proto = p802_11;
    packet->mac_pkt = (void *) (msgbuf + offset);
    /** simple test to make sure there are more higher protos **/
    if (packet->packet_size < (wlan_hdr_len + 3)){
      return (packet);
    }
    proto[0] = msgbuf[offset+wlan_hdr_len];
    proto[1] = msgbuf[offset+wlan_hdr_len+1];
  }  
  else if(mySettings->card_type == PRISMII){
    packet->mac_proto = hfa384x;
    packet->mac_pkt = (void *) (msgbuf + offset);
    /** simple test to make sure there are more higher protos **/
    if (packet->packet_size < (prism2_hdr_len + 3)){
      return (packet);
    }
    /** don't include driver crap in size byte analysis later **/
    packet->packet_size -= (sizeof(hfa384x_descript_t)+(sizeof(__u8)*7)); 
    proto[0] = msgbuf[offset+prism2_hdr_len];
    proto[1] = msgbuf[offset+prism2_hdr_len+1];
  }
  else if((mySettings->card_type==HERMES)||(mySettings->card_type==HOSTAP)||(mySettings->card_type==WLANNG)){
    packet->mac_proto = wlanngp2;
    packet->mac_pkt = (void *) (msgbuf + offset);
    /** simple test to make sure there are more higher protos **/
    if (packet->packet_size < (wlan_ng_hdr_len + 3)){
      return (packet);
    }
    /** don't include driver crap in size byte analysis later **/
    packet->packet_size -= wlan_ng_hdr_len;
    proto[0] = msgbuf[offset+wlan_ng_hdr_len+wlan_hdr_len];
    proto[1] = msgbuf[offset+wlan_ng_hdr_len+wlan_hdr_len+1];
  }    
  else{
    /** shouldn't ever get here... **/
    fprintf(stderr,"card type unsupported!\n");
    exit(1);
  }
  /** this doesn't work...  **/
  //  ifinfo.sll_protocol = htons(ifinfo.sll_protocol);

  /**
   * lets see if its IP...  sockaddr_ll only for 802.3! :(
   * +2 at the end because of protocol identifier between 802.11
   * protocol and ip header...
   **/

  /** see if its IP packet (there should be a better method...)**/
  if ((proto[0] == 8) && (proto[1] == 0)){
    if (mySettings->card_type == AIRONET){
      packet->net_pkt = (void *) (msgbuf + offset + wlan_hdr_len + 2);
      total_hlen += offset + wlan_hdr_len + 2;
    }
    else if (mySettings->card_type == PRISMII){
      packet->net_pkt = (void *) (msgbuf + offset + prism2_hdr_len + 2);
      total_hlen += offset + prism2_hdr_len + 2;
    }
    else if ((mySettings->card_type == HERMES)||(mySettings->card_type == HOSTAP)||(mySettings->card_type == WLANNG)){
      packet->net_pkt = (void *) (msgbuf + offset + wlan_ng_hdr_len + wlan_hdr_len + 2);
      total_hlen += offset + wlan_ng_hdr_len + wlan_hdr_len + 2;
    }
    else{
      fprintf(stderr, "major internal error!");
      exit(1);
    }
       
    /** if its version 4, then we're okay **/
    if ( ((struct iphdr *)packet->net_pkt)->version == 4){
      packet->net_proto = IPv4;
      /** if iphdr is invalid, then lets just ignore the entire packet **/
      if (!verify_chksum((struct iphdr *)packet->net_pkt)){
	packet->error_status = IPCHKSUM_ERR;
	return (packet);    
      }

      /** grab the higer level protocols **/
      ip_len = ((struct iphdr *)packet->net_pkt)->ihl * 4;
      packet->trans_pkt = (void *) (packet->net_pkt + ip_len);
      total_hlen += ip_len;
      if ((total_hlen > MAX_BUFFER_SIZE)||(total_hlen > recvlen)){
	packet->error_status = IPHDRLEN_ERR;
	return (packet);
      }
      
      /** parse higher protocols here... **/
      if (((struct iphdr *)packet->net_pkt)->protocol == IPPROTO_TCP){
	packet->trans_proto = TCP;
	tcp_len = ((struct tcphdr *)packet->trans_pkt)->doff * 4;
	packet->data = (void *) (packet->trans_pkt + tcp_len);
	total_hlen += tcp_len;
	packet->data_size = recvlen - total_hlen;
      }
      else if (((struct iphdr *)packet->net_pkt)->protocol == IPPROTO_UDP){
	packet->trans_proto = UDP;	
      }
      else if (((struct iphdr *)packet->net_pkt)->protocol == IPPROTO_ICMP){
	packet->trans_proto = ICMP;
      }
      else{
	packet->trans_proto = OTHER;
      }
    }
    else if ( ((struct iphdr *)packet->net_pkt)->version == 6){
      packet->net_proto = IPv6;
    }
    else{
      packet->net_proto = OTHER;
    }
  }
  else{
    packet->net_proto = OTHER;
  }
  return(packet);
}