/** * @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; }