/* This function checks if a frame is IPv4 ARP or IPv6 Neighbour advertisement * frame. If frame has both source and destination mac address as same, this * function drops such gratuitous frames.
*/ staticbool
mwifiex_discard_gratuitous_arp(struct mwifiex_private *priv, struct sk_buff *skb)
{ conststruct mwifiex_arp_eth_header *arp; struct ethhdr *eth; struct ipv6hdr *ipv6; struct icmp6hdr *icmpv6;
eth = (struct ethhdr *)skb->data; switch (ntohs(eth->h_proto)) { case ETH_P_ARP:
arp = (void *)(skb->data + sizeof(struct ethhdr)); if (arp->hdr.ar_op == htons(ARPOP_REPLY) ||
arp->hdr.ar_op == htons(ARPOP_REQUEST)) { if (!memcmp(arp->ar_sip, arp->ar_tip, 4)) returntrue;
} break; case ETH_P_IPV6:
ipv6 = (void *)(skb->data + sizeof(struct ethhdr));
icmpv6 = (void *)(skb->data + sizeof(struct ethhdr) + sizeof(struct ipv6hdr)); if (NDISC_NEIGHBOUR_ADVERTISEMENT == icmpv6->icmp6_type) { if (!memcmp(&ipv6->saddr, &ipv6->daddr, sizeof(struct in6_addr))) returntrue;
} break; default: break;
}
returnfalse;
}
/* * This function processes the received packet and forwards it * to kernel/upper layer. * * This function parses through the received packet and determines * if it is a debug packet or normal packet. * * For non-debug packets, the function chops off unnecessary leading * header bytes, reconstructs the packet as an ethernet frame or * 802.2/llc/snap frame as required, and sends it to kernel/upper layer. * * The completion callback is called after processing in complete.
*/ int mwifiex_process_rx_packet(struct mwifiex_private *priv, struct sk_buff *skb)
{ int ret; struct rx_packet_hdr *rx_pkt_hdr; struct rxpd *local_rx_pd; int hdr_chop; struct ethhdr *eth;
u16 rx_pkt_off, rx_pkt_len;
u8 *offset;
u8 adj_rx_rate = 0;
if (sizeof(*rx_pkt_hdr) + rx_pkt_off <= skb->len &&
((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header, sizeof(bridge_tunnel_header))) ||
(!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header, sizeof(rfc1042_header)) &&
ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP &&
ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX))) { /* * Replace the 803 header and rfc1042 header (llc/snap) with an * EthernetII header, keep the src/dst and snap_type * (ethertype). * The firmware only passes up SNAP frames converting * all RX Data from 802.11 to 802.2/LLC/SNAP frames. * To create the Ethernet II, just move the src, dst address * right before the snap_type.
*/
eth = (struct ethhdr *)
((u8 *) &rx_pkt_hdr->eth803_hdr
+ sizeof(rx_pkt_hdr->eth803_hdr) + sizeof(rx_pkt_hdr->rfc1042_hdr)
- sizeof(rx_pkt_hdr->eth803_hdr.h_dest)
- sizeof(rx_pkt_hdr->eth803_hdr.h_source)
- sizeof(rx_pkt_hdr->rfc1042_hdr.snap_type));
/* Chop off the rxpd + the excess memory from the 802.2/llc/snap
header that was removed. */
hdr_chop = (u8 *) eth - (u8 *) local_rx_pd;
} else { /* Chop off the rxpd */
hdr_chop = (u8 *) &rx_pkt_hdr->eth803_hdr -
(u8 *) local_rx_pd;
}
/* Chop off the leading header bytes so the it points to the start of
either the reconstructed EthII frame or the 802.2/llc/snap frame */
skb_pull(skb, hdr_chop);
ret = mwifiex_recv_packet(priv, skb); if (ret == -1)
mwifiex_dbg(priv->adapter, ERROR, "recv packet failed\n");
return ret;
}
/* * This function processes the received buffer. * * The function looks into the RxPD and performs sanity tests on the * received buffer to ensure its a valid packet, before processing it * further. If the packet is determined to be aggregated, it is * de-aggregated accordingly. Non-unicast packets are sent directly to * the kernel/upper layers. Unicast packets are handed over to the * Rx reordering routine if 11n is enabled. * * The completion callback is called after processing in complete.
*/ int mwifiex_process_sta_rx_packet(struct mwifiex_private *priv, struct sk_buff *skb)
{ struct mwifiex_adapter *adapter = priv->adapter; int ret = 0; struct rxpd *local_rx_pd; struct rx_packet_hdr *rx_pkt_hdr;
u8 ta[ETH_ALEN];
u16 rx_pkt_type, rx_pkt_offset, rx_pkt_length, seq_num; struct mwifiex_sta_node *sta_ptr;
if (rx_pkt_type == PKT_TYPE_MGMT) {
ret = mwifiex_process_mgmt_packet(priv, skb); if (ret)
mwifiex_dbg(adapter, DATA, "Rx of mgmt packet failed");
dev_kfree_skb_any(skb); return ret;
}
/* * If the packet is not an unicast packet then send the packet * directly to os. Don't pass thru rx reordering
*/ if ((!IS_11N_ENABLED(priv) &&
!(ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
!(local_rx_pd->flags & MWIFIEX_RXPD_FLAGS_TDLS_PACKET))) ||
!ether_addr_equal_unaligned(priv->curr_addr, rx_pkt_hdr->eth803_hdr.h_dest)) {
mwifiex_process_rx_packet(priv, skb); return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.