Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
pcap_driver.c
Go to the documentation of this file.
00001 /** 00002 * @file pcap_driver.c 00003 * @brief PCAP driver 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneTCP Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00026 * @version 1.7.6 00027 **/ 00028 00029 //Switch to the appropriate trace level 00030 #define TRACE_LEVEL NIC_TRACE_LEVEL 00031 00032 //Dependencies 00033 #include "core/net.h" 00034 #include "drivers/pcap_driver.h" 00035 #include "debug.h" 00036 00037 //Undefine conflicting definitions 00038 #undef Socket 00039 #undef htons 00040 #undef htonl 00041 #undef ntohs 00042 #undef ntohl 00043 00044 //PCAP dependencies 00045 #include <pcap.h> 00046 00047 //Undefine conflicting definitions 00048 #undef interface 00049 00050 00051 /** 00052 * @brief Packet descriptor 00053 **/ 00054 00055 typedef struct 00056 { 00057 size_t length; 00058 uint8_t data[PCAP_DRIVER_MAX_PACKET_SIZE]; 00059 } PcapDriverPacket; 00060 00061 00062 /** 00063 * @brief PCAP driver context 00064 **/ 00065 00066 typedef struct 00067 { 00068 pcap_t *handle; 00069 uint_t writeIndex; 00070 uint_t readIndex; 00071 PcapDriverPacket queue[PCAP_DRIVER_QUEUE_SIZE]; 00072 } PcapDriverContext; 00073 00074 00075 /** 00076 * @brief PCAP driver 00077 **/ 00078 00079 const NicDriver pcapDriver = 00080 { 00081 NIC_TYPE_ETHERNET, 00082 ETH_MTU, 00083 pcapDriverInit, 00084 pcapDriverTick, 00085 pcapDriverEnableIrq, 00086 pcapDriverDisableIrq, 00087 pcapDriverEventHandler, 00088 pcapDriverSendPacket, 00089 pcapDriverSetMulticastFilter, 00090 NULL, 00091 NULL, 00092 NULL, 00093 TRUE, 00094 TRUE, 00095 TRUE, 00096 TRUE 00097 }; 00098 00099 00100 /** 00101 * @brief PCAP driver initialization 00102 * @param[in] interface Underlying network interface 00103 * @return Error code 00104 **/ 00105 00106 error_t pcapDriverInit(NetInterface *interface) 00107 { 00108 int_t ret; 00109 uint_t i; 00110 uint_t j; 00111 pcap_if_t *device; 00112 pcap_if_t *deviceList; 00113 struct bpf_program filerCode; 00114 char_t filterExpr[256]; 00115 char_t errorBuffer[PCAP_ERRBUF_SIZE]; 00116 PcapDriverContext *context; 00117 #if (NET_RTOS_SUPPORT == ENABLED) 00118 OsTask *task; 00119 #endif 00120 00121 //Debug message 00122 TRACE_INFO("Initializing PCAP driver...\r\n"); 00123 00124 //Allocate PCAP driver context 00125 context = (PcapDriverContext *) malloc(sizeof(PcapDriverContext)); 00126 00127 //Failed to allocate memory? 00128 if(context == NULL) 00129 { 00130 //Debug message 00131 printf("Failed to allocate context!\r\n"); 00132 00133 //Report an error 00134 return ERROR_FAILURE; 00135 } 00136 00137 //Attach the PCAP driver context to the network interface 00138 *((PcapDriverContext **) interface->nicContext) = context; 00139 //Clear PCAP driver context 00140 memset(context, 0, sizeof(PcapDriverContext)); 00141 00142 //Find all the devices 00143 ret = pcap_findalldevs(&deviceList, errorBuffer); 00144 00145 //Any error to report? 00146 if(ret != 0) 00147 { 00148 //Debug message 00149 printf("Failed to list devices!\r\n"); 00150 00151 //Clean up side effects 00152 free(context); 00153 00154 //Report an error 00155 return ERROR_FAILURE; 00156 } 00157 00158 //No network adapter found? 00159 if(deviceList == NULL) 00160 { 00161 //Debug message 00162 printf("No network adapter found!\r\n"); 00163 00164 //Clean up side effects 00165 free(context); 00166 00167 //Exit immediately 00168 return ERROR_FAILURE; 00169 } 00170 00171 //Network adapter selection 00172 while(1) 00173 { 00174 //Debug message 00175 printf("Network adapters:\r\n"); 00176 00177 //Point to the first device 00178 device = deviceList; 00179 i = 0; 00180 00181 //Loop through the list of devices 00182 while(device != NULL) 00183 { 00184 //Index of the current network adapter 00185 printf(" %-2u", i + 1); 00186 00187 #if !defined(_WIN32) 00188 //Display the name of the device 00189 if(device->name != NULL) 00190 printf(" %-8s", device->name); 00191 #endif 00192 //Description of the device 00193 if(device->description != NULL) 00194 printf(" %s\r\n", device->description); 00195 else 00196 printf(" -\r\n"); 00197 00198 //Next device 00199 device = device->next; 00200 i++; 00201 } 00202 00203 //Display message 00204 printf("Select network adapter for %s interface (1-%u):", interface->name, i); 00205 //Get user choice 00206 scanf("%d", &j); 00207 00208 //Valid selection? 00209 if(j >= 1 && j <= i) 00210 break; 00211 } 00212 00213 //Point to the first device 00214 device = deviceList; 00215 00216 //Point to the desired network adapter 00217 for(i = 1; i < j; i++) 00218 device = device->next; 00219 00220 //Open the device 00221 context->handle = pcap_open_live(device->name, 65535, 00222 TRUE, PCAP_DRIVER_TIMEOUT, errorBuffer); 00223 00224 //Failed to open device? 00225 if(context->handle == NULL) 00226 { 00227 //Debug message 00228 printf("Failed to open device!\r\n"); 00229 00230 //Clean up side effects 00231 pcap_freealldevs(deviceList); 00232 free(context); 00233 00234 //Report an error 00235 return ERROR_FAILURE; 00236 } 00237 00238 //Free the device list 00239 pcap_freealldevs(deviceList); 00240 00241 //Filter expression 00242 sprintf(filterExpr, "!(ether src %02x:%02x:%02x:%02x:%02x:%02x) && " 00243 "((ether dst %02x:%02x:%02x:%02x:%02x:%02x) || (ether broadcast) || (ether multicast))", 00244 interface->macAddr.b[0], interface->macAddr.b[1], interface->macAddr.b[2], 00245 interface->macAddr.b[3], interface->macAddr.b[4], interface->macAddr.b[5], 00246 interface->macAddr.b[0], interface->macAddr.b[1], interface->macAddr.b[2], 00247 interface->macAddr.b[3], interface->macAddr.b[4], interface->macAddr.b[5]); 00248 00249 //Compile the filter 00250 ret = pcap_compile(context->handle, &filerCode, filterExpr, 1, 0); 00251 00252 //Failed to open device? 00253 if(ret != 0) 00254 { 00255 //Debug message 00256 printf("Failed to compile filter!\r\n"); 00257 00258 //Clean up side effects 00259 pcap_close(context->handle); 00260 free(context); 00261 00262 //Report an error 00263 return ERROR_FAILURE; 00264 } 00265 00266 //Set the filter 00267 ret = pcap_setfilter(context->handle, &filerCode); 00268 00269 //Failed to open device? 00270 if(ret != 0) 00271 { 00272 //Debug message 00273 printf("Failed to set filter!\r\n"); 00274 00275 //Clean up side effects 00276 pcap_close(context->handle); 00277 free(context); 00278 00279 //Report an error 00280 return ERROR_FAILURE; 00281 } 00282 00283 #if (NET_RTOS_SUPPORT == ENABLED) 00284 //Create the receive task 00285 task = osCreateTask("PCAP", pcapDriverTask, interface, 0, 0); 00286 00287 //Failed to create the task? 00288 if(task == OS_INVALID_HANDLE) 00289 { 00290 //Debug message 00291 printf("Failed to create task!\r\n"); 00292 00293 //Clean up side effects 00294 pcap_close(context->handle); 00295 free(context); 00296 00297 //Report an error 00298 return ERROR_FAILURE; 00299 } 00300 #endif 00301 00302 //Accept any packets from the upper layer 00303 osSetEvent(&interface->nicTxEvent); 00304 00305 //Return status code 00306 return NO_ERROR; 00307 } 00308 00309 00310 /** 00311 * @brief PCAP timer handler 00312 * 00313 * This routine is periodically called by the TCP/IP stack to 00314 * handle periodic operations such as polling the link state 00315 * 00316 * @param[in] interface Underlying network interface 00317 **/ 00318 00319 void pcapDriverTick(NetInterface *interface) 00320 { 00321 //Not implemented 00322 } 00323 00324 00325 /** 00326 * @brief Enable interrupts 00327 * @param[in] interface Underlying network interface 00328 **/ 00329 00330 void pcapDriverEnableIrq(NetInterface *interface) 00331 { 00332 //Not implemented 00333 } 00334 00335 00336 /** 00337 * @brief Disable interrupts 00338 * @param[in] interface Underlying network interface 00339 **/ 00340 00341 void pcapDriverDisableIrq(NetInterface *interface) 00342 { 00343 //Not implemented 00344 } 00345 00346 00347 /** 00348 * @brief PCAP event handler 00349 * @param[in] interface Underlying network interface 00350 **/ 00351 00352 void pcapDriverEventHandler(NetInterface *interface) 00353 { 00354 uint_t n; 00355 PcapDriverContext *context; 00356 00357 //Point to the PCAP driver context 00358 context = *((PcapDriverContext **) interface->nicContext); 00359 00360 //Process all pending packets 00361 while(context->queue[context->readIndex].length > 0) 00362 { 00363 //Pass the packet to the upper layer 00364 nicProcessPacket(interface, context->queue[context->readIndex].data, 00365 context->queue[context->readIndex].length); 00366 00367 //Compute the index of the next packet descriptor 00368 n = (context->readIndex + 1) % PCAP_DRIVER_QUEUE_SIZE; 00369 00370 //Release the current packet 00371 context->queue[context->readIndex].length = 0; 00372 //Point to the next packet descriptor 00373 context->readIndex = n; 00374 } 00375 } 00376 00377 00378 /** 00379 * @brief Send a packet 00380 * @param[in] interface Underlying network interface 00381 * @param[in] buffer Multi-part buffer containing the data to send 00382 * @param[in] offset Offset to the first data byte 00383 * @return Error code 00384 **/ 00385 00386 error_t pcapDriverSendPacket(NetInterface *interface, 00387 const NetBuffer *buffer, size_t offset) 00388 { 00389 int_t ret; 00390 size_t length; 00391 PcapDriverContext *context; 00392 uint8_t temp[PCAP_DRIVER_MAX_PACKET_SIZE]; 00393 00394 //Point to the PCAP driver context 00395 context = *((PcapDriverContext **) interface->nicContext); 00396 00397 //Retrieve the length of the packet 00398 length = netBufferGetLength(buffer) - offset; 00399 00400 //Check the frame length 00401 if(length > PCAP_DRIVER_MAX_PACKET_SIZE) 00402 { 00403 //The transmitter can accept another packet 00404 osSetEvent(&interface->nicTxEvent); 00405 //Report an error 00406 return ERROR_INVALID_LENGTH; 00407 } 00408 00409 //Copy the packet to the transmit buffer 00410 netBufferRead(temp, buffer, offset, length); 00411 00412 //Send packet 00413 ret = pcap_sendpacket(context->handle, temp, length); 00414 00415 //The transmitter can accept another packet 00416 osSetEvent(&interface->nicTxEvent); 00417 00418 //Return status code 00419 if(ret < 0) 00420 return ERROR_FAILURE; 00421 else 00422 return NO_ERROR; 00423 } 00424 00425 00426 /** 00427 * @brief Configure multicast MAC address filtering 00428 * @param[in] interface Underlying network interface 00429 * @return Error code 00430 **/ 00431 00432 error_t pcapDriverSetMulticastFilter(NetInterface *interface) 00433 { 00434 //Not implemented 00435 return NO_ERROR; 00436 } 00437 00438 00439 /** 00440 * @brief PCAP receive task 00441 * @param[in] interface Underlying network interface 00442 **/ 00443 00444 void pcapDriverTask(NetInterface *interface) 00445 { 00446 int_t ret; 00447 uint_t n; 00448 uint_t length; 00449 const uint8_t *data; 00450 struct pcap_pkthdr *header; 00451 PcapDriverContext *context; 00452 00453 //Point to the PCAP driver context 00454 context = *((PcapDriverContext **) interface->nicContext); 00455 00456 //Process events 00457 while(1) 00458 { 00459 //Wait for an incoming packet 00460 ret = pcap_next_ex(context->handle, &header, &data); 00461 00462 //Any packet received? 00463 if(ret > 0) 00464 { 00465 //Retrieve the length of the packet 00466 length = header->caplen; 00467 00468 //Check the length of the received packet 00469 if(length > 0 && length < PCAP_DRIVER_MAX_PACKET_SIZE) 00470 { 00471 //Check whether the link is up 00472 if(interface->linkState) 00473 { 00474 //Compute the index of the next packet descriptor 00475 n = (context->writeIndex + 1) % PCAP_DRIVER_QUEUE_SIZE; 00476 00477 //Ensure the receive queue is not full 00478 if(n != context->readIndex) 00479 { 00480 //Copy the incoming packet 00481 memcpy(context->queue[context->writeIndex].data, data, length); 00482 //Save the length of the packet 00483 context->queue[context->writeIndex].length = length; 00484 00485 //Point to the next packet descriptor 00486 context->writeIndex = n; 00487 00488 //Set event flag 00489 interface->nicEvent = TRUE; 00490 //Notify the TCP/IP stack of the event 00491 osSetEvent(&netEvent); 00492 } 00493 } 00494 } 00495 } 00496 else 00497 { 00498 #if (NET_RTOS_SUPPORT == DISABLED) 00499 //No packet has been received 00500 break; 00501 #endif 00502 } 00503 } 00504 } 00505
Generated on Tue Jul 12 2022 17:10:15 by
