Example #1
0
void read_tap(struct params *p)
{
	char buf[4096];
	char *ptr;
	int len = sizeof(buf);
	int offset;
	char src[6], dst[6];
	struct ieee80211_frame *wh;
	int rd;

	ptr = buf;
	offset = sizeof(struct ieee80211_frame) + 8 - 14;
	if (p->wep_len)
		offset += 4;

	ptr += offset;
	len -= offset;

	/* read packet */
	memset(buf, 0, sizeof(buf));
	rd = read(p->tap, ptr, len);
	if (rd == -1)
		err(1, "read()");

	/* 802.11 header */
	wh = (struct ieee80211_frame*) buf;
	memcpy(dst, ptr, sizeof(dst));
	memcpy(src, ptr+6, sizeof(src));
	fill_basic(wh, p);
	memcpy(wh->i_addr3, src, sizeof(wh->i_addr3));
	memcpy(wh->i_addr1, dst, sizeof(wh->i_addr1));
	wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
	wh->i_fc[1] |= IEEE80211_FC1_DIR_FROMDS;
	if (p->wep_len)
		wh->i_fc[1] |= IEEE80211_FC1_PROTECTED;

	/* LLC & SNAP */
	ptr = (char*) (wh+1);
	if (p->wep_len)
		ptr += 4;
	*ptr++ = 0xAA;
	*ptr++ = 0xAA;
	*ptr++ = 0x03;
	*ptr++ = 0x00;
	*ptr++ = 0x00;
	*ptr++ = 0x00;
	/* ether type overlaps w00t */

	rd += offset;

	/* WEP */
	if (p->wep_len) {
		ptr = (char*) (wh+1);
		memcpy(ptr, &p->wep_iv, 3);
		ptr[3] = 0;
		p->wep_iv++;

		wep_encrypt(wh, rd, p->wep_key, p->wep_len);
		rd += 4; /* ICV */
	}

	send_frame(p, wh, rd);
}
Example #2
0
/*----------------------------------------------------------------
* p80211pb_ether_to_80211
*
* Uses the contents of the ether frame and the etherconv setting
* to build the elements of the 802.11 frame.
*
* We don't actually set
* up the frame header here.  That's the MAC's job.  We're only handling
* conversion of DIXII or 802.3+LLC frames to something that works
* with 802.11.
*
* Note -- 802.11 header is NOT part of the skb.  Likewise, the 802.11
*         FCS is also not present and will need to be added elsewhere.
*
* Arguments:
*	ethconv		Conversion type to perform
*	skb		skbuff containing the ether frame
*       p80211_hdr      802.11 header
*
* Returns:
*	0 on success, non-zero otherwise
*
* Call context:
*	May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv,
			struct sk_buff *skb, union p80211_hdr *p80211_hdr,
			struct p80211_metawep *p80211_wep)
{

	u16 fc;
	u16 proto;
	struct wlan_ethhdr e_hdr;
	struct wlan_llc *e_llc;
	struct wlan_snap *e_snap;
	int foo;

	memcpy(&e_hdr, skb->data, sizeof(e_hdr));

	if (skb->len <= 0) {
		pr_debug("zero-length skb!\n");
		return 1;
	}

	if (ethconv == WLAN_ETHCONV_ENCAP) {	/* simplest case */
		pr_debug("ENCAP len: %d\n", skb->len);
		/* here, we don't care what kind of ether frm. Just stick it */
		/*  in the 80211 payload */
		/* which is to say, leave the skb alone. */
	} else {
		/* step 1: classify ether frame, DIX or 802.3? */
		proto = ntohs(e_hdr.type);
		if (proto <= 1500) {
			pr_debug("802.3 len: %d\n", skb->len);
			/* codes <= 1500 reserved for 802.3 lengths */
			/* it's 802.3, pass ether payload unchanged,  */

			/* trim off ethernet header */
			skb_pull(skb, WLAN_ETHHDR_LEN);

			/*   leave off any PAD octets.  */
			skb_trim(skb, proto);
		} else {
			pr_debug("DIXII len: %d\n", skb->len);
			/* it's DIXII, time for some conversion */

			/* trim off ethernet header */
			skb_pull(skb, WLAN_ETHHDR_LEN);

			/* tack on SNAP */
			e_snap =
			    (struct wlan_snap *) skb_push(skb,
				sizeof(struct wlan_snap));
			e_snap->type = htons(proto);
			if (ethconv == WLAN_ETHCONV_8021h
			    && p80211_stt_findproto(proto)) {
				memcpy(e_snap->oui, oui_8021h,
				       WLAN_IEEE_OUI_LEN);
			} else {
				memcpy(e_snap->oui, oui_rfc1042,
				       WLAN_IEEE_OUI_LEN);
			}

			/* tack on llc */
			e_llc =
			    (struct wlan_llc *) skb_push(skb,
				sizeof(struct wlan_llc));
			e_llc->dsap = 0xAA;	/* SNAP, see IEEE 802 */
			e_llc->ssap = 0xAA;
			e_llc->ctl = 0x03;

		}
	}

	/* Set up the 802.11 header */
	/* It's a data frame */
	fc = cpu_to_le16(WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) |
			 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY));

	switch (wlandev->macmode) {
	case WLAN_MACMODE_IBSS_STA:
		memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, ETH_ALEN);
		memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, ETH_ALEN);
		memcpy(p80211_hdr->a3.a3, wlandev->bssid, ETH_ALEN);
		break;
	case WLAN_MACMODE_ESS_STA:
		fc |= cpu_to_le16(WLAN_SET_FC_TODS(1));
		memcpy(p80211_hdr->a3.a1, wlandev->bssid, ETH_ALEN);
		memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, ETH_ALEN);
		memcpy(p80211_hdr->a3.a3, &e_hdr.daddr, ETH_ALEN);
		break;
	case WLAN_MACMODE_ESS_AP:
		fc |= cpu_to_le16(WLAN_SET_FC_FROMDS(1));
		memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, ETH_ALEN);
		memcpy(p80211_hdr->a3.a2, wlandev->bssid, ETH_ALEN);
		memcpy(p80211_hdr->a3.a3, &e_hdr.saddr, ETH_ALEN);
		break;
	default:
//		printk(KERN_ERR
;
		return 1;
		break;
	}

	p80211_wep->data = NULL;

	if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
	    && (wlandev->hostwep & HOSTWEP_ENCRYPT)) {
		/* XXXX need to pick keynum other than default? */

		p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC);
		foo = wep_encrypt(wlandev, skb->data, p80211_wep->data,
				  skb->len,
				  (wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK),
				  p80211_wep->iv, p80211_wep->icv);
		if (foo) {
//			printk(KERN_WARNING
//			       "Host en-WEP failed, dropping frame (%d).\n",
;
			return 2;
		}
		fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1));
	}

	/*      skb->nh.raw = skb->data; */

	p80211_hdr->a3.fc = fc;
	p80211_hdr->a3.dur = 0;
	p80211_hdr->a3.seq = 0;

	return 0;
}
Example #3
0
/**
 * Function to inject TCP packets to the wireless interface.  Requires headers
 * from a TO_DS packet for use in crafting the FROM_DS response.
 */
void inject_tcp(airpwn_ctx *ctx,
								ieee80211_hdr *w_hdr,
								struct iphdr *ip_hdr,
								struct tcphdr *tcp_hdr,
								uint8_t *wepkey,
								uint32_t keylen,
								char *content,
								uint32_t contentlen,
								uint8_t tcpflags,
								uint32_t *seqnum)
{

  // libnet wants the data in host-byte-order
  u_int ack = ntohl(tcp_hdr->seq) + 
    ( ntohs(ip_hdr->tot_len) - ip_hdr->ihl * 4 - tcp_hdr->doff * 4 );
  
  ctx->tcp_t = libnet_build_tcp(
    ntohs(tcp_hdr->dest), // source port
    ntohs(tcp_hdr->source), // dest port
    *seqnum, // sequence number
    ack, // ack number
    tcpflags, // flags
    0xffff, // window size
    0, // checksum
    0, // urg ptr
    20 + contentlen, // total length of the TCP packet
    (uint8_t*)content, // response
    contentlen, // response_length
    ctx->lnet, // libnet_t pointer
    ctx->tcp_t // ptag
  );

  if(ctx->tcp_t == -1){
    printf("libnet_build_tcp returns error: %s\n", libnet_geterror(ctx->lnet));
    return;
  }

  ctx->ip_t = libnet_build_ipv4(
    40 + contentlen, // length
    0, // TOS bits
    1, // IPID (need to calculate)
    0, // fragmentation
    0xff, // TTL
    6, // protocol
    0, // checksum
    ip_hdr->daddr, // source address
    ip_hdr->saddr, // dest address
    NULL, // response
    0, // response length
    ctx->lnet, // libnet_t pointer
    ctx->ip_t // ptag
  );

  if(ctx->ip_t == -1){
    printf("libnet_build_ipv4 returns error: %s\n", libnet_geterror(ctx->lnet));
    return;
  }

  // copy the libnet packets to to a buffer to send raw..
  
  unsigned char packet_buff[0x10000];

  memcpy(packet_buff, w_hdr, IEEE80211_HDR_LEN);

  ieee80211_hdr *n_w_hdr = (ieee80211_hdr *)packet_buff;

  // set the FROM_DS flag and swap MAC addresses
  n_w_hdr->flags = IEEE80211_FROM_DS;
  if(wepkey)
    n_w_hdr->flags |= IEEE80211_WEP_FLAG;
  n_w_hdr->llc.type = LLC_TYPE_IP;

  uint8_t tmp_addr[6];
  memcpy(tmp_addr, n_w_hdr->addr1, 6);
  memcpy(n_w_hdr->addr1, n_w_hdr->addr2, 6);
  memcpy(n_w_hdr->addr2, tmp_addr, 6);
    
  u_int32_t packet_len;
  u_int8_t *lnet_packet_buf;
  
  // cull_packet will dump the packet (with correct checksums) into a
  // buffer for us to send via the raw socket
  if(libnet_adv_cull_packet(ctx->lnet, &lnet_packet_buf, &packet_len) == -1){
    printf("libnet_adv_cull_packet returns error: %s\n", 
			libnet_geterror(ctx->lnet));
    return;
  }

  memcpy(packet_buff + IEEE80211_HDR_LEN, lnet_packet_buf, packet_len);

  libnet_adv_free_packet(ctx->lnet, lnet_packet_buf);

  // total packet length
  int len = IEEE80211_HDR_LEN + 40 + contentlen;
  
  if(wepkey){
    uint8_t tmpbuf[0x10000];
    /* encryption starts after the 802.11 header, but the LLC header
     * gets encrypted. */
    memcpy(tmpbuf, packet_buff+IEEE80211_HDR_LEN_NO_LLC, 
			len-IEEE80211_HDR_LEN_NO_LLC);
    len = wep_encrypt(tmpbuf, packet_buff+IEEE80211_HDR_LEN_NO_LLC,
			len-IEEE80211_HDR_LEN_NO_LLC, wepkey, keylen);
    if(len <= 0){
      fprintf(stderr, "Error performing WEP encryption!\n");
      return;
    } else
      len += IEEE80211_HDR_LEN_NO_LLC;
  }

  /* Establish lorcon packet transmission structure */
  ctx->in_packet.packet = packet_buff;
  ctx->in_packet.plen = len;

  /* Send the packet */
  if (tx80211_txpacket(&ctx->inject_tx, &ctx->in_packet) < 0) {
    fprintf(stderr, "Unable to transmit packet.");
    perror("tx80211_txpacket");
    return;
  }

  *seqnum += contentlen;  //advance the sequence number
  
  printlog(ctx, 2, "wrote %d bytes to the wire(less)\n", len);
}