Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.21-rc2 144 lines 3.2 kB view raw
1/* 2 * Copyright (C) 2002 Jeff Dike <jdike@karaya.com> 3 * Licensed under the GPL. 4 */ 5 6#include <unistd.h> 7#include <stdlib.h> 8#include <string.h> 9#include <errno.h> 10#include <pcap.h> 11#include <asm/types.h> 12#include "net_user.h" 13#include "pcap_user.h" 14#include "user.h" 15#include "um_malloc.h" 16 17#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) 18 19#define PCAP_FD(p) (*(int *)(p)) 20 21static void pcap_user_init(void *data, void *dev) 22{ 23 struct pcap_data *pri = data; 24 pcap_t *p; 25 char errors[PCAP_ERRBUF_SIZE]; 26 27 p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors); 28 if(p == NULL){ 29 printk("pcap_user_init : pcap_open_live failed - '%s'\n", 30 errors); 31 return; 32 } 33 34 pri->dev = dev; 35 pri->pcap = p; 36} 37 38static int pcap_open(void *data) 39{ 40 struct pcap_data *pri = data; 41 __u32 netmask; 42 int err; 43 44 if(pri->pcap == NULL) 45 return(-ENODEV); 46 47 if(pri->filter != NULL){ 48 err = dev_netmask(pri->dev, &netmask); 49 if(err < 0){ 50 printk("pcap_open : dev_netmask failed\n"); 51 return(-EIO); 52 } 53 54 pri->compiled = um_kmalloc(sizeof(struct bpf_program)); 55 if(pri->compiled == NULL){ 56 printk("pcap_open : kmalloc failed\n"); 57 return(-ENOMEM); 58 } 59 60 err = pcap_compile(pri->pcap, 61 (struct bpf_program *) pri->compiled, 62 pri->filter, pri->optimize, netmask); 63 if(err < 0){ 64 printk("pcap_open : pcap_compile failed - '%s'\n", 65 pcap_geterr(pri->pcap)); 66 return(-EIO); 67 } 68 69 err = pcap_setfilter(pri->pcap, pri->compiled); 70 if(err < 0){ 71 printk("pcap_open : pcap_setfilter failed - '%s'\n", 72 pcap_geterr(pri->pcap)); 73 return(-EIO); 74 } 75 } 76 77 return(PCAP_FD(pri->pcap)); 78} 79 80static void pcap_remove(void *data) 81{ 82 struct pcap_data *pri = data; 83 84 if(pri->compiled != NULL) 85 pcap_freecode(pri->compiled); 86 87 pcap_close(pri->pcap); 88} 89 90struct pcap_handler_data { 91 char *buffer; 92 int len; 93}; 94 95static void handler(u_char *data, const struct pcap_pkthdr *header, 96 const u_char *packet) 97{ 98 int len; 99 100 struct pcap_handler_data *hdata = (struct pcap_handler_data *) data; 101 102 len = hdata->len < header->caplen ? hdata->len : header->caplen; 103 memcpy(hdata->buffer, packet, len); 104 hdata->len = len; 105} 106 107int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri) 108{ 109 struct pcap_handler_data hdata = ((struct pcap_handler_data) 110 { .buffer = buffer, 111 .len = len }); 112 int n; 113 114 n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata); 115 if(n < 0){ 116 printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap)); 117 return(-EIO); 118 } 119 else if(n == 0) 120 return(0); 121 return(hdata.len); 122} 123 124const struct net_user_info pcap_user_info = { 125 .init = pcap_user_init, 126 .open = pcap_open, 127 .close = NULL, 128 .remove = pcap_remove, 129 .set_mtu = NULL, 130 .add_address = NULL, 131 .delete_address = NULL, 132 .max_packet = MAX_PACKET - ETH_HEADER_OTHER 133}; 134 135/* 136 * Overrides for Emacs so that we follow Linus's tabbing style. 137 * Emacs will notice this stuff at the end of the file and automatically 138 * adjust the settings for this buffer only. This must remain at the end 139 * of the file. 140 * --------------------------------------------------------------------------- 141 * Local variables: 142 * c-file-style: "linux" 143 * End: 144 */