pcap-dag.c 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430
  1. /*
  2. * pcap-dag.c: Packet capture interface for Endace DAG cards.
  3. *
  4. * The functionality of this code attempts to mimic that of pcap-linux as much
  5. * as possible. This code is compiled in several different ways depending on
  6. * whether DAG_ONLY and HAVE_DAG_API are defined. If HAVE_DAG_API is not
  7. * defined it should not get compiled in, otherwise if DAG_ONLY is defined then
  8. * the 'dag_' function calls are renamed to 'pcap_' equivalents. If DAG_ONLY
  9. * is not defined then nothing is altered - the dag_ functions will be
  10. * called as required from their pcap-linux/bpf equivalents.
  11. *
  12. * Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
  13. * Modifications: Jesper Peterson
  14. * Koryn Grant
  15. * Stephen Donnelly <stephen.donnelly@endace.com>
  16. */
  17. #ifdef HAVE_CONFIG_H
  18. #include <config.h>
  19. #endif
  20. #include <sys/param.h> /* optionally get BSD define */
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <errno.h>
  24. #include "pcap-int.h"
  25. #include <ctype.h>
  26. #include <netinet/in.h>
  27. #include <sys/mman.h>
  28. #include <sys/socket.h>
  29. #include <sys/types.h>
  30. #include <unistd.h>
  31. struct mbuf; /* Squelch compiler warnings on some platforms for */
  32. struct rtentry; /* declarations in <net/if.h> */
  33. #include <net/if.h>
  34. #include "dagnew.h"
  35. #include "dagapi.h"
  36. #include "dagpci.h"
  37. #include "dag_config_api.h"
  38. #include "pcap-dag.h"
  39. /*
  40. * DAG devices have names beginning with "dag", followed by a number
  41. * from 0 to DAG_MAX_BOARDS, then optionally a colon and a stream number
  42. * from 0 to DAG_STREAM_MAX.
  43. */
  44. #ifndef DAG_MAX_BOARDS
  45. #define DAG_MAX_BOARDS 32
  46. #endif
  47. #ifndef ERF_TYPE_AAL5
  48. #define ERF_TYPE_AAL5 4
  49. #endif
  50. #ifndef ERF_TYPE_MC_HDLC
  51. #define ERF_TYPE_MC_HDLC 5
  52. #endif
  53. #ifndef ERF_TYPE_MC_RAW
  54. #define ERF_TYPE_MC_RAW 6
  55. #endif
  56. #ifndef ERF_TYPE_MC_ATM
  57. #define ERF_TYPE_MC_ATM 7
  58. #endif
  59. #ifndef ERF_TYPE_MC_RAW_CHANNEL
  60. #define ERF_TYPE_MC_RAW_CHANNEL 8
  61. #endif
  62. #ifndef ERF_TYPE_MC_AAL5
  63. #define ERF_TYPE_MC_AAL5 9
  64. #endif
  65. #ifndef ERF_TYPE_COLOR_HDLC_POS
  66. #define ERF_TYPE_COLOR_HDLC_POS 10
  67. #endif
  68. #ifndef ERF_TYPE_COLOR_ETH
  69. #define ERF_TYPE_COLOR_ETH 11
  70. #endif
  71. #ifndef ERF_TYPE_MC_AAL2
  72. #define ERF_TYPE_MC_AAL2 12
  73. #endif
  74. #ifndef ERF_TYPE_IP_COUNTER
  75. #define ERF_TYPE_IP_COUNTER 13
  76. #endif
  77. #ifndef ERF_TYPE_TCP_FLOW_COUNTER
  78. #define ERF_TYPE_TCP_FLOW_COUNTER 14
  79. #endif
  80. #ifndef ERF_TYPE_DSM_COLOR_HDLC_POS
  81. #define ERF_TYPE_DSM_COLOR_HDLC_POS 15
  82. #endif
  83. #ifndef ERF_TYPE_DSM_COLOR_ETH
  84. #define ERF_TYPE_DSM_COLOR_ETH 16
  85. #endif
  86. #ifndef ERF_TYPE_COLOR_MC_HDLC_POS
  87. #define ERF_TYPE_COLOR_MC_HDLC_POS 17
  88. #endif
  89. #ifndef ERF_TYPE_AAL2
  90. #define ERF_TYPE_AAL2 18
  91. #endif
  92. #ifndef ERF_TYPE_COLOR_HASH_POS
  93. #define ERF_TYPE_COLOR_HASH_POS 19
  94. #endif
  95. #ifndef ERF_TYPE_COLOR_HASH_ETH
  96. #define ERF_TYPE_COLOR_HASH_ETH 20
  97. #endif
  98. #ifndef ERF_TYPE_INFINIBAND
  99. #define ERF_TYPE_INFINIBAND 21
  100. #endif
  101. #ifndef ERF_TYPE_IPV4
  102. #define ERF_TYPE_IPV4 22
  103. #endif
  104. #ifndef ERF_TYPE_IPV6
  105. #define ERF_TYPE_IPV6 23
  106. #endif
  107. #ifndef ERF_TYPE_RAW_LINK
  108. #define ERF_TYPE_RAW_LINK 24
  109. #endif
  110. #ifndef ERF_TYPE_INFINIBAND_LINK
  111. #define ERF_TYPE_INFINIBAND_LINK 25
  112. #endif
  113. #ifndef ERF_TYPE_META
  114. #define ERF_TYPE_META 27
  115. #endif
  116. #ifndef ERF_TYPE_PAD
  117. #define ERF_TYPE_PAD 48
  118. #endif
  119. #define ATM_CELL_SIZE 52
  120. #define ATM_HDR_SIZE 4
  121. /*
  122. * A header containing additional MTP information.
  123. */
  124. #define MTP2_SENT_OFFSET 0 /* 1 byte */
  125. #define MTP2_ANNEX_A_USED_OFFSET 1 /* 1 byte */
  126. #define MTP2_LINK_NUMBER_OFFSET 2 /* 2 bytes */
  127. #define MTP2_HDR_LEN 4 /* length of the header */
  128. #define MTP2_ANNEX_A_NOT_USED 0
  129. #define MTP2_ANNEX_A_USED 1
  130. #define MTP2_ANNEX_A_USED_UNKNOWN 2
  131. /* SunATM pseudo header */
  132. struct sunatm_hdr {
  133. unsigned char flags; /* destination and traffic type */
  134. unsigned char vpi; /* VPI */
  135. unsigned short vci; /* VCI */
  136. };
  137. /*
  138. * Private data for capturing on DAG devices.
  139. */
  140. struct pcap_dag {
  141. struct pcap_stat stat;
  142. u_char *dag_mem_bottom; /* DAG card current memory bottom pointer */
  143. u_char *dag_mem_top; /* DAG card current memory top pointer */
  144. int dag_fcs_bits; /* Number of checksum bits from link layer */
  145. int dag_flags; /* Flags */
  146. int dag_stream; /* DAG stream number */
  147. int dag_timeout; /* timeout specified to pcap_open_live.
  148. * Same as in linux above, introduce
  149. * generally? */
  150. dag_card_ref_t dag_ref; /* DAG Configuration/Status API card reference */
  151. dag_component_t dag_root; /* DAG CSAPI Root component */
  152. attr_uuid_t drop_attr; /* DAG Stream Drop Attribute handle, if available */
  153. struct timeval required_select_timeout;
  154. /* Timeout caller must use in event loops */
  155. };
  156. typedef struct pcap_dag_node {
  157. struct pcap_dag_node *next;
  158. pcap_t *p;
  159. pid_t pid;
  160. } pcap_dag_node_t;
  161. static pcap_dag_node_t *pcap_dags = NULL;
  162. static int atexit_handler_installed = 0;
  163. static const unsigned short endian_test_word = 0x0100;
  164. #define IS_BIGENDIAN() (*((unsigned char *)&endian_test_word))
  165. #define MAX_DAG_PACKET 65536
  166. static unsigned char TempPkt[MAX_DAG_PACKET];
  167. #ifndef HAVE_DAG_LARGE_STREAMS_API
  168. #define dag_attach_stream64(a, b, c, d) dag_attach_stream(a, b, c, d)
  169. #define dag_get_stream_poll64(a, b, c, d, e) dag_get_stream_poll(a, b, c, d, e)
  170. #define dag_set_stream_poll64(a, b, c, d, e) dag_set_stream_poll(a, b, c, d, e)
  171. #define dag_size_t uint32_t
  172. #endif
  173. static int dag_setfilter(pcap_t *p, struct bpf_program *fp);
  174. static int dag_stats(pcap_t *p, struct pcap_stat *ps);
  175. static int dag_set_datalink(pcap_t *p, int dlt);
  176. static int dag_get_datalink(pcap_t *p);
  177. static int dag_setnonblock(pcap_t *p, int nonblock);
  178. static void
  179. delete_pcap_dag(pcap_t *p)
  180. {
  181. pcap_dag_node_t *curr = NULL, *prev = NULL;
  182. for (prev = NULL, curr = pcap_dags; curr != NULL && curr->p != p; prev = curr, curr = curr->next) {
  183. /* empty */
  184. }
  185. if (curr != NULL && curr->p == p) {
  186. if (prev != NULL) {
  187. prev->next = curr->next;
  188. } else {
  189. pcap_dags = curr->next;
  190. }
  191. }
  192. }
  193. /*
  194. * Performs a graceful shutdown of the DAG card, frees dynamic memory held
  195. * in the pcap_t structure, and closes the file descriptor for the DAG card.
  196. */
  197. static void
  198. dag_platform_cleanup(pcap_t *p)
  199. {
  200. struct pcap_dag *pd = p->priv;
  201. if(dag_stop_stream(p->fd, pd->dag_stream) < 0)
  202. fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
  203. if(dag_detach_stream(p->fd, pd->dag_stream) < 0)
  204. fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
  205. if(pd->dag_ref != NULL) {
  206. dag_config_dispose(pd->dag_ref);
  207. p->fd = -1;
  208. pd->dag_ref = NULL;
  209. }
  210. delete_pcap_dag(p);
  211. pcap_cleanup_live_common(p);
  212. /* Note: don't need to call close(p->fd) or dag_close(p->fd) as dag_config_dispose(pd->dag_ref) does this. */
  213. }
  214. static void
  215. atexit_handler(void)
  216. {
  217. while (pcap_dags != NULL) {
  218. if (pcap_dags->pid == getpid()) {
  219. if (pcap_dags->p != NULL)
  220. dag_platform_cleanup(pcap_dags->p);
  221. } else {
  222. delete_pcap_dag(pcap_dags->p);
  223. }
  224. }
  225. }
  226. static int
  227. new_pcap_dag(pcap_t *p)
  228. {
  229. pcap_dag_node_t *node = NULL;
  230. if ((node = malloc(sizeof(pcap_dag_node_t))) == NULL) {
  231. return -1;
  232. }
  233. if (!atexit_handler_installed) {
  234. atexit(atexit_handler);
  235. atexit_handler_installed = 1;
  236. }
  237. node->next = pcap_dags;
  238. node->p = p;
  239. node->pid = getpid();
  240. pcap_dags = node;
  241. return 0;
  242. }
  243. static unsigned int
  244. dag_erf_ext_header_count(uint8_t * erf, size_t len)
  245. {
  246. uint32_t hdr_num = 0;
  247. uint8_t hdr_type;
  248. /* basic sanity checks */
  249. if ( erf == NULL )
  250. return 0;
  251. if ( len < 16 )
  252. return 0;
  253. /* check if we have any extension headers */
  254. if ( (erf[8] & 0x80) == 0x00 )
  255. return 0;
  256. /* loop over the extension headers */
  257. do {
  258. /* sanity check we have enough bytes */
  259. if ( len < (24 + (hdr_num * 8)) )
  260. return hdr_num;
  261. /* get the header type */
  262. hdr_type = erf[(16 + (hdr_num * 8))];
  263. hdr_num++;
  264. } while ( hdr_type & 0x80 );
  265. return hdr_num;
  266. }
  267. /*
  268. * Read at most max_packets from the capture stream and call the callback
  269. * for each of them. Returns the number of packets handled, -1 if an
  270. * error occured, or -2 if we were told to break out of the loop.
  271. */
  272. static int
  273. dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
  274. {
  275. struct pcap_dag *pd = p->priv;
  276. unsigned int processed = 0;
  277. unsigned int nonblocking = pd->dag_flags & DAGF_NONBLOCK;
  278. unsigned int num_ext_hdr = 0;
  279. unsigned int ticks_per_second;
  280. /* Get the next bufferful of packets (if necessary). */
  281. while (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size) {
  282. /*
  283. * Has "pcap_breakloop()" been called?
  284. */
  285. if (p->break_loop) {
  286. /*
  287. * Yes - clear the flag that indicates that
  288. * it has, and return -2 to indicate that
  289. * we were told to break out of the loop.
  290. */
  291. p->break_loop = 0;
  292. return -2;
  293. }
  294. /* dag_advance_stream() will block (unless nonblock is called)
  295. * until 64kB of data has accumulated.
  296. * If to_ms is set, it will timeout before 64kB has accumulated.
  297. * We wait for 64kB because processing a few packets at a time
  298. * can cause problems at high packet rates (>200kpps) due
  299. * to inefficiencies.
  300. * This does mean if to_ms is not specified the capture may 'hang'
  301. * for long periods if the data rate is extremely slow (<64kB/sec)
  302. * If non-block is specified it will return immediately. The user
  303. * is then responsible for efficiency.
  304. */
  305. if ( NULL == (pd->dag_mem_top = dag_advance_stream(p->fd, pd->dag_stream, &(pd->dag_mem_bottom))) ) {
  306. return -1;
  307. }
  308. if (nonblocking && (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
  309. {
  310. /* Pcap is configured to process only available packets, and there aren't any, return immediately. */
  311. return 0;
  312. }
  313. if(!nonblocking &&
  314. pd->dag_timeout &&
  315. (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
  316. {
  317. /* Blocking mode, but timeout set and no data has arrived, return anyway.*/
  318. return 0;
  319. }
  320. }
  321. /* Process the packets. */
  322. while (pd->dag_mem_top - pd->dag_mem_bottom >= dag_record_size) {
  323. unsigned short packet_len = 0;
  324. int caplen = 0;
  325. struct pcap_pkthdr pcap_header;
  326. dag_record_t *header = (dag_record_t *)(pd->dag_mem_bottom);
  327. u_char *dp = ((u_char *)header); /* + dag_record_size; */
  328. unsigned short rlen;
  329. /*
  330. * Has "pcap_breakloop()" been called?
  331. */
  332. if (p->break_loop) {
  333. /*
  334. * Yes - clear the flag that indicates that
  335. * it has, and return -2 to indicate that
  336. * we were told to break out of the loop.
  337. */
  338. p->break_loop = 0;
  339. return -2;
  340. }
  341. rlen = ntohs(header->rlen);
  342. if (rlen < dag_record_size)
  343. {
  344. strncpy(p->errbuf, "dag_read: record too small", PCAP_ERRBUF_SIZE);
  345. return -1;
  346. }
  347. pd->dag_mem_bottom += rlen;
  348. /* Count lost packets. */
  349. switch((header->type & 0x7f)) {
  350. /* in these types the color value overwrites the lctr */
  351. case ERF_TYPE_COLOR_HDLC_POS:
  352. case ERF_TYPE_COLOR_ETH:
  353. case ERF_TYPE_DSM_COLOR_HDLC_POS:
  354. case ERF_TYPE_DSM_COLOR_ETH:
  355. case ERF_TYPE_COLOR_MC_HDLC_POS:
  356. case ERF_TYPE_COLOR_HASH_ETH:
  357. case ERF_TYPE_COLOR_HASH_POS:
  358. break;
  359. default:
  360. if ( (pd->drop_attr == kNullAttributeUuid) && (header->lctr) ) {
  361. pd->stat.ps_drop += ntohs(header->lctr);
  362. }
  363. }
  364. if ((header->type & 0x7f) == ERF_TYPE_PAD) {
  365. continue;
  366. }
  367. num_ext_hdr = dag_erf_ext_header_count(dp, rlen);
  368. /* ERF encapsulation */
  369. /* The Extensible Record Format is not dropped for this kind of encapsulation,
  370. * and will be handled as a pseudo header by the decoding application.
  371. * The information carried in the ERF header and in the optional subheader (if present)
  372. * could be merged with the libpcap information, to offer a better decoding.
  373. * The packet length is
  374. * o the length of the packet on the link (header->wlen),
  375. * o plus the length of the ERF header (dag_record_size), as the length of the
  376. * pseudo header will be adjusted during the decoding,
  377. * o plus the length of the optional subheader (if present).
  378. *
  379. * The capture length is header.rlen and the byte stuffing for alignment will be dropped
  380. * if the capture length is greater than the packet length.
  381. */
  382. if (p->linktype == DLT_ERF) {
  383. packet_len = ntohs(header->wlen) + dag_record_size;
  384. caplen = rlen;
  385. switch ((header->type & 0x7f)) {
  386. case ERF_TYPE_MC_AAL5:
  387. case ERF_TYPE_MC_ATM:
  388. case ERF_TYPE_MC_HDLC:
  389. case ERF_TYPE_MC_RAW_CHANNEL:
  390. case ERF_TYPE_MC_RAW:
  391. case ERF_TYPE_MC_AAL2:
  392. case ERF_TYPE_COLOR_MC_HDLC_POS:
  393. packet_len += 4; /* MC header */
  394. break;
  395. case ERF_TYPE_COLOR_HASH_ETH:
  396. case ERF_TYPE_DSM_COLOR_ETH:
  397. case ERF_TYPE_COLOR_ETH:
  398. case ERF_TYPE_ETH:
  399. packet_len += 2; /* ETH header */
  400. break;
  401. } /* switch type */
  402. /* Include ERF extension headers */
  403. packet_len += (8 * num_ext_hdr);
  404. if (caplen > packet_len) {
  405. caplen = packet_len;
  406. }
  407. } else {
  408. /* Other kind of encapsulation according to the header Type */
  409. /* Skip over generic ERF header */
  410. dp += dag_record_size;
  411. /* Skip over extension headers */
  412. dp += 8 * num_ext_hdr;
  413. switch((header->type & 0x7f)) {
  414. case ERF_TYPE_ATM:
  415. case ERF_TYPE_AAL5:
  416. if ((header->type & 0x7f) == ERF_TYPE_AAL5) {
  417. packet_len = ntohs(header->wlen);
  418. caplen = rlen - dag_record_size;
  419. }
  420. case ERF_TYPE_MC_ATM:
  421. if ((header->type & 0x7f) == ERF_TYPE_MC_ATM) {
  422. caplen = packet_len = ATM_CELL_SIZE;
  423. dp+=4;
  424. }
  425. case ERF_TYPE_MC_AAL5:
  426. if ((header->type & 0x7f) == ERF_TYPE_MC_AAL5) {
  427. packet_len = ntohs(header->wlen);
  428. caplen = rlen - dag_record_size - 4;
  429. dp+=4;
  430. }
  431. /* Skip over extension headers */
  432. caplen -= (8 * num_ext_hdr);
  433. if ((header->type & 0x7f) == ERF_TYPE_ATM) {
  434. caplen = packet_len = ATM_CELL_SIZE;
  435. }
  436. if (p->linktype == DLT_SUNATM) {
  437. struct sunatm_hdr *sunatm = (struct sunatm_hdr *)dp;
  438. unsigned long rawatm;
  439. rawatm = ntohl(*((unsigned long *)dp));
  440. sunatm->vci = htons((rawatm >> 4) & 0xffff);
  441. sunatm->vpi = (rawatm >> 20) & 0x00ff;
  442. sunatm->flags = ((header->flags.iface & 1) ? 0x80 : 0x00) |
  443. ((sunatm->vpi == 0 && sunatm->vci == htons(5)) ? 6 :
  444. ((sunatm->vpi == 0 && sunatm->vci == htons(16)) ? 5 :
  445. ((dp[ATM_HDR_SIZE] == 0xaa &&
  446. dp[ATM_HDR_SIZE+1] == 0xaa &&
  447. dp[ATM_HDR_SIZE+2] == 0x03) ? 2 : 1)));
  448. } else if (p->linktype == DLT_ATM_RFC1483) {
  449. packet_len -= ATM_HDR_SIZE;
  450. caplen -= ATM_HDR_SIZE;
  451. dp += ATM_HDR_SIZE;
  452. } else
  453. continue;
  454. break;
  455. case ERF_TYPE_COLOR_HASH_ETH:
  456. case ERF_TYPE_DSM_COLOR_ETH:
  457. case ERF_TYPE_COLOR_ETH:
  458. case ERF_TYPE_ETH:
  459. if ((p->linktype != DLT_EN10MB) &&
  460. (p->linktype != DLT_DOCSIS))
  461. continue;
  462. packet_len = ntohs(header->wlen);
  463. packet_len -= (pd->dag_fcs_bits >> 3);
  464. caplen = rlen - dag_record_size - 2;
  465. /* Skip over extension headers */
  466. caplen -= (8 * num_ext_hdr);
  467. if (caplen > packet_len) {
  468. caplen = packet_len;
  469. }
  470. dp += 2;
  471. break;
  472. case ERF_TYPE_COLOR_HASH_POS:
  473. case ERF_TYPE_DSM_COLOR_HDLC_POS:
  474. case ERF_TYPE_COLOR_HDLC_POS:
  475. case ERF_TYPE_HDLC_POS:
  476. if ((p->linktype != DLT_CHDLC) &&
  477. (p->linktype != DLT_PPP_SERIAL) &&
  478. (p->linktype != DLT_FRELAY))
  479. continue;
  480. packet_len = ntohs(header->wlen);
  481. packet_len -= (pd->dag_fcs_bits >> 3);
  482. caplen = rlen - dag_record_size;
  483. /* Skip over extension headers */
  484. caplen -= (8 * num_ext_hdr);
  485. if (caplen > packet_len) {
  486. caplen = packet_len;
  487. }
  488. break;
  489. case ERF_TYPE_COLOR_MC_HDLC_POS:
  490. case ERF_TYPE_MC_HDLC:
  491. if ((p->linktype != DLT_CHDLC) &&
  492. (p->linktype != DLT_PPP_SERIAL) &&
  493. (p->linktype != DLT_FRELAY) &&
  494. (p->linktype != DLT_MTP2) &&
  495. (p->linktype != DLT_MTP2_WITH_PHDR) &&
  496. (p->linktype != DLT_LAPD))
  497. continue;
  498. packet_len = ntohs(header->wlen);
  499. packet_len -= (pd->dag_fcs_bits >> 3);
  500. caplen = rlen - dag_record_size - 4;
  501. /* Skip over extension headers */
  502. caplen -= (8 * num_ext_hdr);
  503. if (caplen > packet_len) {
  504. caplen = packet_len;
  505. }
  506. /* jump the MC_HDLC_HEADER */
  507. dp += 4;
  508. #ifdef DLT_MTP2_WITH_PHDR
  509. if (p->linktype == DLT_MTP2_WITH_PHDR) {
  510. /* Add the MTP2 Pseudo Header */
  511. caplen += MTP2_HDR_LEN;
  512. packet_len += MTP2_HDR_LEN;
  513. TempPkt[MTP2_SENT_OFFSET] = 0;
  514. TempPkt[MTP2_ANNEX_A_USED_OFFSET] = MTP2_ANNEX_A_USED_UNKNOWN;
  515. *(TempPkt+MTP2_LINK_NUMBER_OFFSET) = ((header->rec.mc_hdlc.mc_header>>16)&0x01);
  516. *(TempPkt+MTP2_LINK_NUMBER_OFFSET+1) = ((header->rec.mc_hdlc.mc_header>>24)&0xff);
  517. memcpy(TempPkt+MTP2_HDR_LEN, dp, caplen);
  518. dp = TempPkt;
  519. }
  520. #endif
  521. break;
  522. case ERF_TYPE_IPV4:
  523. if ((p->linktype != DLT_RAW) &&
  524. (p->linktype != DLT_IPV4))
  525. continue;
  526. packet_len = ntohs(header->wlen);
  527. caplen = rlen - dag_record_size;
  528. /* Skip over extension headers */
  529. caplen -= (8 * num_ext_hdr);
  530. if (caplen > packet_len) {
  531. caplen = packet_len;
  532. }
  533. break;
  534. case ERF_TYPE_IPV6:
  535. if ((p->linktype != DLT_RAW) &&
  536. (p->linktype != DLT_IPV6))
  537. continue;
  538. packet_len = ntohs(header->wlen);
  539. caplen = rlen - dag_record_size;
  540. /* Skip over extension headers */
  541. caplen -= (8 * num_ext_hdr);
  542. if (caplen > packet_len) {
  543. caplen = packet_len;
  544. }
  545. break;
  546. /* These types have no matching 'native' DLT, but can be used with DLT_ERF above */
  547. case ERF_TYPE_MC_RAW:
  548. case ERF_TYPE_MC_RAW_CHANNEL:
  549. case ERF_TYPE_IP_COUNTER:
  550. case ERF_TYPE_TCP_FLOW_COUNTER:
  551. case ERF_TYPE_INFINIBAND:
  552. case ERF_TYPE_RAW_LINK:
  553. case ERF_TYPE_INFINIBAND_LINK:
  554. default:
  555. /* Unhandled ERF type.
  556. * Ignore rather than generating error
  557. */
  558. continue;
  559. } /* switch type */
  560. } /* ERF encapsulation */
  561. if (caplen > p->snapshot)
  562. caplen = p->snapshot;
  563. /* Run the packet filter if there is one. */
  564. if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) {
  565. /* convert between timestamp formats */
  566. register unsigned long long ts;
  567. if (IS_BIGENDIAN()) {
  568. ts = SWAPLL(header->ts);
  569. } else {
  570. ts = header->ts;
  571. }
  572. switch (p->opt.tstamp_precision) {
  573. case PCAP_TSTAMP_PRECISION_NANO:
  574. ticks_per_second = 1000000000;
  575. break;
  576. case PCAP_TSTAMP_PRECISION_MICRO:
  577. default:
  578. ticks_per_second = 1000000;
  579. break;
  580. }
  581. pcap_header.ts.tv_sec = ts >> 32;
  582. ts = (ts & 0xffffffffULL) * ticks_per_second;
  583. ts += 0x80000000; /* rounding */
  584. pcap_header.ts.tv_usec = ts >> 32;
  585. if (pcap_header.ts.tv_usec >= ticks_per_second) {
  586. pcap_header.ts.tv_usec -= ticks_per_second;
  587. pcap_header.ts.tv_sec++;
  588. }
  589. /* Fill in our own header data */
  590. pcap_header.caplen = caplen;
  591. pcap_header.len = packet_len;
  592. /* Count the packet. */
  593. pd->stat.ps_recv++;
  594. /* Call the user supplied callback function */
  595. callback(user, &pcap_header, dp);
  596. /* Only count packets that pass the filter, for consistency with standard Linux behaviour. */
  597. processed++;
  598. if (processed == cnt && !PACKET_COUNT_IS_UNLIMITED(cnt))
  599. {
  600. /* Reached the user-specified limit. */
  601. return cnt;
  602. }
  603. }
  604. }
  605. return processed;
  606. }
  607. static int
  608. dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
  609. {
  610. strlcpy(p->errbuf, "Sending packets isn't supported on DAG cards",
  611. PCAP_ERRBUF_SIZE);
  612. return (-1);
  613. }
  614. /*
  615. * Get a handle for a live capture from the given DAG device. Passing a NULL
  616. * device will result in a failure. The promisc flag is ignored because DAG
  617. * cards are always promiscuous. The to_ms parameter is used in setting the
  618. * API polling parameters.
  619. *
  620. * snaplen is now also ignored, until we get per-stream slen support. Set
  621. * slen with approprite DAG tool BEFORE pcap_activate().
  622. *
  623. * See also pcap(3).
  624. */
  625. static int dag_activate(pcap_t* p)
  626. {
  627. struct pcap_dag *pd = p->priv;
  628. char *s;
  629. int n;
  630. daginf_t* daginf;
  631. char * newDev = NULL;
  632. char * device = p->opt.device;
  633. dag_size_t mindata;
  634. struct timeval maxwait;
  635. struct timeval poll;
  636. if (device == NULL) {
  637. pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "device is NULL");
  638. return -1;
  639. }
  640. /* Initialize some components of the pcap structure. */
  641. newDev = (char *)malloc(strlen(device) + 16);
  642. if (newDev == NULL) {
  643. pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
  644. errno, "Can't allocate string for device name");
  645. goto fail;
  646. }
  647. /* Parse input name to get dag device and stream number if provided */
  648. if (dag_parse_name(device, newDev, strlen(device) + 16, &pd->dag_stream) < 0) {
  649. pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
  650. errno, "dag_parse_name");
  651. goto fail;
  652. }
  653. device = newDev;
  654. if (pd->dag_stream%2) {
  655. pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture");
  656. goto fail;
  657. }
  658. /* setup device parameters */
  659. if((pd->dag_ref = dag_config_init((char *)device)) == NULL) {
  660. pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
  661. errno, "dag_config_init %s", device);
  662. goto fail;
  663. }
  664. if((p->fd = dag_config_get_card_fd(pd->dag_ref)) < 0) {
  665. pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
  666. errno, "dag_config_get_card_fd %s", device);
  667. goto fail;
  668. }
  669. /* Open requested stream. Can fail if already locked or on error */
  670. if (dag_attach_stream64(p->fd, pd->dag_stream, 0, 0) < 0) {
  671. pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
  672. errno, "dag_attach_stream");
  673. goto failclose;
  674. }
  675. /* Try to find Stream Drop attribute */
  676. pd->drop_attr = kNullAttributeUuid;
  677. pd->dag_root = dag_config_get_root_component(pd->dag_ref);
  678. if ( dag_component_get_subcomponent(pd->dag_root, kComponentStreamFeatures, 0) )
  679. {
  680. pd->drop_attr = dag_config_get_indexed_attribute_uuid(pd->dag_ref, kUint32AttributeStreamDropCount, pd->dag_stream/2);
  681. }
  682. /* Set up default poll parameters for stream
  683. * Can be overridden by pcap_set_nonblock()
  684. */
  685. if (dag_get_stream_poll64(p->fd, pd->dag_stream,
  686. &mindata, &maxwait, &poll) < 0) {
  687. pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
  688. errno, "dag_get_stream_poll");
  689. goto faildetach;
  690. }
  691. /* Use the poll time as the required select timeout for callers
  692. * who are using select()/etc. in an event loop waiting for
  693. * packets to arrive.
  694. */
  695. pd->required_select_timeout = poll;
  696. p->required_select_timeout = &pd->required_select_timeout;
  697. /*
  698. * Turn a negative snapshot value (invalid), a snapshot value of
  699. * 0 (unspecified), or a value bigger than the normal maximum
  700. * value, into the maximum allowed value.
  701. *
  702. * If some application really *needs* a bigger snapshot
  703. * length, we should just increase MAXIMUM_SNAPLEN.
  704. */
  705. if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
  706. p->snapshot = MAXIMUM_SNAPLEN;
  707. if (p->opt.immediate) {
  708. /* Call callback immediately.
  709. * XXX - is this the right way to p this?
  710. */
  711. mindata = 0;
  712. } else {
  713. /* Amount of data to collect in Bytes before calling callbacks.
  714. * Important for efficiency, but can introduce latency
  715. * at low packet rates if to_ms not set!
  716. */
  717. mindata = 65536;
  718. }
  719. /* Obey opt.timeout (was to_ms) if supplied. This is a good idea!
  720. * Recommend 10-100ms. Calls will time out even if no data arrived.
  721. */
  722. maxwait.tv_sec = p->opt.timeout/1000;
  723. maxwait.tv_usec = (p->opt.timeout%1000) * 1000;
  724. if (dag_set_stream_poll64(p->fd, pd->dag_stream,
  725. mindata, &maxwait, &poll) < 0) {
  726. pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
  727. errno, "dag_set_stream_poll");
  728. goto faildetach;
  729. }
  730. /* XXX Not calling dag_configure() to set slen; this is unsafe in
  731. * multi-stream environments as the gpp config is global.
  732. * Once the firmware provides 'per-stream slen' this can be supported
  733. * again via the Config API without side-effects */
  734. #if 0
  735. /* set the card snap length to the specified snaplen parameter */
  736. /* This is a really bad idea, as different cards have different
  737. * valid slen ranges. Should fix in Config API. */
  738. if (p->snapshot == 0 || p->snapshot > MAX_DAG_SNAPLEN) {
  739. p->snapshot = MAX_DAG_SNAPLEN;
  740. } else if (snaplen < MIN_DAG_SNAPLEN) {
  741. p->snapshot = MIN_DAG_SNAPLEN;
  742. }
  743. /* snap len has to be a multiple of 4 */
  744. #endif
  745. if(dag_start_stream(p->fd, pd->dag_stream) < 0) {
  746. pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
  747. errno, "dag_start_stream %s", device);
  748. goto faildetach;
  749. }
  750. /*
  751. * Important! You have to ensure bottom is properly
  752. * initialized to zero on startup, it won't give you
  753. * a compiler warning if you make this mistake!
  754. */
  755. pd->dag_mem_bottom = 0;
  756. pd->dag_mem_top = 0;
  757. /*
  758. * Find out how many FCS bits we should strip.
  759. * First, query the card to see if it strips the FCS.
  760. */
  761. daginf = dag_info(p->fd);
  762. if ((0x4200 == daginf->device_code) || (0x4230 == daginf->device_code)) {
  763. /* DAG 4.2S and 4.23S already strip the FCS. Stripping the final word again truncates the packet. */
  764. pd->dag_fcs_bits = 0;
  765. /* Note that no FCS will be supplied. */
  766. p->linktype_ext = LT_FCS_DATALINK_EXT(0);
  767. } else {
  768. /*
  769. * Start out assuming it's 32 bits.
  770. */
  771. pd->dag_fcs_bits = 32;
  772. /* Allow an environment variable to override. */
  773. if ((s = getenv("ERF_FCS_BITS")) != NULL) {
  774. if ((n = atoi(s)) == 0 || n == 16 || n == 32) {
  775. pd->dag_fcs_bits = n;
  776. } else {
  777. pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
  778. "pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment", device, n);
  779. goto failstop;
  780. }
  781. }
  782. /*
  783. * Did the user request that they not be stripped?
  784. */
  785. if ((s = getenv("ERF_DONT_STRIP_FCS")) != NULL) {
  786. /* Yes. Note the number of bytes that will be
  787. supplied. */
  788. p->linktype_ext = LT_FCS_DATALINK_EXT(pd->dag_fcs_bits/16);
  789. /* And don't strip them. */
  790. pd->dag_fcs_bits = 0;
  791. }
  792. }
  793. pd->dag_timeout = p->opt.timeout;
  794. p->linktype = -1;
  795. if (dag_get_datalink(p) < 0)
  796. goto failstop;
  797. p->bufsize = 0;
  798. if (new_pcap_dag(p) < 0) {
  799. pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
  800. errno, "new_pcap_dag %s", device);
  801. goto failstop;
  802. }
  803. /*
  804. * "select()" and "poll()" don't work on DAG device descriptors.
  805. */
  806. p->selectable_fd = -1;
  807. if (newDev != NULL) {
  808. free((char *)newDev);
  809. }
  810. p->read_op = dag_read;
  811. p->inject_op = dag_inject;
  812. p->setfilter_op = dag_setfilter;
  813. p->setdirection_op = NULL; /* Not implemented.*/
  814. p->set_datalink_op = dag_set_datalink;
  815. p->getnonblock_op = pcap_getnonblock_fd;
  816. p->setnonblock_op = dag_setnonblock;
  817. p->stats_op = dag_stats;
  818. p->cleanup_op = dag_platform_cleanup;
  819. pd->stat.ps_drop = 0;
  820. pd->stat.ps_recv = 0;
  821. pd->stat.ps_ifdrop = 0;
  822. return 0;
  823. failstop:
  824. if (dag_stop_stream(p->fd, pd->dag_stream) < 0) {
  825. fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
  826. }
  827. faildetach:
  828. if (dag_detach_stream(p->fd, pd->dag_stream) < 0)
  829. fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
  830. failclose:
  831. dag_config_dispose(pd->dag_ref);
  832. delete_pcap_dag(p);
  833. fail:
  834. pcap_cleanup_live_common(p);
  835. if (newDev != NULL) {
  836. free((char *)newDev);
  837. }
  838. return PCAP_ERROR;
  839. }
  840. pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
  841. {
  842. const char *cp;
  843. char *cpend;
  844. long devnum;
  845. pcap_t *p;
  846. long stream = 0;
  847. /* Does this look like a DAG device? */
  848. cp = strrchr(device, '/');
  849. if (cp == NULL)
  850. cp = device;
  851. /* Does it begin with "dag"? */
  852. if (strncmp(cp, "dag", 3) != 0) {
  853. /* Nope, doesn't begin with "dag" */
  854. *is_ours = 0;
  855. return NULL;
  856. }
  857. /* Yes - is "dag" followed by a number from 0 to DAG_MAX_BOARDS-1 */
  858. cp += 3;
  859. devnum = strtol(cp, &cpend, 10);
  860. if (*cpend == ':') {
  861. /* Followed by a stream number. */
  862. stream = strtol(++cpend, &cpend, 10);
  863. }
  864. if (cpend == cp || *cpend != '\0') {
  865. /* Not followed by a number. */
  866. *is_ours = 0;
  867. return NULL;
  868. }
  869. if (devnum < 0 || devnum >= DAG_MAX_BOARDS) {
  870. /* Followed by a non-valid number. */
  871. *is_ours = 0;
  872. return NULL;
  873. }
  874. if (stream <0 || stream >= DAG_STREAM_MAX) {
  875. /* Followed by a non-valid stream number. */
  876. *is_ours = 0;
  877. return NULL;
  878. }
  879. /* OK, it's probably ours. */
  880. *is_ours = 1;
  881. p = pcap_create_common(ebuf, sizeof (struct pcap_dag));
  882. if (p == NULL)
  883. return NULL;
  884. p->activate_op = dag_activate;
  885. /*
  886. * We claim that we support microsecond and nanosecond time
  887. * stamps.
  888. *
  889. * XXX Our native precision is 2^-32s, but libpcap doesn't support
  890. * power of two precisions yet. We can convert to either MICRO or NANO.
  891. */
  892. p->tstamp_precision_count = 2;
  893. p->tstamp_precision_list = malloc(2 * sizeof(u_int));
  894. if (p->tstamp_precision_list == NULL) {
  895. pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
  896. errno, "malloc");
  897. pcap_close(p);
  898. return NULL;
  899. }
  900. p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO;
  901. p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO;
  902. return p;
  903. }
  904. static int
  905. dag_stats(pcap_t *p, struct pcap_stat *ps) {
  906. struct pcap_dag *pd = p->priv;
  907. uint32_t stream_drop;
  908. dag_err_t dag_error;
  909. /*
  910. * Packet records received (ps_recv) are counted in dag_read().
  911. * Packet records dropped (ps_drop) are read from Stream Drop attribute if present,
  912. * otherwise integrate the ERF Header lctr counts (if available) in dag_read().
  913. * We are reporting that no records are dropped by the card/driver (ps_ifdrop).
  914. */
  915. if(pd->drop_attr != kNullAttributeUuid) {
  916. /* Note this counter is cleared at start of capture and will wrap at UINT_MAX.
  917. * The application is responsible for polling ps_drop frequently enough
  918. * to detect each wrap and integrate total drop with a wider counter */
  919. if ((dag_error = dag_config_get_uint32_attribute_ex(pd->dag_ref, pd->drop_attr, &stream_drop) == kDagErrNone)) {
  920. pd->stat.ps_drop = stream_drop;
  921. } else {
  922. pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "reading stream drop attribute: %s",
  923. dag_config_strerror(dag_error));
  924. return -1;
  925. }
  926. }
  927. *ps = pd->stat;
  928. return 0;
  929. }
  930. /*
  931. * Add all DAG devices.
  932. */
  933. int
  934. dag_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
  935. {
  936. char name[12]; /* XXX - pick a size */
  937. int c;
  938. char dagname[DAGNAME_BUFSIZE];
  939. int dagstream;
  940. int dagfd;
  941. dag_card_inf_t *inf;
  942. char *description;
  943. int stream, rxstreams;
  944. /* Try all the DAGs 0-DAG_MAX_BOARDS */
  945. for (c = 0; c < DAG_MAX_BOARDS; c++) {
  946. pcap_snprintf(name, 12, "dag%d", c);
  947. if (-1 == dag_parse_name(name, dagname, DAGNAME_BUFSIZE, &dagstream))
  948. {
  949. (void) pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
  950. "dag: device name %s can't be parsed", name);
  951. return (-1);
  952. }
  953. if ( (dagfd = dag_open(dagname)) >= 0 ) {
  954. description = NULL;
  955. if ((inf = dag_pciinfo(dagfd)))
  956. description = dag_device_name(inf->device_code, 1);
  957. /*
  958. * XXX - is there a way to determine whether
  959. * the card is plugged into a network or not?
  960. * If so, we should check that and set
  961. * PCAP_IF_CONNECTION_STATUS_CONNECTED or
  962. * PCAP_IF_CONNECTION_STATUS_DISCONNECTED.
  963. *
  964. * Also, are there notions of "up" and "running"?
  965. */
  966. if (add_dev(devlistp, name, 0, description, errbuf) == NULL) {
  967. /*
  968. * Failure.
  969. */
  970. return (-1);
  971. }
  972. rxstreams = dag_rx_get_stream_count(dagfd);
  973. for(stream=0;stream<DAG_STREAM_MAX;stream+=2) {
  974. if (0 == dag_attach_stream(dagfd, stream, 0, 0)) {
  975. dag_detach_stream(dagfd, stream);
  976. pcap_snprintf(name, 10, "dag%d:%d", c, stream);
  977. if (add_dev(devlistp, name, 0, description, errbuf) == NULL) {
  978. /*
  979. * Failure.
  980. */
  981. return (-1);
  982. }
  983. rxstreams--;
  984. if(rxstreams <= 0) {
  985. break;
  986. }
  987. }
  988. }
  989. dag_close(dagfd);
  990. }
  991. }
  992. return (0);
  993. }
  994. /*
  995. * Installs the given bpf filter program in the given pcap structure. There is
  996. * no attempt to store the filter in kernel memory as that is not supported
  997. * with DAG cards.
  998. */
  999. static int
  1000. dag_setfilter(pcap_t *p, struct bpf_program *fp)
  1001. {
  1002. if (!p)
  1003. return -1;
  1004. if (!fp) {
  1005. strncpy(p->errbuf, "setfilter: No filter specified",
  1006. sizeof(p->errbuf));
  1007. return -1;
  1008. }
  1009. /* Make our private copy of the filter */
  1010. if (install_bpf_program(p, fp) < 0)
  1011. return -1;
  1012. return (0);
  1013. }
  1014. static int
  1015. dag_set_datalink(pcap_t *p, int dlt)
  1016. {
  1017. p->linktype = dlt;
  1018. return (0);
  1019. }
  1020. static int
  1021. dag_setnonblock(pcap_t *p, int nonblock)
  1022. {
  1023. struct pcap_dag *pd = p->priv;
  1024. dag_size_t mindata;
  1025. struct timeval maxwait;
  1026. struct timeval poll;
  1027. /*
  1028. * Set non-blocking mode on the FD.
  1029. * XXX - is that necessary? If not, don't bother calling it,
  1030. * and have a "dag_getnonblock()" function that looks at
  1031. * "pd->dag_flags".
  1032. */
  1033. if (pcap_setnonblock_fd(p, nonblock) < 0)
  1034. return (-1);
  1035. if (dag_get_stream_poll64(p->fd, pd->dag_stream,
  1036. &mindata, &maxwait, &poll) < 0) {
  1037. pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
  1038. errno, "dag_get_stream_poll");
  1039. return -1;
  1040. }
  1041. /* Amount of data to collect in Bytes before calling callbacks.
  1042. * Important for efficiency, but can introduce latency
  1043. * at low packet rates if to_ms not set!
  1044. */
  1045. if(nonblock)
  1046. mindata = 0;
  1047. else
  1048. mindata = 65536;
  1049. if (dag_set_stream_poll64(p->fd, pd->dag_stream,
  1050. mindata, &maxwait, &poll) < 0) {
  1051. pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
  1052. errno, "dag_set_stream_poll");
  1053. return -1;
  1054. }
  1055. if (nonblock) {
  1056. pd->dag_flags |= DAGF_NONBLOCK;
  1057. } else {
  1058. pd->dag_flags &= ~DAGF_NONBLOCK;
  1059. }
  1060. return (0);
  1061. }
  1062. static int
  1063. dag_get_datalink(pcap_t *p)
  1064. {
  1065. struct pcap_dag *pd = p->priv;
  1066. int index=0, dlt_index=0;
  1067. uint8_t types[255];
  1068. memset(types, 0, 255);
  1069. if (p->dlt_list == NULL && (p->dlt_list = malloc(255*sizeof(*(p->dlt_list)))) == NULL) {
  1070. pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
  1071. errno, "malloc");
  1072. return (-1);
  1073. }
  1074. p->linktype = 0;
  1075. #ifdef HAVE_DAG_GET_STREAM_ERF_TYPES
  1076. /* Get list of possible ERF types for this card */
  1077. if (dag_get_stream_erf_types(p->fd, pd->dag_stream, types, 255) < 0) {
  1078. pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
  1079. errno, "dag_get_stream_erf_types");
  1080. return (-1);
  1081. }
  1082. while (types[index]) {
  1083. #elif defined HAVE_DAG_GET_ERF_TYPES
  1084. /* Get list of possible ERF types for this card */
  1085. if (dag_get_erf_types(p->fd, types, 255) < 0) {
  1086. pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
  1087. errno, "dag_get_erf_types");
  1088. return (-1);
  1089. }
  1090. while (types[index]) {
  1091. #else
  1092. /* Check the type through a dagapi call. */
  1093. types[index] = dag_linktype(p->fd);
  1094. {
  1095. #endif
  1096. switch((types[index] & 0x7f)) {
  1097. case ERF_TYPE_HDLC_POS:
  1098. case ERF_TYPE_COLOR_HDLC_POS:
  1099. case ERF_TYPE_DSM_COLOR_HDLC_POS:
  1100. case ERF_TYPE_COLOR_HASH_POS:
  1101. if (p->dlt_list != NULL) {
  1102. p->dlt_list[dlt_index++] = DLT_CHDLC;
  1103. p->dlt_list[dlt_index++] = DLT_PPP_SERIAL;
  1104. p->dlt_list[dlt_index++] = DLT_FRELAY;
  1105. }
  1106. if(!p->linktype)
  1107. p->linktype = DLT_CHDLC;
  1108. break;
  1109. case ERF_TYPE_ETH:
  1110. case ERF_TYPE_COLOR_ETH:
  1111. case ERF_TYPE_DSM_COLOR_ETH:
  1112. case ERF_TYPE_COLOR_HASH_ETH:
  1113. /*
  1114. * This is (presumably) a real Ethernet capture; give it a
  1115. * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
  1116. * that an application can let you choose it, in case you're
  1117. * capturing DOCSIS traffic that a Cisco Cable Modem
  1118. * Termination System is putting out onto an Ethernet (it
  1119. * doesn't put an Ethernet header onto the wire, it puts raw
  1120. * DOCSIS frames out on the wire inside the low-level
  1121. * Ethernet framing).
  1122. */
  1123. if (p->dlt_list != NULL) {
  1124. p->dlt_list[dlt_index++] = DLT_EN10MB;
  1125. p->dlt_list[dlt_index++] = DLT_DOCSIS;
  1126. }
  1127. if(!p->linktype)
  1128. p->linktype = DLT_EN10MB;
  1129. break;
  1130. case ERF_TYPE_ATM:
  1131. case ERF_TYPE_AAL5:
  1132. case ERF_TYPE_MC_ATM:
  1133. case ERF_TYPE_MC_AAL5:
  1134. if (p->dlt_list != NULL) {
  1135. p->dlt_list[dlt_index++] = DLT_ATM_RFC1483;
  1136. p->dlt_list[dlt_index++] = DLT_SUNATM;
  1137. }
  1138. if(!p->linktype)
  1139. p->linktype = DLT_ATM_RFC1483;
  1140. break;
  1141. case ERF_TYPE_COLOR_MC_HDLC_POS:
  1142. case ERF_TYPE_MC_HDLC:
  1143. if (p->dlt_list != NULL) {
  1144. p->dlt_list[dlt_index++] = DLT_CHDLC;
  1145. p->dlt_list[dlt_index++] = DLT_PPP_SERIAL;
  1146. p->dlt_list[dlt_index++] = DLT_FRELAY;
  1147. p->dlt_list[dlt_index++] = DLT_MTP2;
  1148. p->dlt_list[dlt_index++] = DLT_MTP2_WITH_PHDR;
  1149. p->dlt_list[dlt_index++] = DLT_LAPD;
  1150. }
  1151. if(!p->linktype)
  1152. p->linktype = DLT_CHDLC;
  1153. break;
  1154. case ERF_TYPE_IPV4:
  1155. if (p->dlt_list != NULL) {
  1156. p->dlt_list[dlt_index++] = DLT_RAW;
  1157. p->dlt_list[dlt_index++] = DLT_IPV4;
  1158. }
  1159. if(!p->linktype)
  1160. p->linktype = DLT_RAW;
  1161. break;
  1162. case ERF_TYPE_IPV6:
  1163. if (p->dlt_list != NULL) {
  1164. p->dlt_list[dlt_index++] = DLT_RAW;
  1165. p->dlt_list[dlt_index++] = DLT_IPV6;
  1166. }
  1167. if(!p->linktype)
  1168. p->linktype = DLT_RAW;
  1169. break;
  1170. case ERF_TYPE_LEGACY:
  1171. case ERF_TYPE_MC_RAW:
  1172. case ERF_TYPE_MC_RAW_CHANNEL:
  1173. case ERF_TYPE_IP_COUNTER:
  1174. case ERF_TYPE_TCP_FLOW_COUNTER:
  1175. case ERF_TYPE_INFINIBAND:
  1176. case ERF_TYPE_RAW_LINK:
  1177. case ERF_TYPE_INFINIBAND_LINK:
  1178. case ERF_TYPE_META:
  1179. default:
  1180. /* Libpcap cannot deal with these types yet */
  1181. /* Add no 'native' DLTs, but still covered by DLT_ERF */
  1182. break;
  1183. } /* switch */
  1184. index++;
  1185. }
  1186. p->dlt_list[dlt_index++] = DLT_ERF;
  1187. p->dlt_count = dlt_index;
  1188. if(!p->linktype)
  1189. p->linktype = DLT_ERF;
  1190. return p->linktype;
  1191. }
  1192. #ifdef DAG_ONLY
  1193. /*
  1194. * This libpcap build supports only DAG cards, not regular network
  1195. * interfaces.
  1196. */
  1197. /*
  1198. * There are no regular interfaces, just DAG interfaces.
  1199. */
  1200. int
  1201. pcap_platform_finddevs(pcap_if_list_t *devlistp _U_, char *errbuf)
  1202. {
  1203. return (0);
  1204. }
  1205. /*
  1206. * Attempts to open a regular interface fail.
  1207. */
  1208. pcap_t *
  1209. pcap_create_interface(const char *device, char *errbuf)
  1210. {
  1211. pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
  1212. "This version of libpcap only supports DAG cards");
  1213. return NULL;
  1214. }
  1215. /*
  1216. * Libpcap version string.
  1217. */
  1218. const char *
  1219. pcap_lib_version(void)
  1220. {
  1221. return (PCAP_VERSION_STRING " (DAG-only)");
  1222. }
  1223. #endif