root/arch/um/drivers/pcap_user.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pcap_user_init
  2. pcap_open
  3. pcap_remove
  4. handler
  5. pcap_user_read

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

/* [<][>][^][v][top][bottom][index][help] */