^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <pcap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <asm/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <net_user.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "pcap_user.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <um_malloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define PCAP_FD(p) (*(int *)(p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) static int pcap_user_init(void *data, void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct pcap_data *pri = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) pcap_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) char errors[PCAP_ERRBUF_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) p = pcap_open_live(pri->host_if, ETH_MAX_PACKET + ETH_HEADER_OTHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) pri->promisc, 0, errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) if (p == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) "'%s'\n", errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) pri->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) pri->pcap = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static int pcap_user_open(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct pcap_data *pri = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) __u32 netmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (pri->pcap == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (pri->filter != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) err = dev_netmask(pri->dev, &netmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) printk(UM_KERN_ERR "pcap_user_open : dev_netmask failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) pri->compiled = uml_kmalloc(sizeof(struct bpf_program),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) UM_GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (pri->compiled == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) printk(UM_KERN_ERR "pcap_user_open : kmalloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) err = pcap_compile(pri->pcap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) (struct bpf_program *) pri->compiled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) pri->filter, pri->optimize, netmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) printk(UM_KERN_ERR "pcap_user_open : pcap_compile failed - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) "'%s'\n", pcap_geterr(pri->pcap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) err = pcap_setfilter(pri->pcap, pri->compiled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) printk(UM_KERN_ERR "pcap_user_open : pcap_setfilter "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) "failed - '%s'\n", pcap_geterr(pri->pcap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return PCAP_FD(pri->pcap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) kfree(pri->compiled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static void pcap_remove(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct pcap_data *pri = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (pri->compiled != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) pcap_freecode(pri->compiled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (pri->pcap != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) pcap_close(pri->pcap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct pcap_handler_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) char *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static void handler(u_char *data, const struct pcap_pkthdr *header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) const u_char *packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct pcap_handler_data *hdata = (struct pcap_handler_data *) data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) len = hdata->len < header->caplen ? hdata->len : header->caplen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) memcpy(hdata->buffer, packet, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) hdata->len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct pcap_handler_data hdata = ((struct pcap_handler_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) { .buffer = buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) .len = len });
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (n < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) printk(UM_KERN_ERR "pcap_dispatch failed - %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) pcap_geterr(pri->pcap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) else if (n == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return hdata.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) const struct net_user_info pcap_user_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .init = pcap_user_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .open = pcap_user_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .close = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .remove = pcap_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .add_address = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .delete_address = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .mtu = ETH_MAX_PACKET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) };