Webserver+3d print

Dependents:   Nucleo

Committer:
Sergunb
Date:
Sat Feb 04 18:15:49 2017 +0000
Revision:
0:8918a71cdbe9
nothing else

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sergunb 0:8918a71cdbe9 1 /**
Sergunb 0:8918a71cdbe9 2 * @file pcap_driver.c
Sergunb 0:8918a71cdbe9 3 * @brief PCAP driver
Sergunb 0:8918a71cdbe9 4 *
Sergunb 0:8918a71cdbe9 5 * @section License
Sergunb 0:8918a71cdbe9 6 *
Sergunb 0:8918a71cdbe9 7 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
Sergunb 0:8918a71cdbe9 8 *
Sergunb 0:8918a71cdbe9 9 * This file is part of CycloneTCP Open.
Sergunb 0:8918a71cdbe9 10 *
Sergunb 0:8918a71cdbe9 11 * This program is free software; you can redistribute it and/or
Sergunb 0:8918a71cdbe9 12 * modify it under the terms of the GNU General Public License
Sergunb 0:8918a71cdbe9 13 * as published by the Free Software Foundation; either version 2
Sergunb 0:8918a71cdbe9 14 * of the License, or (at your option) any later version.
Sergunb 0:8918a71cdbe9 15 *
Sergunb 0:8918a71cdbe9 16 * This program is distributed in the hope that it will be useful,
Sergunb 0:8918a71cdbe9 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Sergunb 0:8918a71cdbe9 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Sergunb 0:8918a71cdbe9 19 * GNU General Public License for more details.
Sergunb 0:8918a71cdbe9 20 *
Sergunb 0:8918a71cdbe9 21 * You should have received a copy of the GNU General Public License
Sergunb 0:8918a71cdbe9 22 * along with this program; if not, write to the Free Software Foundation,
Sergunb 0:8918a71cdbe9 23 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Sergunb 0:8918a71cdbe9 24 *
Sergunb 0:8918a71cdbe9 25 * @author Oryx Embedded SARL (www.oryx-embedded.com)
Sergunb 0:8918a71cdbe9 26 * @version 1.7.6
Sergunb 0:8918a71cdbe9 27 **/
Sergunb 0:8918a71cdbe9 28
Sergunb 0:8918a71cdbe9 29 //Switch to the appropriate trace level
Sergunb 0:8918a71cdbe9 30 #define TRACE_LEVEL NIC_TRACE_LEVEL
Sergunb 0:8918a71cdbe9 31
Sergunb 0:8918a71cdbe9 32 //Dependencies
Sergunb 0:8918a71cdbe9 33 #include "core/net.h"
Sergunb 0:8918a71cdbe9 34 #include "drivers/pcap_driver.h"
Sergunb 0:8918a71cdbe9 35 #include "debug.h"
Sergunb 0:8918a71cdbe9 36
Sergunb 0:8918a71cdbe9 37 //Undefine conflicting definitions
Sergunb 0:8918a71cdbe9 38 #undef Socket
Sergunb 0:8918a71cdbe9 39 #undef htons
Sergunb 0:8918a71cdbe9 40 #undef htonl
Sergunb 0:8918a71cdbe9 41 #undef ntohs
Sergunb 0:8918a71cdbe9 42 #undef ntohl
Sergunb 0:8918a71cdbe9 43
Sergunb 0:8918a71cdbe9 44 //PCAP dependencies
Sergunb 0:8918a71cdbe9 45 #include <pcap.h>
Sergunb 0:8918a71cdbe9 46
Sergunb 0:8918a71cdbe9 47 //Undefine conflicting definitions
Sergunb 0:8918a71cdbe9 48 #undef interface
Sergunb 0:8918a71cdbe9 49
Sergunb 0:8918a71cdbe9 50
Sergunb 0:8918a71cdbe9 51 /**
Sergunb 0:8918a71cdbe9 52 * @brief Packet descriptor
Sergunb 0:8918a71cdbe9 53 **/
Sergunb 0:8918a71cdbe9 54
Sergunb 0:8918a71cdbe9 55 typedef struct
Sergunb 0:8918a71cdbe9 56 {
Sergunb 0:8918a71cdbe9 57 size_t length;
Sergunb 0:8918a71cdbe9 58 uint8_t data[PCAP_DRIVER_MAX_PACKET_SIZE];
Sergunb 0:8918a71cdbe9 59 } PcapDriverPacket;
Sergunb 0:8918a71cdbe9 60
Sergunb 0:8918a71cdbe9 61
Sergunb 0:8918a71cdbe9 62 /**
Sergunb 0:8918a71cdbe9 63 * @brief PCAP driver context
Sergunb 0:8918a71cdbe9 64 **/
Sergunb 0:8918a71cdbe9 65
Sergunb 0:8918a71cdbe9 66 typedef struct
Sergunb 0:8918a71cdbe9 67 {
Sergunb 0:8918a71cdbe9 68 pcap_t *handle;
Sergunb 0:8918a71cdbe9 69 uint_t writeIndex;
Sergunb 0:8918a71cdbe9 70 uint_t readIndex;
Sergunb 0:8918a71cdbe9 71 PcapDriverPacket queue[PCAP_DRIVER_QUEUE_SIZE];
Sergunb 0:8918a71cdbe9 72 } PcapDriverContext;
Sergunb 0:8918a71cdbe9 73
Sergunb 0:8918a71cdbe9 74
Sergunb 0:8918a71cdbe9 75 /**
Sergunb 0:8918a71cdbe9 76 * @brief PCAP driver
Sergunb 0:8918a71cdbe9 77 **/
Sergunb 0:8918a71cdbe9 78
Sergunb 0:8918a71cdbe9 79 const NicDriver pcapDriver =
Sergunb 0:8918a71cdbe9 80 {
Sergunb 0:8918a71cdbe9 81 NIC_TYPE_ETHERNET,
Sergunb 0:8918a71cdbe9 82 ETH_MTU,
Sergunb 0:8918a71cdbe9 83 pcapDriverInit,
Sergunb 0:8918a71cdbe9 84 pcapDriverTick,
Sergunb 0:8918a71cdbe9 85 pcapDriverEnableIrq,
Sergunb 0:8918a71cdbe9 86 pcapDriverDisableIrq,
Sergunb 0:8918a71cdbe9 87 pcapDriverEventHandler,
Sergunb 0:8918a71cdbe9 88 pcapDriverSendPacket,
Sergunb 0:8918a71cdbe9 89 pcapDriverSetMulticastFilter,
Sergunb 0:8918a71cdbe9 90 NULL,
Sergunb 0:8918a71cdbe9 91 NULL,
Sergunb 0:8918a71cdbe9 92 NULL,
Sergunb 0:8918a71cdbe9 93 TRUE,
Sergunb 0:8918a71cdbe9 94 TRUE,
Sergunb 0:8918a71cdbe9 95 TRUE,
Sergunb 0:8918a71cdbe9 96 TRUE
Sergunb 0:8918a71cdbe9 97 };
Sergunb 0:8918a71cdbe9 98
Sergunb 0:8918a71cdbe9 99
Sergunb 0:8918a71cdbe9 100 /**
Sergunb 0:8918a71cdbe9 101 * @brief PCAP driver initialization
Sergunb 0:8918a71cdbe9 102 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 103 * @return Error code
Sergunb 0:8918a71cdbe9 104 **/
Sergunb 0:8918a71cdbe9 105
Sergunb 0:8918a71cdbe9 106 error_t pcapDriverInit(NetInterface *interface)
Sergunb 0:8918a71cdbe9 107 {
Sergunb 0:8918a71cdbe9 108 int_t ret;
Sergunb 0:8918a71cdbe9 109 uint_t i;
Sergunb 0:8918a71cdbe9 110 uint_t j;
Sergunb 0:8918a71cdbe9 111 pcap_if_t *device;
Sergunb 0:8918a71cdbe9 112 pcap_if_t *deviceList;
Sergunb 0:8918a71cdbe9 113 struct bpf_program filerCode;
Sergunb 0:8918a71cdbe9 114 char_t filterExpr[256];
Sergunb 0:8918a71cdbe9 115 char_t errorBuffer[PCAP_ERRBUF_SIZE];
Sergunb 0:8918a71cdbe9 116 PcapDriverContext *context;
Sergunb 0:8918a71cdbe9 117 #if (NET_RTOS_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 118 OsTask *task;
Sergunb 0:8918a71cdbe9 119 #endif
Sergunb 0:8918a71cdbe9 120
Sergunb 0:8918a71cdbe9 121 //Debug message
Sergunb 0:8918a71cdbe9 122 TRACE_INFO("Initializing PCAP driver...\r\n");
Sergunb 0:8918a71cdbe9 123
Sergunb 0:8918a71cdbe9 124 //Allocate PCAP driver context
Sergunb 0:8918a71cdbe9 125 context = (PcapDriverContext *) malloc(sizeof(PcapDriverContext));
Sergunb 0:8918a71cdbe9 126
Sergunb 0:8918a71cdbe9 127 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 128 if(context == NULL)
Sergunb 0:8918a71cdbe9 129 {
Sergunb 0:8918a71cdbe9 130 //Debug message
Sergunb 0:8918a71cdbe9 131 printf("Failed to allocate context!\r\n");
Sergunb 0:8918a71cdbe9 132
Sergunb 0:8918a71cdbe9 133 //Report an error
Sergunb 0:8918a71cdbe9 134 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 135 }
Sergunb 0:8918a71cdbe9 136
Sergunb 0:8918a71cdbe9 137 //Attach the PCAP driver context to the network interface
Sergunb 0:8918a71cdbe9 138 *((PcapDriverContext **) interface->nicContext) = context;
Sergunb 0:8918a71cdbe9 139 //Clear PCAP driver context
Sergunb 0:8918a71cdbe9 140 memset(context, 0, sizeof(PcapDriverContext));
Sergunb 0:8918a71cdbe9 141
Sergunb 0:8918a71cdbe9 142 //Find all the devices
Sergunb 0:8918a71cdbe9 143 ret = pcap_findalldevs(&deviceList, errorBuffer);
Sergunb 0:8918a71cdbe9 144
Sergunb 0:8918a71cdbe9 145 //Any error to report?
Sergunb 0:8918a71cdbe9 146 if(ret != 0)
Sergunb 0:8918a71cdbe9 147 {
Sergunb 0:8918a71cdbe9 148 //Debug message
Sergunb 0:8918a71cdbe9 149 printf("Failed to list devices!\r\n");
Sergunb 0:8918a71cdbe9 150
Sergunb 0:8918a71cdbe9 151 //Clean up side effects
Sergunb 0:8918a71cdbe9 152 free(context);
Sergunb 0:8918a71cdbe9 153
Sergunb 0:8918a71cdbe9 154 //Report an error
Sergunb 0:8918a71cdbe9 155 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 156 }
Sergunb 0:8918a71cdbe9 157
Sergunb 0:8918a71cdbe9 158 //No network adapter found?
Sergunb 0:8918a71cdbe9 159 if(deviceList == NULL)
Sergunb 0:8918a71cdbe9 160 {
Sergunb 0:8918a71cdbe9 161 //Debug message
Sergunb 0:8918a71cdbe9 162 printf("No network adapter found!\r\n");
Sergunb 0:8918a71cdbe9 163
Sergunb 0:8918a71cdbe9 164 //Clean up side effects
Sergunb 0:8918a71cdbe9 165 free(context);
Sergunb 0:8918a71cdbe9 166
Sergunb 0:8918a71cdbe9 167 //Exit immediately
Sergunb 0:8918a71cdbe9 168 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 169 }
Sergunb 0:8918a71cdbe9 170
Sergunb 0:8918a71cdbe9 171 //Network adapter selection
Sergunb 0:8918a71cdbe9 172 while(1)
Sergunb 0:8918a71cdbe9 173 {
Sergunb 0:8918a71cdbe9 174 //Debug message
Sergunb 0:8918a71cdbe9 175 printf("Network adapters:\r\n");
Sergunb 0:8918a71cdbe9 176
Sergunb 0:8918a71cdbe9 177 //Point to the first device
Sergunb 0:8918a71cdbe9 178 device = deviceList;
Sergunb 0:8918a71cdbe9 179 i = 0;
Sergunb 0:8918a71cdbe9 180
Sergunb 0:8918a71cdbe9 181 //Loop through the list of devices
Sergunb 0:8918a71cdbe9 182 while(device != NULL)
Sergunb 0:8918a71cdbe9 183 {
Sergunb 0:8918a71cdbe9 184 //Index of the current network adapter
Sergunb 0:8918a71cdbe9 185 printf(" %-2u", i + 1);
Sergunb 0:8918a71cdbe9 186
Sergunb 0:8918a71cdbe9 187 #if !defined(_WIN32)
Sergunb 0:8918a71cdbe9 188 //Display the name of the device
Sergunb 0:8918a71cdbe9 189 if(device->name != NULL)
Sergunb 0:8918a71cdbe9 190 printf(" %-8s", device->name);
Sergunb 0:8918a71cdbe9 191 #endif
Sergunb 0:8918a71cdbe9 192 //Description of the device
Sergunb 0:8918a71cdbe9 193 if(device->description != NULL)
Sergunb 0:8918a71cdbe9 194 printf(" %s\r\n", device->description);
Sergunb 0:8918a71cdbe9 195 else
Sergunb 0:8918a71cdbe9 196 printf(" -\r\n");
Sergunb 0:8918a71cdbe9 197
Sergunb 0:8918a71cdbe9 198 //Next device
Sergunb 0:8918a71cdbe9 199 device = device->next;
Sergunb 0:8918a71cdbe9 200 i++;
Sergunb 0:8918a71cdbe9 201 }
Sergunb 0:8918a71cdbe9 202
Sergunb 0:8918a71cdbe9 203 //Display message
Sergunb 0:8918a71cdbe9 204 printf("Select network adapter for %s interface (1-%u):", interface->name, i);
Sergunb 0:8918a71cdbe9 205 //Get user choice
Sergunb 0:8918a71cdbe9 206 scanf("%d", &j);
Sergunb 0:8918a71cdbe9 207
Sergunb 0:8918a71cdbe9 208 //Valid selection?
Sergunb 0:8918a71cdbe9 209 if(j >= 1 && j <= i)
Sergunb 0:8918a71cdbe9 210 break;
Sergunb 0:8918a71cdbe9 211 }
Sergunb 0:8918a71cdbe9 212
Sergunb 0:8918a71cdbe9 213 //Point to the first device
Sergunb 0:8918a71cdbe9 214 device = deviceList;
Sergunb 0:8918a71cdbe9 215
Sergunb 0:8918a71cdbe9 216 //Point to the desired network adapter
Sergunb 0:8918a71cdbe9 217 for(i = 1; i < j; i++)
Sergunb 0:8918a71cdbe9 218 device = device->next;
Sergunb 0:8918a71cdbe9 219
Sergunb 0:8918a71cdbe9 220 //Open the device
Sergunb 0:8918a71cdbe9 221 context->handle = pcap_open_live(device->name, 65535,
Sergunb 0:8918a71cdbe9 222 TRUE, PCAP_DRIVER_TIMEOUT, errorBuffer);
Sergunb 0:8918a71cdbe9 223
Sergunb 0:8918a71cdbe9 224 //Failed to open device?
Sergunb 0:8918a71cdbe9 225 if(context->handle == NULL)
Sergunb 0:8918a71cdbe9 226 {
Sergunb 0:8918a71cdbe9 227 //Debug message
Sergunb 0:8918a71cdbe9 228 printf("Failed to open device!\r\n");
Sergunb 0:8918a71cdbe9 229
Sergunb 0:8918a71cdbe9 230 //Clean up side effects
Sergunb 0:8918a71cdbe9 231 pcap_freealldevs(deviceList);
Sergunb 0:8918a71cdbe9 232 free(context);
Sergunb 0:8918a71cdbe9 233
Sergunb 0:8918a71cdbe9 234 //Report an error
Sergunb 0:8918a71cdbe9 235 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 236 }
Sergunb 0:8918a71cdbe9 237
Sergunb 0:8918a71cdbe9 238 //Free the device list
Sergunb 0:8918a71cdbe9 239 pcap_freealldevs(deviceList);
Sergunb 0:8918a71cdbe9 240
Sergunb 0:8918a71cdbe9 241 //Filter expression
Sergunb 0:8918a71cdbe9 242 sprintf(filterExpr, "!(ether src %02x:%02x:%02x:%02x:%02x:%02x) && "
Sergunb 0:8918a71cdbe9 243 "((ether dst %02x:%02x:%02x:%02x:%02x:%02x) || (ether broadcast) || (ether multicast))",
Sergunb 0:8918a71cdbe9 244 interface->macAddr.b[0], interface->macAddr.b[1], interface->macAddr.b[2],
Sergunb 0:8918a71cdbe9 245 interface->macAddr.b[3], interface->macAddr.b[4], interface->macAddr.b[5],
Sergunb 0:8918a71cdbe9 246 interface->macAddr.b[0], interface->macAddr.b[1], interface->macAddr.b[2],
Sergunb 0:8918a71cdbe9 247 interface->macAddr.b[3], interface->macAddr.b[4], interface->macAddr.b[5]);
Sergunb 0:8918a71cdbe9 248
Sergunb 0:8918a71cdbe9 249 //Compile the filter
Sergunb 0:8918a71cdbe9 250 ret = pcap_compile(context->handle, &filerCode, filterExpr, 1, 0);
Sergunb 0:8918a71cdbe9 251
Sergunb 0:8918a71cdbe9 252 //Failed to open device?
Sergunb 0:8918a71cdbe9 253 if(ret != 0)
Sergunb 0:8918a71cdbe9 254 {
Sergunb 0:8918a71cdbe9 255 //Debug message
Sergunb 0:8918a71cdbe9 256 printf("Failed to compile filter!\r\n");
Sergunb 0:8918a71cdbe9 257
Sergunb 0:8918a71cdbe9 258 //Clean up side effects
Sergunb 0:8918a71cdbe9 259 pcap_close(context->handle);
Sergunb 0:8918a71cdbe9 260 free(context);
Sergunb 0:8918a71cdbe9 261
Sergunb 0:8918a71cdbe9 262 //Report an error
Sergunb 0:8918a71cdbe9 263 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 264 }
Sergunb 0:8918a71cdbe9 265
Sergunb 0:8918a71cdbe9 266 //Set the filter
Sergunb 0:8918a71cdbe9 267 ret = pcap_setfilter(context->handle, &filerCode);
Sergunb 0:8918a71cdbe9 268
Sergunb 0:8918a71cdbe9 269 //Failed to open device?
Sergunb 0:8918a71cdbe9 270 if(ret != 0)
Sergunb 0:8918a71cdbe9 271 {
Sergunb 0:8918a71cdbe9 272 //Debug message
Sergunb 0:8918a71cdbe9 273 printf("Failed to set filter!\r\n");
Sergunb 0:8918a71cdbe9 274
Sergunb 0:8918a71cdbe9 275 //Clean up side effects
Sergunb 0:8918a71cdbe9 276 pcap_close(context->handle);
Sergunb 0:8918a71cdbe9 277 free(context);
Sergunb 0:8918a71cdbe9 278
Sergunb 0:8918a71cdbe9 279 //Report an error
Sergunb 0:8918a71cdbe9 280 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 281 }
Sergunb 0:8918a71cdbe9 282
Sergunb 0:8918a71cdbe9 283 #if (NET_RTOS_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 284 //Create the receive task
Sergunb 0:8918a71cdbe9 285 task = osCreateTask("PCAP", pcapDriverTask, interface, 0, 0);
Sergunb 0:8918a71cdbe9 286
Sergunb 0:8918a71cdbe9 287 //Failed to create the task?
Sergunb 0:8918a71cdbe9 288 if(task == OS_INVALID_HANDLE)
Sergunb 0:8918a71cdbe9 289 {
Sergunb 0:8918a71cdbe9 290 //Debug message
Sergunb 0:8918a71cdbe9 291 printf("Failed to create task!\r\n");
Sergunb 0:8918a71cdbe9 292
Sergunb 0:8918a71cdbe9 293 //Clean up side effects
Sergunb 0:8918a71cdbe9 294 pcap_close(context->handle);
Sergunb 0:8918a71cdbe9 295 free(context);
Sergunb 0:8918a71cdbe9 296
Sergunb 0:8918a71cdbe9 297 //Report an error
Sergunb 0:8918a71cdbe9 298 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 299 }
Sergunb 0:8918a71cdbe9 300 #endif
Sergunb 0:8918a71cdbe9 301
Sergunb 0:8918a71cdbe9 302 //Accept any packets from the upper layer
Sergunb 0:8918a71cdbe9 303 osSetEvent(&interface->nicTxEvent);
Sergunb 0:8918a71cdbe9 304
Sergunb 0:8918a71cdbe9 305 //Return status code
Sergunb 0:8918a71cdbe9 306 return NO_ERROR;
Sergunb 0:8918a71cdbe9 307 }
Sergunb 0:8918a71cdbe9 308
Sergunb 0:8918a71cdbe9 309
Sergunb 0:8918a71cdbe9 310 /**
Sergunb 0:8918a71cdbe9 311 * @brief PCAP timer handler
Sergunb 0:8918a71cdbe9 312 *
Sergunb 0:8918a71cdbe9 313 * This routine is periodically called by the TCP/IP stack to
Sergunb 0:8918a71cdbe9 314 * handle periodic operations such as polling the link state
Sergunb 0:8918a71cdbe9 315 *
Sergunb 0:8918a71cdbe9 316 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 317 **/
Sergunb 0:8918a71cdbe9 318
Sergunb 0:8918a71cdbe9 319 void pcapDriverTick(NetInterface *interface)
Sergunb 0:8918a71cdbe9 320 {
Sergunb 0:8918a71cdbe9 321 //Not implemented
Sergunb 0:8918a71cdbe9 322 }
Sergunb 0:8918a71cdbe9 323
Sergunb 0:8918a71cdbe9 324
Sergunb 0:8918a71cdbe9 325 /**
Sergunb 0:8918a71cdbe9 326 * @brief Enable interrupts
Sergunb 0:8918a71cdbe9 327 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 328 **/
Sergunb 0:8918a71cdbe9 329
Sergunb 0:8918a71cdbe9 330 void pcapDriverEnableIrq(NetInterface *interface)
Sergunb 0:8918a71cdbe9 331 {
Sergunb 0:8918a71cdbe9 332 //Not implemented
Sergunb 0:8918a71cdbe9 333 }
Sergunb 0:8918a71cdbe9 334
Sergunb 0:8918a71cdbe9 335
Sergunb 0:8918a71cdbe9 336 /**
Sergunb 0:8918a71cdbe9 337 * @brief Disable interrupts
Sergunb 0:8918a71cdbe9 338 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 339 **/
Sergunb 0:8918a71cdbe9 340
Sergunb 0:8918a71cdbe9 341 void pcapDriverDisableIrq(NetInterface *interface)
Sergunb 0:8918a71cdbe9 342 {
Sergunb 0:8918a71cdbe9 343 //Not implemented
Sergunb 0:8918a71cdbe9 344 }
Sergunb 0:8918a71cdbe9 345
Sergunb 0:8918a71cdbe9 346
Sergunb 0:8918a71cdbe9 347 /**
Sergunb 0:8918a71cdbe9 348 * @brief PCAP event handler
Sergunb 0:8918a71cdbe9 349 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 350 **/
Sergunb 0:8918a71cdbe9 351
Sergunb 0:8918a71cdbe9 352 void pcapDriverEventHandler(NetInterface *interface)
Sergunb 0:8918a71cdbe9 353 {
Sergunb 0:8918a71cdbe9 354 uint_t n;
Sergunb 0:8918a71cdbe9 355 PcapDriverContext *context;
Sergunb 0:8918a71cdbe9 356
Sergunb 0:8918a71cdbe9 357 //Point to the PCAP driver context
Sergunb 0:8918a71cdbe9 358 context = *((PcapDriverContext **) interface->nicContext);
Sergunb 0:8918a71cdbe9 359
Sergunb 0:8918a71cdbe9 360 //Process all pending packets
Sergunb 0:8918a71cdbe9 361 while(context->queue[context->readIndex].length > 0)
Sergunb 0:8918a71cdbe9 362 {
Sergunb 0:8918a71cdbe9 363 //Pass the packet to the upper layer
Sergunb 0:8918a71cdbe9 364 nicProcessPacket(interface, context->queue[context->readIndex].data,
Sergunb 0:8918a71cdbe9 365 context->queue[context->readIndex].length);
Sergunb 0:8918a71cdbe9 366
Sergunb 0:8918a71cdbe9 367 //Compute the index of the next packet descriptor
Sergunb 0:8918a71cdbe9 368 n = (context->readIndex + 1) % PCAP_DRIVER_QUEUE_SIZE;
Sergunb 0:8918a71cdbe9 369
Sergunb 0:8918a71cdbe9 370 //Release the current packet
Sergunb 0:8918a71cdbe9 371 context->queue[context->readIndex].length = 0;
Sergunb 0:8918a71cdbe9 372 //Point to the next packet descriptor
Sergunb 0:8918a71cdbe9 373 context->readIndex = n;
Sergunb 0:8918a71cdbe9 374 }
Sergunb 0:8918a71cdbe9 375 }
Sergunb 0:8918a71cdbe9 376
Sergunb 0:8918a71cdbe9 377
Sergunb 0:8918a71cdbe9 378 /**
Sergunb 0:8918a71cdbe9 379 * @brief Send a packet
Sergunb 0:8918a71cdbe9 380 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 381 * @param[in] buffer Multi-part buffer containing the data to send
Sergunb 0:8918a71cdbe9 382 * @param[in] offset Offset to the first data byte
Sergunb 0:8918a71cdbe9 383 * @return Error code
Sergunb 0:8918a71cdbe9 384 **/
Sergunb 0:8918a71cdbe9 385
Sergunb 0:8918a71cdbe9 386 error_t pcapDriverSendPacket(NetInterface *interface,
Sergunb 0:8918a71cdbe9 387 const NetBuffer *buffer, size_t offset)
Sergunb 0:8918a71cdbe9 388 {
Sergunb 0:8918a71cdbe9 389 int_t ret;
Sergunb 0:8918a71cdbe9 390 size_t length;
Sergunb 0:8918a71cdbe9 391 PcapDriverContext *context;
Sergunb 0:8918a71cdbe9 392 uint8_t temp[PCAP_DRIVER_MAX_PACKET_SIZE];
Sergunb 0:8918a71cdbe9 393
Sergunb 0:8918a71cdbe9 394 //Point to the PCAP driver context
Sergunb 0:8918a71cdbe9 395 context = *((PcapDriverContext **) interface->nicContext);
Sergunb 0:8918a71cdbe9 396
Sergunb 0:8918a71cdbe9 397 //Retrieve the length of the packet
Sergunb 0:8918a71cdbe9 398 length = netBufferGetLength(buffer) - offset;
Sergunb 0:8918a71cdbe9 399
Sergunb 0:8918a71cdbe9 400 //Check the frame length
Sergunb 0:8918a71cdbe9 401 if(length > PCAP_DRIVER_MAX_PACKET_SIZE)
Sergunb 0:8918a71cdbe9 402 {
Sergunb 0:8918a71cdbe9 403 //The transmitter can accept another packet
Sergunb 0:8918a71cdbe9 404 osSetEvent(&interface->nicTxEvent);
Sergunb 0:8918a71cdbe9 405 //Report an error
Sergunb 0:8918a71cdbe9 406 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 407 }
Sergunb 0:8918a71cdbe9 408
Sergunb 0:8918a71cdbe9 409 //Copy the packet to the transmit buffer
Sergunb 0:8918a71cdbe9 410 netBufferRead(temp, buffer, offset, length);
Sergunb 0:8918a71cdbe9 411
Sergunb 0:8918a71cdbe9 412 //Send packet
Sergunb 0:8918a71cdbe9 413 ret = pcap_sendpacket(context->handle, temp, length);
Sergunb 0:8918a71cdbe9 414
Sergunb 0:8918a71cdbe9 415 //The transmitter can accept another packet
Sergunb 0:8918a71cdbe9 416 osSetEvent(&interface->nicTxEvent);
Sergunb 0:8918a71cdbe9 417
Sergunb 0:8918a71cdbe9 418 //Return status code
Sergunb 0:8918a71cdbe9 419 if(ret < 0)
Sergunb 0:8918a71cdbe9 420 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 421 else
Sergunb 0:8918a71cdbe9 422 return NO_ERROR;
Sergunb 0:8918a71cdbe9 423 }
Sergunb 0:8918a71cdbe9 424
Sergunb 0:8918a71cdbe9 425
Sergunb 0:8918a71cdbe9 426 /**
Sergunb 0:8918a71cdbe9 427 * @brief Configure multicast MAC address filtering
Sergunb 0:8918a71cdbe9 428 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 429 * @return Error code
Sergunb 0:8918a71cdbe9 430 **/
Sergunb 0:8918a71cdbe9 431
Sergunb 0:8918a71cdbe9 432 error_t pcapDriverSetMulticastFilter(NetInterface *interface)
Sergunb 0:8918a71cdbe9 433 {
Sergunb 0:8918a71cdbe9 434 //Not implemented
Sergunb 0:8918a71cdbe9 435 return NO_ERROR;
Sergunb 0:8918a71cdbe9 436 }
Sergunb 0:8918a71cdbe9 437
Sergunb 0:8918a71cdbe9 438
Sergunb 0:8918a71cdbe9 439 /**
Sergunb 0:8918a71cdbe9 440 * @brief PCAP receive task
Sergunb 0:8918a71cdbe9 441 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 442 **/
Sergunb 0:8918a71cdbe9 443
Sergunb 0:8918a71cdbe9 444 void pcapDriverTask(NetInterface *interface)
Sergunb 0:8918a71cdbe9 445 {
Sergunb 0:8918a71cdbe9 446 int_t ret;
Sergunb 0:8918a71cdbe9 447 uint_t n;
Sergunb 0:8918a71cdbe9 448 uint_t length;
Sergunb 0:8918a71cdbe9 449 const uint8_t *data;
Sergunb 0:8918a71cdbe9 450 struct pcap_pkthdr *header;
Sergunb 0:8918a71cdbe9 451 PcapDriverContext *context;
Sergunb 0:8918a71cdbe9 452
Sergunb 0:8918a71cdbe9 453 //Point to the PCAP driver context
Sergunb 0:8918a71cdbe9 454 context = *((PcapDriverContext **) interface->nicContext);
Sergunb 0:8918a71cdbe9 455
Sergunb 0:8918a71cdbe9 456 //Process events
Sergunb 0:8918a71cdbe9 457 while(1)
Sergunb 0:8918a71cdbe9 458 {
Sergunb 0:8918a71cdbe9 459 //Wait for an incoming packet
Sergunb 0:8918a71cdbe9 460 ret = pcap_next_ex(context->handle, &header, &data);
Sergunb 0:8918a71cdbe9 461
Sergunb 0:8918a71cdbe9 462 //Any packet received?
Sergunb 0:8918a71cdbe9 463 if(ret > 0)
Sergunb 0:8918a71cdbe9 464 {
Sergunb 0:8918a71cdbe9 465 //Retrieve the length of the packet
Sergunb 0:8918a71cdbe9 466 length = header->caplen;
Sergunb 0:8918a71cdbe9 467
Sergunb 0:8918a71cdbe9 468 //Check the length of the received packet
Sergunb 0:8918a71cdbe9 469 if(length > 0 && length < PCAP_DRIVER_MAX_PACKET_SIZE)
Sergunb 0:8918a71cdbe9 470 {
Sergunb 0:8918a71cdbe9 471 //Check whether the link is up
Sergunb 0:8918a71cdbe9 472 if(interface->linkState)
Sergunb 0:8918a71cdbe9 473 {
Sergunb 0:8918a71cdbe9 474 //Compute the index of the next packet descriptor
Sergunb 0:8918a71cdbe9 475 n = (context->writeIndex + 1) % PCAP_DRIVER_QUEUE_SIZE;
Sergunb 0:8918a71cdbe9 476
Sergunb 0:8918a71cdbe9 477 //Ensure the receive queue is not full
Sergunb 0:8918a71cdbe9 478 if(n != context->readIndex)
Sergunb 0:8918a71cdbe9 479 {
Sergunb 0:8918a71cdbe9 480 //Copy the incoming packet
Sergunb 0:8918a71cdbe9 481 memcpy(context->queue[context->writeIndex].data, data, length);
Sergunb 0:8918a71cdbe9 482 //Save the length of the packet
Sergunb 0:8918a71cdbe9 483 context->queue[context->writeIndex].length = length;
Sergunb 0:8918a71cdbe9 484
Sergunb 0:8918a71cdbe9 485 //Point to the next packet descriptor
Sergunb 0:8918a71cdbe9 486 context->writeIndex = n;
Sergunb 0:8918a71cdbe9 487
Sergunb 0:8918a71cdbe9 488 //Set event flag
Sergunb 0:8918a71cdbe9 489 interface->nicEvent = TRUE;
Sergunb 0:8918a71cdbe9 490 //Notify the TCP/IP stack of the event
Sergunb 0:8918a71cdbe9 491 osSetEvent(&netEvent);
Sergunb 0:8918a71cdbe9 492 }
Sergunb 0:8918a71cdbe9 493 }
Sergunb 0:8918a71cdbe9 494 }
Sergunb 0:8918a71cdbe9 495 }
Sergunb 0:8918a71cdbe9 496 else
Sergunb 0:8918a71cdbe9 497 {
Sergunb 0:8918a71cdbe9 498 #if (NET_RTOS_SUPPORT == DISABLED)
Sergunb 0:8918a71cdbe9 499 //No packet has been received
Sergunb 0:8918a71cdbe9 500 break;
Sergunb 0:8918a71cdbe9 501 #endif
Sergunb 0:8918a71cdbe9 502 }
Sergunb 0:8918a71cdbe9 503 }
Sergunb 0:8918a71cdbe9 504 }
Sergunb 0:8918a71cdbe9 505