pcap_user.c 3.1 KB

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