-
-
Save sora/331f2f98d1ac18164fe4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static const unsigned char pkt[] = { | |
// ethernet header | |
0xa0, 0x36, 0x9f, 0x18, 0x50, 0xe5, | |
0x00, 0x1c, 0x7e, 0x6a, 0xba, 0xd1, | |
0x08, 0x00, | |
// IPv4 header | |
0x45, 0x00, 0x00, 0x4e, | |
0x00, 0x00, 0x40, 0x00, | |
0x40, 0x11, 0xfb, 0x32, | |
0x0a, 0x00, 0x00, 0x6e, | |
0x0a, 0x00, 0x00, 0x02, | |
// payload | |
0x04, 0x04, 0x00, 0x89, 0x00, 0x3a, 0x38, 0x03, | |
0x10, 0xfd, 0x01, 0x10, 0x00, 0x01, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x20, 0x46, 0x45, 0x45, | |
0x4e, 0x45, 0x42, 0x46, 0x45, 0x46, 0x44, 0x46, | |
0x46, 0x46, 0x4a, 0x45, 0x42, 0x43, 0x4e, 0x45, | |
0x49, 0x46, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, | |
0x41, 0x43, 0x41, 0x43, 0x41, 0x00, 0x00, 0x20, | |
0x00, 0x01 | |
}; | |
static const unsigned short pktlen = sizeof(pkt) / sizeof(pkt[0]); | |
static int packet_direct_xmit(struct sk_buff *skb) | |
{ | |
struct net_device *dev = skb->dev; | |
const struct net_device_ops *ops = dev->netdev_ops; | |
netdev_features_t features; | |
struct netdev_queue *txq; | |
int ret = NETDEV_TX_BUSY; | |
u16 queue_map; | |
if (unlikely(!netif_running(dev) || !netif_carrier_ok(dev))) | |
goto drop; | |
features = netif_skb_features(skb); | |
if (skb_needs_linearize(skb, features) && __skb_linearize(skb)) | |
goto drop; | |
queue_map = skb_get_queue_mapping(skb); | |
txq = netdev_get_tx_queue(dev, queue_map); | |
local_bh_disable(); | |
HARD_TX_LOCK(dev, txq, smp_processor_id()); | |
if (!netif_xmit_frozen_or_drv_stopped(txq)) { | |
ret = ops->ndo_start_xmit(skb, dev); | |
if (ret == NETDEV_TX_OK) | |
txq_trans_update(txq); | |
} | |
HARD_TX_UNLOCK(dev, txq); | |
local_bh_enable(); | |
if (!dev_xmit_complete(ret)) | |
kfree_skb(skb); | |
return ret; | |
drop: | |
atomic_long_inc(&dev->tx_dropped); | |
kfree_skb(skb); | |
return NET_XMIT_DROP; | |
} | |
static ssize_t tx_write(struct file *filp, const char __user *buf, | |
size_t count, loff_t *ppos) | |
{ | |
int ret; | |
struct sk_buff *tx_skb = NULL; | |
pr_info( "pktlen: %d\n", pktlen ); | |
tx_skb = netdev_alloc_skb(device, pktlen); | |
if (likely(tx_skb)) { | |
tx_skb->dev = device; | |
skb_put(tx_skb, pktlen); | |
memcpy(tx_skb->data, pkt, pktlen); | |
ret = packet_direct_xmit(tx_skb); | |
if (ret) { | |
pr_info( "fail packet_direct_xmit=%d\n", ret ); | |
} | |
} | |
return count; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment