Exemple #1
0
/**
 *  @brief This function check and discard IPv4 and IPv6 gratuitous broadcast packets
 *
 *  @param prx_pkt     A pointer to RxPacketHdr_t structure of received packet
 *  @param pmadapter   A pointer to pmlan_adapter structure
 *  @return            TRUE if found such type of packets, FALSE not found
 */
static t_u8
discard_gratuitous_ARP_msg(RxPacketHdr_t * prx_pkt, pmlan_adapter pmadapter)
{
	t_u8 proto_ARP_type[] = { 0x08, 0x06 };
	t_u8 proto_ARP_type_v6[] = { 0x86, 0xDD };
	IPv4_ARP_t *parp_hdr;
	IPv6_Nadv_t *pNadv_hdr;
	t_u8 ret = MFALSE;

	/* IPV4 pkt check * A gratuitous ARP is an ARP packet * where the
	   source and destination IP are both set to * the IP of the machine
	   issuing the packet. */
	if (memcmp
	    (pmadapter, proto_ARP_type, &prx_pkt->eth803_hdr.h803_len,
	     sizeof(proto_ARP_type)) == 0) {
		parp_hdr = (IPv4_ARP_t *) (&prx_pkt->rfc1042_hdr);
		/* Graguitous ARP can be ARP request or ARP reply */
		if ((parp_hdr->op_code == mlan_htons(0x01)) ||
		    (parp_hdr->op_code == mlan_htons(0x02))) {
			if (memcmp
			    (pmadapter, parp_hdr->src_ip, parp_hdr->dst_ip,
			     4) == 0) {
				ret = MTRUE;
			}
		}
	}

	/* IPV6 pkt check * An unsolicited Neighbor Advertisement pkt is *
	   marked by a cleared Solicited Flag */
	if (memcmp
	    (pmadapter, proto_ARP_type_v6, &prx_pkt->eth803_hdr.h803_len,
	     sizeof(proto_ARP_type_v6)) == 0) {
		pNadv_hdr = (IPv6_Nadv_t *) (&prx_pkt->rfc1042_hdr);
		/* Check Nadv type: next header is ICMPv6 and icmp type is Nadv */
		if (pNadv_hdr->next_hdr == 0x3A && pNadv_hdr->icmp_type == 0x88) {
			if ((pNadv_hdr->flags & mlan_htonl(0x40000000)) == 0) {
				ret = MTRUE;
			}
		}
	}

	return ret;
}
/**
 *  @brief Aggregate individual packets into one AMSDU packet
 *
 *  @param pmadapter A pointer to mlan_adapter structure
 *  @param amsdu_buf A pointer to packet buffer
 *  @param data      A pointer to aggregated data packet being formed
 *  @param pkt_len   Length of current packet to aggregate
 *  @param pad       Pad
 *
 *  @return         Final packet size
 */
static int
wlan_11n_form_amsdu_pkt(pmlan_adapter pmadapter, t_u8 * amsdu_buf, t_u8 * data,
			int pkt_len, int *pad)
{
	int dt_offset, amsdu_buf_offset;
	Rfc1042Hdr_t snap = {
		0xaa,		/* LLC DSAP */
		0xaa,		/* LLC SSAP */
		0x03,		/* LLC CTRL */
		{0x00, 0x00, 0x00},	/* SNAP OUI */
		0x0000		/* SNAP type */
			/*
			 * This field will be overwritten
			 * later with ethertype
			 */
	};

	ENTER();

	memcpy(pmadapter, amsdu_buf, data, (MLAN_MAC_ADDR_LENGTH) * 2);
	dt_offset = amsdu_buf_offset = (MLAN_MAC_ADDR_LENGTH) * 2;

	snap.snap_type = *(t_u16 *) (data + dt_offset);
	dt_offset += sizeof(t_u16);
	*(t_u16 *) (amsdu_buf + amsdu_buf_offset) = mlan_htons(pkt_len +
							       LLC_SNAP_LEN -
							       ((2 *
								 MLAN_MAC_ADDR_LENGTH)
								+
								sizeof(t_u16)));
	amsdu_buf_offset += sizeof(t_u16);
	memcpy(pmadapter, amsdu_buf + amsdu_buf_offset, &snap, LLC_SNAP_LEN);
	amsdu_buf_offset += LLC_SNAP_LEN;

	memcpy(pmadapter, amsdu_buf + amsdu_buf_offset, data + dt_offset,
	       pkt_len - dt_offset);
	*pad = (((pkt_len + LLC_SNAP_LEN) & 3)) ? (4 -
						   (((pkt_len +
						      LLC_SNAP_LEN)) & 3)) : 0;

	LEAVE();
	return pkt_len + LLC_SNAP_LEN + *pad;
}