Skip to content

Instantly share code, notes, and snippets.

@chrizchow
Last active December 23, 2023 13:24
Show Gist options
  • Save chrizchow/af3e987d2ccf85dc736b71b24d82d331 to your computer and use it in GitHub Desktop.
Save chrizchow/af3e987d2ccf85dc736b71b24d82d331 to your computer and use it in GitHub Desktop.
Linux Minimal ioctl Network Device Example
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/netdevice.h>
static int chriz_open(struct net_device *dev)
{
printk(KERN_INFO "chriz open...\n");
netif_start_queue(dev);
return 0;
}
static int chriz_release(struct net_device *dev)
{
printk(KERN_INFO "chriz release...\n");
netif_stop_queue(dev);
return 0;
}
static int chriz_xmit(struct sk_buff *skb, struct net_device *dev)
{
printk(KERN_INFO "chriz xmit...\n");
dev_kfree_skb(skb);
return 0;
}
static int chriz_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
printk(KERN_INFO "chriz ioctl: command: %x\n", cmd);
return 0;
}
// ---------------------------------------------------------------
static const struct net_device_ops chriz_netdev_ops = {
.ndo_open = chriz_open,
.ndo_stop = chriz_release,
.ndo_start_xmit = chriz_xmit,
.ndo_do_ioctl = chriz_ioctl,
};
void chriz_init(struct net_device *dev)
{
ether_setup(dev);
dev->netdev_ops = &chriz_netdev_ops;
printk(KERN_INFO "chriz device initialized!\n");
}
// ---------------------------------------------------------------
struct net_device *chriz_dev = NULL;
static int __init chriz_init_module(void)
{
printk(KERN_INFO "chriz init module...\n");
chriz_dev = alloc_netdev(0, "chriz", NET_NAME_UNKNOWN, chriz_init);
if (register_netdev(chriz_dev)) {
printk("chriz: device init error\n");
return 1;
}
return 0;
}
static void __exit chriz_exit_module(void)
{
unregister_netdev(chriz_dev);
printk(KERN_INFO "chriz exit module... Goodbye!\n");
}
module_init(chriz_init_module);
module_exit(chriz_exit_module);
#include <net/if.h>
#include <net/if_arp.h>
#include <fcntl.h> /* open */
#include <unistd.h> /* exit */
#include <sys/ioctl.h> /* ioctl */
#include <sys/socket.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <linux/wireless.h> // struct iwreq
#define SIOC_CHRIZ SIOCDEVPRIVATE+1
char interface_name[16] = "chriz";
int main() {
int sock = 0;
int ret = 0;
struct iwreq iwr;
struct ifreq ifr;
printf("Start...\n");
// init net socket
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
printf("socket error\n");
return 1;
}
// fill in interface name
memset(&iwr, 0, sizeof(iwr)); // for wireless
strcpy(iwr.ifr_name, interface_name);
memset(&ifr, 0, sizeof(ifr)); // for ethernet
strcpy(ifr.ifr_name, interface_name);
// do ioctl
ret = ioctl(sock, SIOC_CHRIZ, &ifr);
if (ret < 0) {
printf("ioctl error %d, err: %s\n", ret, strerror(errno));
}
// finished
printf("Finished...\n");
close(sock);
return 0;
}
KDIR := /home/chriz/repositories/WSL2-Linux-Kernel/
obj-m += chriz_ioctl_kernel.o
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
gcc -o chriz_ioctl_user chriz_ioctl_user.c
clean:
rm -rf *.o *.ko *.mod.* *.cmd .module* modules* Module* .*.cmd .tmp*
make -C ${KDIR} M=$(PWD) clean
rm -f chriz_ioctl_user
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment