Выясняются новые подробности. Нет необходимости доступаться до 802.11 MPDU уровня. На самом деле 802.11 фреймы, на выходе из mac802.11 конвернируются в 802.3 фреймы. И вот именно их и надо шифровать. Для этого, в моем модуле надо уметь подцепиться к заданному сетевому интерфейсу и перехватывать все входящие и исходящие 802.3 фреймы. Задача - зашифровать(AES) содержимое фрейма который пришел из сетевого стека перед его выдачей в сеть. И наоборот, полученный из сети фрейм надо расшифровать и отправить вверх в сетевой стек.
Для реализации такого подхода можно использовать следующее:
1) Для ТХ фреймов (исходящих из wlan0) нечто следующее:
static struct net_device_ops *orig_dataif_ops;
static struct net_device_ops new_dataif_ops;
struct net_device *slave;
netdev_tx_t my_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
return orig_start_xmit(skb, dev);
}
int __init crypto_init(void)
{
...
...
/* Запоминаем net_device_ops структуру зарегистрированную для wlan0 и заменяем ее на новую, */
/* с подмененной ndo_start_xmit колбека на наш my_start_xmit()*/
slave = __dev_get_by_name(&init_net, slave_name);
if (slave && slave->netdev_ops)
{
/* save original net_device options*/
orig_dataif_ops = slave->netdev_ops;
new_dataif_ops = *slave->netdev_ops;
/* update ndo_start_xmit */
orig_start_xmit = slave->netdev_ops->ndo_start_xmit;
/* change net_device to new ones */
new_dataif_ops.ndo_start_xmit = my_start_xmit;
slave->netdev_ops = &new_dataif_ops;
}
}
2) Для RX фреймов (входящих в wlan0) используем netdev_rx_handler_register:
struct net_device *slave;
rx_handler_result_t handle_frame(struct sk_buff **pskb)
{
struct sk_buff *skb = *pskb;
/* printk(KERN_WARNING "%s: Address src=%pM dst=%pM len=%d data_len=%d mac_len=%d\n", skb->dev->name, eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, skb->len, skb->data_len, skb->mac_len); */
#if 1
/* We need to remove scb from slave device and push it to crypto device */
if (crypto_dev)
{
struct crypto_priv *priv = netdev_priv(crypto_dev);
priv->priv_stats.rx_packets++;
priv->priv_stats.rx_bytes += skb->len;
printk("injecting frame from %s to %s\n", skb->dev->name, crypto_dev->name);
skb->dev = crypto_dev;
return RX_HANDLER_ANOTHER;
}
#endif
return RX_HANDLER_PASS;
}
int __init crypto_init(void)
{
...
...
slave = __dev_get_by_name(&init_net, slave_name);
if (!slave)
return -ENODEV;
netdev_rx_handler_register(slave, handle_frame, NULL);
...
...
}
Note: тут еще проблемка. netdev_rx_handler_register() относительно новый хук и появился он в 2.6.36, а мне надо чтобы модуль был также совместим с 2.6.35. Наверняка там есть какой-то аналог этой функции - надо копать