pcap-dos.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536
  1. /*
  2. * This file is part of DOS-libpcap
  3. * Ported to DOS/DOSX by G. Vanem <gvanem@yahoo.no>
  4. *
  5. * pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode
  6. * network drivers.
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <signal.h>
  12. #include <float.h>
  13. #include <fcntl.h>
  14. #include <io.h>
  15. #if defined(USE_32BIT_DRIVERS)
  16. #include "msdos/pm_drvr/pmdrvr.h"
  17. #include "msdos/pm_drvr/pci.h"
  18. #include "msdos/pm_drvr/bios32.h"
  19. #include "msdos/pm_drvr/module.h"
  20. #include "msdos/pm_drvr/3c501.h"
  21. #include "msdos/pm_drvr/3c503.h"
  22. #include "msdos/pm_drvr/3c509.h"
  23. #include "msdos/pm_drvr/3c59x.h"
  24. #include "msdos/pm_drvr/3c515.h"
  25. #include "msdos/pm_drvr/3c90x.h"
  26. #include "msdos/pm_drvr/3c575_cb.h"
  27. #include "msdos/pm_drvr/ne.h"
  28. #include "msdos/pm_drvr/wd.h"
  29. #include "msdos/pm_drvr/accton.h"
  30. #include "msdos/pm_drvr/cs89x0.h"
  31. #include "msdos/pm_drvr/rtl8139.h"
  32. #include "msdos/pm_drvr/ne2k-pci.h"
  33. #endif
  34. #include "pcap.h"
  35. #include "pcap-dos.h"
  36. #include "pcap-int.h"
  37. #include "msdos/pktdrvr.h"
  38. #ifdef USE_NDIS2
  39. #include "msdos/ndis2.h"
  40. #endif
  41. #include <arpa/inet.h>
  42. #include <net/if.h>
  43. #include <net/if_arp.h>
  44. #include <net/if_ether.h>
  45. #include <net/if_packe.h>
  46. #include <tcp.h>
  47. #if defined(USE_32BIT_DRIVERS)
  48. #define FLUSHK() do { _printk_safe = 1; _printk_flush(); } while (0)
  49. #define NDIS_NEXT_DEV &rtl8139_dev
  50. static char *rx_pool = NULL;
  51. static void init_32bit (void);
  52. static int pktq_init (struct rx_ringbuf *q, int size, int num, char *pool);
  53. static int pktq_check (struct rx_ringbuf *q);
  54. static int pktq_inc_out (struct rx_ringbuf *q);
  55. static int pktq_in_index (struct rx_ringbuf *q) LOCKED_FUNC;
  56. static void pktq_clear (struct rx_ringbuf *q) LOCKED_FUNC;
  57. static struct rx_elem *pktq_in_elem (struct rx_ringbuf *q) LOCKED_FUNC;
  58. static struct rx_elem *pktq_out_elem (struct rx_ringbuf *q);
  59. #else
  60. #define FLUSHK() ((void)0)
  61. #define NDIS_NEXT_DEV NULL
  62. #endif
  63. /*
  64. * Internal variables/functions in Watt-32
  65. */
  66. extern WORD _pktdevclass;
  67. extern BOOL _eth_is_init;
  68. extern int _w32_dynamic_host;
  69. extern int _watt_do_exit;
  70. extern int _watt_is_init;
  71. extern int _w32__bootp_on, _w32__dhcp_on, _w32__rarp_on, _w32__do_mask_req;
  72. extern void (*_w32_usr_post_init) (void);
  73. extern void (*_w32_print_hook)();
  74. extern void dbug_write (const char *); /* Watt-32 lib, pcdbug.c */
  75. extern int pkt_get_mtu (void);
  76. static int ref_count = 0;
  77. static u_long mac_count = 0;
  78. static u_long filter_count = 0;
  79. static volatile BOOL exc_occured = 0;
  80. static struct device *handle_to_device [20];
  81. static int pcap_activate_dos (pcap_t *p);
  82. static int pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback,
  83. u_char *data);
  84. static void pcap_cleanup_dos (pcap_t *p);
  85. static int pcap_stats_dos (pcap_t *p, struct pcap_stat *ps);
  86. static int pcap_sendpacket_dos (pcap_t *p, const void *buf, size_t len);
  87. static int pcap_setfilter_dos (pcap_t *p, struct bpf_program *fp);
  88. static int ndis_probe (struct device *dev);
  89. static int pkt_probe (struct device *dev);
  90. static void close_driver (void);
  91. static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf);
  92. static int first_init (const char *name, char *ebuf, int promisc);
  93. static void watt32_recv_hook (u_char *dummy, const struct pcap_pkthdr *pcap,
  94. const u_char *buf);
  95. /*
  96. * These are the device we always support
  97. */
  98. static struct device ndis_dev = {
  99. "ndis",
  100. "NDIS2 LanManager",
  101. 0,
  102. 0,0,0,0,0,0,
  103. NDIS_NEXT_DEV, /* NULL or a 32-bit device */
  104. ndis_probe
  105. };
  106. static struct device pkt_dev = {
  107. "pkt",
  108. "Packet-Driver",
  109. 0,
  110. 0,0,0,0,0,0,
  111. &ndis_dev,
  112. pkt_probe
  113. };
  114. static struct device *get_device (int fd)
  115. {
  116. if (fd <= 0 || fd >= sizeof(handle_to_device)/sizeof(handle_to_device[0]))
  117. return (NULL);
  118. return handle_to_device [fd-1];
  119. }
  120. /*
  121. * Private data for capturing on MS-DOS.
  122. */
  123. struct pcap_dos {
  124. void (*wait_proc)(void); /* call proc while waiting */
  125. struct pcap_stat stat;
  126. };
  127. pcap_t *pcap_create_interface (const char *device _U_, char *ebuf)
  128. {
  129. pcap_t *p;
  130. p = pcap_create_common(ebuf, sizeof (struct pcap_dos));
  131. if (p == NULL)
  132. return (NULL);
  133. p->activate_op = pcap_activate_dos;
  134. return (p);
  135. }
  136. /*
  137. * Open MAC-driver with name 'device_name' for live capture of
  138. * network packets.
  139. */
  140. static int pcap_activate_dos (pcap_t *pcap)
  141. {
  142. if (pcap->opt.rfmon) {
  143. /*
  144. * No monitor mode on DOS.
  145. */
  146. return (PCAP_ERROR_RFMON_NOTSUP);
  147. }
  148. /*
  149. * Turn a negative snapshot value (invalid), a snapshot value of
  150. * 0 (unspecified), or a value bigger than the normal maximum
  151. * value, into the maximum allowed value.
  152. *
  153. * If some application really *needs* a bigger snapshot
  154. * length, we should just increase MAXIMUM_SNAPLEN.
  155. */
  156. if (pcap->snapshot <= 0 || pcap->snapshot > MAXIMUM_SNAPLEN)
  157. pcap->snapshot = MAXIMUM_SNAPLEN;
  158. if (pcap->snapshot < ETH_MIN+8)
  159. pcap->snapshot = ETH_MIN+8;
  160. if (pcap->snapshot > ETH_MAX) /* silently accept and truncate large MTUs */
  161. pcap->snapshot = ETH_MAX;
  162. pcap->linktype = DLT_EN10MB; /* !! */
  163. pcap->cleanup_op = pcap_cleanup_dos;
  164. pcap->read_op = pcap_read_dos;
  165. pcap->stats_op = pcap_stats_dos;
  166. pcap->inject_op = pcap_sendpacket_dos;
  167. pcap->setfilter_op = pcap_setfilter_dos;
  168. pcap->setdirection_op = NULL; /* Not implemented.*/
  169. pcap->fd = ++ref_count;
  170. pcap->bufsize = ETH_MAX+100; /* add some margin */
  171. pcap->buffer = calloc (pcap->bufsize, 1);
  172. if (pcap->fd == 1) /* first time we're called */
  173. {
  174. if (!init_watt32(pcap, pcap->opt.device, pcap->errbuf) ||
  175. !first_init(pcap->opt.device, pcap->errbuf, pcap->opt.promisc))
  176. {
  177. /* XXX - free pcap->buffer? */
  178. return (PCAP_ERROR);
  179. }
  180. atexit (close_driver);
  181. }
  182. else if (stricmp(active_dev->name,pcap->opt.device))
  183. {
  184. pcap_snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
  185. "Cannot use different devices simultaneously "
  186. "(`%s' vs. `%s')", active_dev->name, pcap->opt.device);
  187. /* XXX - free pcap->buffer? */
  188. return (PCAP_ERROR);
  189. }
  190. handle_to_device [pcap->fd-1] = active_dev;
  191. return (0);
  192. }
  193. /*
  194. * Poll the receiver queue and call the pcap callback-handler
  195. * with the packet.
  196. */
  197. static int
  198. pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
  199. {
  200. struct pcap_dos *pd = p->priv;
  201. struct pcap_pkthdr pcap;
  202. struct timeval now, expiry = { 0,0 };
  203. int rx_len = 0;
  204. if (p->opt.timeout > 0)
  205. {
  206. gettimeofday2 (&now, NULL);
  207. expiry.tv_usec = now.tv_usec + 1000UL * p->opt.timeout;
  208. expiry.tv_sec = now.tv_sec;
  209. while (expiry.tv_usec >= 1000000L)
  210. {
  211. expiry.tv_usec -= 1000000L;
  212. expiry.tv_sec++;
  213. }
  214. }
  215. while (!exc_occured)
  216. {
  217. volatile struct device *dev; /* might be reset by sig_handler */
  218. dev = get_device (p->fd);
  219. if (!dev)
  220. break;
  221. PCAP_ASSERT (dev->copy_rx_buf || dev->peek_rx_buf);
  222. FLUSHK();
  223. /* If driver has a zero-copy receive facility, peek at the queue,
  224. * filter it, do the callback and release the buffer.
  225. */
  226. if (dev->peek_rx_buf)
  227. {
  228. PCAP_ASSERT (dev->release_rx_buf);
  229. rx_len = (*dev->peek_rx_buf) (&p->buffer);
  230. }
  231. else
  232. {
  233. rx_len = (*dev->copy_rx_buf) (p->buffer, p->snapshot);
  234. }
  235. if (rx_len > 0) /* got a packet */
  236. {
  237. mac_count++;
  238. FLUSHK();
  239. pcap.caplen = min (rx_len, p->snapshot);
  240. pcap.len = rx_len;
  241. if (callback &&
  242. (!p->fcode.bf_insns || bpf_filter(p->fcode.bf_insns, p->buffer, pcap.len, pcap.caplen)))
  243. {
  244. filter_count++;
  245. /* Fix-me!! Should be time of arrival. Not time of
  246. * capture.
  247. */
  248. gettimeofday2 (&pcap.ts, NULL);
  249. (*callback) (data, &pcap, p->buffer);
  250. }
  251. if (dev->release_rx_buf)
  252. (*dev->release_rx_buf) (p->buffer);
  253. if (pcap_pkt_debug > 0)
  254. {
  255. if (callback == watt32_recv_hook)
  256. dbug_write ("pcap_recv_hook\n");
  257. else dbug_write ("pcap_read_op\n");
  258. }
  259. FLUSHK();
  260. return (1);
  261. }
  262. /* Has "pcap_breakloop()" been called?
  263. */
  264. if (p->break_loop) {
  265. /*
  266. * Yes - clear the flag that indicates that it
  267. * has, and return -2 to indicate that we were
  268. * told to break out of the loop.
  269. */
  270. p->break_loop = 0;
  271. return (-2);
  272. }
  273. /* If not to wait for a packet or pcap_cleanup_dos() called from
  274. * e.g. SIGINT handler, exit loop now.
  275. */
  276. if (p->opt.timeout <= 0 || (volatile int)p->fd <= 0)
  277. break;
  278. gettimeofday2 (&now, NULL);
  279. if (timercmp(&now, &expiry, >))
  280. break;
  281. #ifndef DJGPP
  282. kbhit(); /* a real CPU hog */
  283. #endif
  284. if (pd->wait_proc)
  285. (*pd->wait_proc)(); /* call yield func */
  286. }
  287. if (rx_len < 0) /* receive error */
  288. {
  289. pd->stat.ps_drop++;
  290. #ifdef USE_32BIT_DRIVERS
  291. if (pcap_pkt_debug > 1)
  292. printk ("pkt-err %s\n", pktInfo.error);
  293. #endif
  294. return (-1);
  295. }
  296. return (0);
  297. }
  298. static int
  299. pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback, u_char *data)
  300. {
  301. int rc, num = 0;
  302. while (num <= cnt || PACKET_COUNT_IS_UNLIMITED(cnt))
  303. {
  304. if (p->fd <= 0)
  305. return (-1);
  306. rc = pcap_read_one (p, callback, data);
  307. if (rc > 0)
  308. num++;
  309. if (rc < 0)
  310. break;
  311. _w32_os_yield(); /* allow SIGINT generation, yield to Win95/NT */
  312. }
  313. return (num);
  314. }
  315. /*
  316. * Return network statistics
  317. */
  318. static int pcap_stats_dos (pcap_t *p, struct pcap_stat *ps)
  319. {
  320. struct net_device_stats *stats;
  321. struct pcap_dos *pd;
  322. struct device *dev = p ? get_device(p->fd) : NULL;
  323. if (!dev)
  324. {
  325. strcpy (p->errbuf, "illegal pcap handle");
  326. return (-1);
  327. }
  328. if (!dev->get_stats || (stats = (*dev->get_stats)(dev)) == NULL)
  329. {
  330. strcpy (p->errbuf, "device statistics not available");
  331. return (-1);
  332. }
  333. FLUSHK();
  334. pd = p->priv;
  335. pd->stat.ps_recv = stats->rx_packets;
  336. pd->stat.ps_drop += stats->rx_missed_errors;
  337. pd->stat.ps_ifdrop = stats->rx_dropped + /* queue full */
  338. stats->rx_errors; /* HW errors */
  339. if (ps)
  340. *ps = pd->stat;
  341. return (0);
  342. }
  343. /*
  344. * Return detailed network/device statistics.
  345. * May be called after 'dev->close' is called.
  346. */
  347. int pcap_stats_ex (pcap_t *p, struct pcap_stat_ex *se)
  348. {
  349. struct device *dev = p ? get_device (p->fd) : NULL;
  350. if (!dev || !dev->get_stats)
  351. {
  352. strlcpy (p->errbuf, "detailed device statistics not available",
  353. PCAP_ERRBUF_SIZE);
  354. return (-1);
  355. }
  356. if (!strnicmp(dev->name,"pkt",3))
  357. {
  358. strlcpy (p->errbuf, "pktdrvr doesn't have detailed statistics",
  359. PCAP_ERRBUF_SIZE);
  360. return (-1);
  361. }
  362. memcpy (se, (*dev->get_stats)(dev), sizeof(*se));
  363. return (0);
  364. }
  365. /*
  366. * Simply store the filter-code for the pcap_read_dos() callback
  367. * Some day the filter-code could be handed down to the active
  368. * device (pkt_rx1.s or 32-bit device interrupt handler).
  369. */
  370. static int pcap_setfilter_dos (pcap_t *p, struct bpf_program *fp)
  371. {
  372. if (!p)
  373. return (-1);
  374. p->fcode = *fp;
  375. return (0);
  376. }
  377. /*
  378. * Return # of packets received in pcap_read_dos()
  379. */
  380. u_long pcap_mac_packets (void)
  381. {
  382. return (mac_count);
  383. }
  384. /*
  385. * Return # of packets passed through filter in pcap_read_dos()
  386. */
  387. u_long pcap_filter_packets (void)
  388. {
  389. return (filter_count);
  390. }
  391. /*
  392. * Close pcap device. Not called for offline captures.
  393. */
  394. static void pcap_cleanup_dos (pcap_t *p)
  395. {
  396. struct pcap_dos *pd;
  397. if (!exc_occured)
  398. {
  399. pd = p->priv;
  400. if (pcap_stats(p,NULL) < 0)
  401. pd->stat.ps_drop = 0;
  402. if (!get_device(p->fd))
  403. return;
  404. handle_to_device [p->fd-1] = NULL;
  405. p->fd = 0;
  406. if (ref_count > 0)
  407. ref_count--;
  408. if (ref_count > 0)
  409. return;
  410. }
  411. close_driver();
  412. /* XXX - call pcap_cleanup_live_common? */
  413. }
  414. /*
  415. * Return the name of the 1st network interface,
  416. * or NULL if none can be found.
  417. */
  418. char *pcap_lookupdev (char *ebuf)
  419. {
  420. struct device *dev;
  421. #ifdef USE_32BIT_DRIVERS
  422. init_32bit();
  423. #endif
  424. for (dev = (struct device*)dev_base; dev; dev = dev->next)
  425. {
  426. PCAP_ASSERT (dev->probe);
  427. if ((*dev->probe)(dev))
  428. {
  429. FLUSHK();
  430. probed_dev = (struct device*) dev; /* remember last probed device */
  431. return (char*) dev->name;
  432. }
  433. }
  434. if (ebuf)
  435. strcpy (ebuf, "No driver found");
  436. return (NULL);
  437. }
  438. /*
  439. * Gets localnet & netmask from Watt-32.
  440. */
  441. int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
  442. bpf_u_int32 *netmask, char *errbuf)
  443. {
  444. DWORD mask, net;
  445. if (!_watt_is_init)
  446. {
  447. strcpy (errbuf, "pcap_open_offline() or pcap_activate() must be "
  448. "called first");
  449. return (-1);
  450. }
  451. mask = _w32_sin_mask;
  452. net = my_ip_addr & mask;
  453. if (net == 0)
  454. {
  455. if (IN_CLASSA(*netmask))
  456. net = IN_CLASSA_NET;
  457. else if (IN_CLASSB(*netmask))
  458. net = IN_CLASSB_NET;
  459. else if (IN_CLASSC(*netmask))
  460. net = IN_CLASSC_NET;
  461. else
  462. {
  463. pcap_snprintf (errbuf, PCAP_ERRBUF_SIZE, "inet class for 0x%lx unknown", mask);
  464. return (-1);
  465. }
  466. }
  467. *localnet = htonl (net);
  468. *netmask = htonl (mask);
  469. ARGSUSED (device);
  470. return (0);
  471. }
  472. /*
  473. * Get a list of all interfaces that are present and that we probe okay.
  474. * Returns -1 on error, 0 otherwise.
  475. * The list may be NULL epty if no interfaces were up and could be opened.
  476. */
  477. int pcap_platform_finddevs (pcap_if_list_t *devlistp, char *errbuf)
  478. {
  479. struct device *dev;
  480. pcap_if_t *curdev;
  481. #if 0 /* Pkt drivers should have no addresses */
  482. struct sockaddr_in sa_ll_1, sa_ll_2;
  483. struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
  484. #endif
  485. int ret = 0;
  486. int found = 0;
  487. for (dev = (struct device*)dev_base; dev; dev = dev->next)
  488. {
  489. PCAP_ASSERT (dev->probe);
  490. if (!(*dev->probe)(dev))
  491. continue;
  492. PCAP_ASSERT (dev->close); /* set by probe routine */
  493. FLUSHK();
  494. (*dev->close) (dev);
  495. /*
  496. * XXX - find out whether it's up or running? Does that apply here?
  497. * Can we find out if anything's plugged into the adapter, if it's
  498. * a wired device, and set PCAP_IF_CONNECTION_STATUS_CONNECTED
  499. * or PCAP_IF_CONNECTION_STATUS_DISCONNECTED?
  500. */
  501. if ((curdev = add_dev(devlistp, dev->name, 0,
  502. dev->long_name, errbuf)) == NULL)
  503. {
  504. ret = -1;
  505. break;
  506. }
  507. found = 1;
  508. #if 0 /* Pkt drivers should have no addresses */
  509. memset (&sa_ll_1, 0, sizeof(sa_ll_1));
  510. memset (&sa_ll_2, 0, sizeof(sa_ll_2));
  511. sa_ll_1.sin_family = AF_INET;
  512. sa_ll_2.sin_family = AF_INET;
  513. addr = (struct sockaddr*) &sa_ll_1;
  514. netmask = (struct sockaddr*) &sa_ll_1;
  515. dstaddr = (struct sockaddr*) &sa_ll_1;
  516. broadaddr = (struct sockaddr*) &sa_ll_2;
  517. memset (&sa_ll_2.sin_addr, 0xFF, sizeof(sa_ll_2.sin_addr));
  518. if (add_addr_to_dev(curdev, addr, sizeof(*addr),
  519. netmask, sizeof(*netmask),
  520. broadaddr, sizeof(*broadaddr),
  521. dstaddr, sizeof(*dstaddr), errbuf) < 0)
  522. {
  523. ret = -1;
  524. break;
  525. }
  526. #endif
  527. }
  528. if (ret == 0 && !found)
  529. strcpy (errbuf, "No drivers found");
  530. return (ret);
  531. }
  532. /*
  533. * pcap_assert() is mainly used for debugging
  534. */
  535. void pcap_assert (const char *what, const char *file, unsigned line)
  536. {
  537. FLUSHK();
  538. fprintf (stderr, "%s (%u): Assertion \"%s\" failed\n",
  539. file, line, what);
  540. close_driver();
  541. _exit (-1);
  542. }
  543. /*
  544. * For pcap_offline_read(): wait and yield between printing packets
  545. * to simulate the pace packets where actually recorded.
  546. */
  547. void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait)
  548. {
  549. if (p)
  550. {
  551. struct pcap_dos *pd = p->priv;
  552. pd->wait_proc = yield;
  553. p->opt.timeout = wait;
  554. }
  555. }
  556. /*
  557. * Initialise a named network device.
  558. */
  559. static struct device *
  560. open_driver (const char *dev_name, char *ebuf, int promisc)
  561. {
  562. struct device *dev;
  563. for (dev = (struct device*)dev_base; dev; dev = dev->next)
  564. {
  565. PCAP_ASSERT (dev->name);
  566. if (strcmp (dev_name,dev->name))
  567. continue;
  568. if (!probed_dev) /* user didn't call pcap_lookupdev() first */
  569. {
  570. PCAP_ASSERT (dev->probe);
  571. if (!(*dev->probe)(dev)) /* call the xx_probe() function */
  572. {
  573. pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "failed to detect device `%s'", dev_name);
  574. return (NULL);
  575. }
  576. probed_dev = dev; /* device is probed okay and may be used */
  577. }
  578. else if (dev != probed_dev)
  579. {
  580. goto not_probed;
  581. }
  582. FLUSHK();
  583. /* Select what traffic to receive
  584. */
  585. if (promisc)
  586. dev->flags |= (IFF_ALLMULTI | IFF_PROMISC);
  587. else dev->flags &= ~(IFF_ALLMULTI | IFF_PROMISC);
  588. PCAP_ASSERT (dev->open);
  589. if (!(*dev->open)(dev))
  590. {
  591. pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "failed to activate device `%s'", dev_name);
  592. if (pktInfo.error && !strncmp(dev->name,"pkt",3))
  593. {
  594. strcat (ebuf, ": ");
  595. strcat (ebuf, pktInfo.error);
  596. }
  597. return (NULL);
  598. }
  599. /* Some devices need this to operate in promiscous mode
  600. */
  601. if (promisc && dev->set_multicast_list)
  602. (*dev->set_multicast_list) (dev);
  603. active_dev = dev; /* remember our active device */
  604. break;
  605. }
  606. /* 'dev_name' not matched in 'dev_base' list.
  607. */
  608. if (!dev)
  609. {
  610. pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "device `%s' not supported", dev_name);
  611. return (NULL);
  612. }
  613. not_probed:
  614. if (!probed_dev)
  615. {
  616. pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "device `%s' not probed", dev_name);
  617. return (NULL);
  618. }
  619. return (dev);
  620. }
  621. /*
  622. * Deinitialise MAC driver.
  623. * Set receive mode back to default mode.
  624. */
  625. static void close_driver (void)
  626. {
  627. /* !!todo: loop over all 'handle_to_device[]' ? */
  628. struct device *dev = active_dev;
  629. if (dev && dev->close)
  630. {
  631. (*dev->close) (dev);
  632. FLUSHK();
  633. }
  634. active_dev = NULL;
  635. #ifdef USE_32BIT_DRIVERS
  636. if (rx_pool)
  637. {
  638. k_free (rx_pool);
  639. rx_pool = NULL;
  640. }
  641. if (dev)
  642. pcibios_exit();
  643. #endif
  644. }
  645. #ifdef __DJGPP__
  646. static void setup_signals (void (*handler)(int))
  647. {
  648. signal (SIGSEGV,handler);
  649. signal (SIGILL, handler);
  650. signal (SIGFPE, handler);
  651. }
  652. static void exc_handler (int sig)
  653. {
  654. #ifdef USE_32BIT_DRIVERS
  655. if (active_dev->irq > 0) /* excludes IRQ 0 */
  656. {
  657. disable_irq (active_dev->irq);
  658. irq_eoi_cmd (active_dev->irq);
  659. _printk_safe = 1;
  660. }
  661. #endif
  662. switch (sig)
  663. {
  664. case SIGSEGV:
  665. fputs ("Catching SIGSEGV.\n", stderr);
  666. break;
  667. case SIGILL:
  668. fputs ("Catching SIGILL.\n", stderr);
  669. break;
  670. case SIGFPE:
  671. _fpreset();
  672. fputs ("Catching SIGFPE.\n", stderr);
  673. break;
  674. default:
  675. fprintf (stderr, "Catching signal %d.\n", sig);
  676. }
  677. exc_occured = 1;
  678. close_driver();
  679. }
  680. #endif /* __DJGPP__ */
  681. /*
  682. * Open the pcap device for the first client calling pcap_activate()
  683. */
  684. static int first_init (const char *name, char *ebuf, int promisc)
  685. {
  686. struct device *dev;
  687. #ifdef USE_32BIT_DRIVERS
  688. rx_pool = k_calloc (RECEIVE_BUF_SIZE, RECEIVE_QUEUE_SIZE);
  689. if (!rx_pool)
  690. {
  691. strcpy (ebuf, "Not enough memory (Rx pool)");
  692. return (0);
  693. }
  694. #endif
  695. #ifdef __DJGPP__
  696. setup_signals (exc_handler);
  697. #endif
  698. #ifdef USE_32BIT_DRIVERS
  699. init_32bit();
  700. #endif
  701. dev = open_driver (name, ebuf, promisc);
  702. if (!dev)
  703. {
  704. #ifdef USE_32BIT_DRIVERS
  705. k_free (rx_pool);
  706. rx_pool = NULL;
  707. #endif
  708. #ifdef __DJGPP__
  709. setup_signals (SIG_DFL);
  710. #endif
  711. return (0);
  712. }
  713. #ifdef USE_32BIT_DRIVERS
  714. /*
  715. * If driver is NOT a 16-bit "pkt/ndis" driver (having a 'copy_rx_buf'
  716. * set in it's probe handler), initialise near-memory ring-buffer for
  717. * the 32-bit device.
  718. */
  719. if (dev->copy_rx_buf == NULL)
  720. {
  721. dev->get_rx_buf = get_rxbuf;
  722. dev->peek_rx_buf = peek_rxbuf;
  723. dev->release_rx_buf = release_rxbuf;
  724. pktq_init (&dev->queue, RECEIVE_BUF_SIZE, RECEIVE_QUEUE_SIZE, rx_pool);
  725. }
  726. #endif
  727. return (1);
  728. }
  729. #ifdef USE_32BIT_DRIVERS
  730. static void init_32bit (void)
  731. {
  732. static int init_pci = 0;
  733. if (!_printk_file)
  734. _printk_init (64*1024, NULL); /* calls atexit(printk_exit) */
  735. if (!init_pci)
  736. (void)pci_init(); /* init BIOS32+PCI interface */
  737. init_pci = 1;
  738. }
  739. #endif
  740. /*
  741. * Hook functions for using Watt-32 together with pcap
  742. */
  743. static char rxbuf [ETH_MAX+100]; /* rx-buffer with some margin */
  744. static WORD etype;
  745. static pcap_t pcap_save;
  746. static void watt32_recv_hook (u_char *dummy, const struct pcap_pkthdr *pcap,
  747. const u_char *buf)
  748. {
  749. /* Fix me: assumes Ethernet II only */
  750. struct ether_header *ep = (struct ether_header*) buf;
  751. memcpy (rxbuf, buf, pcap->caplen);
  752. etype = ep->ether_type;
  753. ARGSUSED (dummy);
  754. }
  755. #if (WATTCP_VER >= 0x0224)
  756. /*
  757. * This function is used by Watt-32 to poll for a packet.
  758. * i.e. it's set to bypass _eth_arrived()
  759. */
  760. static void *pcap_recv_hook (WORD *type)
  761. {
  762. int len = pcap_read_dos (&pcap_save, 1, watt32_recv_hook, NULL);
  763. if (len < 0)
  764. return (NULL);
  765. *type = etype;
  766. return (void*) &rxbuf;
  767. }
  768. /*
  769. * This function is called by Watt-32 (via _eth_xmit_hook).
  770. * If dbug_init() was called, we should trace packets sent.
  771. */
  772. static int pcap_xmit_hook (const void *buf, unsigned len)
  773. {
  774. int rc = 0;
  775. if (pcap_pkt_debug > 0)
  776. dbug_write ("pcap_xmit_hook: ");
  777. if (active_dev && active_dev->xmit)
  778. if ((*active_dev->xmit) (active_dev, buf, len) > 0)
  779. rc = len;
  780. if (pcap_pkt_debug > 0)
  781. dbug_write (rc ? "ok\n" : "fail\n");
  782. return (rc);
  783. }
  784. #endif
  785. static int pcap_sendpacket_dos (pcap_t *p, const void *buf, size_t len)
  786. {
  787. struct device *dev = p ? get_device(p->fd) : NULL;
  788. if (!dev || !dev->xmit)
  789. return (-1);
  790. return (*dev->xmit) (dev, buf, len);
  791. }
  792. /*
  793. * This function is called by Watt-32 in tcp_post_init().
  794. * We should prevent Watt-32 from using BOOTP/DHCP/RARP etc.
  795. */
  796. static void (*prev_post_hook) (void);
  797. static void pcap_init_hook (void)
  798. {
  799. _w32__bootp_on = _w32__dhcp_on = _w32__rarp_on = 0;
  800. _w32__do_mask_req = 0;
  801. _w32_dynamic_host = 0;
  802. if (prev_post_hook)
  803. (*prev_post_hook)();
  804. }
  805. /*
  806. * Supress PRINT message from Watt-32's sock_init()
  807. */
  808. static void null_print (void) {}
  809. /*
  810. * To use features of Watt-32 (netdb functions and socket etc.)
  811. * we must call sock_init(). But we set various hooks to prevent
  812. * using normal PKTDRVR functions in pcpkt.c. This should hopefully
  813. * make Watt-32 and pcap co-operate.
  814. */
  815. static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)
  816. {
  817. char *env;
  818. int rc, MTU, has_ip_addr;
  819. int using_pktdrv = 1;
  820. /* If user called sock_init() first, we need to reinit in
  821. * order to open debug/trace-file properly
  822. */
  823. if (_watt_is_init)
  824. sock_exit();
  825. env = getenv ("PCAP_TRACE");
  826. if (env && atoi(env) > 0 &&
  827. pcap_pkt_debug < 0) /* if not already set */
  828. {
  829. dbug_init();
  830. pcap_pkt_debug = atoi (env);
  831. }
  832. _watt_do_exit = 0; /* prevent sock_init() calling exit() */
  833. prev_post_hook = _w32_usr_post_init;
  834. _w32_usr_post_init = pcap_init_hook;
  835. _w32_print_hook = null_print;
  836. if (dev_name && strncmp(dev_name,"pkt",3))
  837. using_pktdrv = FALSE;
  838. rc = sock_init();
  839. has_ip_addr = (rc != 8); /* IP-address assignment failed */
  840. /* if pcap is using a 32-bit driver w/o a pktdrvr loaded, we
  841. * just pretend Watt-32 is initialised okay.
  842. *
  843. * !! fix-me: The Watt-32 config isn't done if no pktdrvr
  844. * was found. In that case my_ip_addr + sin_mask
  845. * have default values. Should be taken from another
  846. * ini-file/environment in any case (ref. tcpdump.ini)
  847. */
  848. _watt_is_init = 1;
  849. if (!using_pktdrv || !has_ip_addr) /* for now .... */
  850. {
  851. static const char myip[] = "192.168.0.1";
  852. static const char mask[] = "255.255.255.0";
  853. printf ("Just guessing, using IP %s and netmask %s\n", myip, mask);
  854. my_ip_addr = aton (myip);
  855. _w32_sin_mask = aton (mask);
  856. }
  857. else if (rc && using_pktdrv)
  858. {
  859. pcap_snprintf (err_buf, PCAP_ERRBUF_SIZE, "sock_init() failed, code %d", rc);
  860. return (0);
  861. }
  862. /* Set recv-hook for peeking in _eth_arrived().
  863. */
  864. #if (WATTCP_VER >= 0x0224)
  865. _eth_recv_hook = pcap_recv_hook;
  866. _eth_xmit_hook = pcap_xmit_hook;
  867. #endif
  868. /* Free the pkt-drvr handle allocated in pkt_init().
  869. * The above hooks should thus use the handle reopened in open_driver()
  870. */
  871. if (using_pktdrv)
  872. {
  873. _eth_release();
  874. /* _eth_is_init = 1; */ /* hack to get Rx/Tx-hooks in Watt-32 working */
  875. }
  876. memcpy (&pcap_save, pcap, sizeof(pcap_save));
  877. MTU = pkt_get_mtu();
  878. pcap_save.fcode.bf_insns = NULL;
  879. pcap_save.linktype = _eth_get_hwtype (NULL, NULL);
  880. pcap_save.snapshot = MTU > 0 ? MTU : ETH_MAX; /* assume 1514 */
  881. #if 1
  882. /* prevent use of resolve() and resolve_ip()
  883. */
  884. last_nameserver = 0;
  885. #endif
  886. return (1);
  887. }
  888. int EISA_bus = 0; /* Where is natural place for this? */
  889. /*
  890. * Application config hooks to set various driver parameters.
  891. */
  892. static const struct config_table debug_tab[] = {
  893. { "PKT.DEBUG", ARG_ATOI, &pcap_pkt_debug },
  894. { "PKT.VECTOR", ARG_ATOX_W, NULL },
  895. { "NDIS.DEBUG", ARG_ATOI, NULL },
  896. #ifdef USE_32BIT_DRIVERS
  897. { "3C503.DEBUG", ARG_ATOI, &ei_debug },
  898. { "3C503.IO_BASE", ARG_ATOX_W, &el2_dev.base_addr },
  899. { "3C503.MEMORY", ARG_ATOX_W, &el2_dev.mem_start },
  900. { "3C503.IRQ", ARG_ATOI, &el2_dev.irq },
  901. { "3C505.DEBUG", ARG_ATOI, NULL },
  902. { "3C505.BASE", ARG_ATOX_W, NULL },
  903. { "3C507.DEBUG", ARG_ATOI, NULL },
  904. { "3C509.DEBUG", ARG_ATOI, &el3_debug },
  905. { "3C509.ILOOP", ARG_ATOI, &el3_max_loop },
  906. { "3C529.DEBUG", ARG_ATOI, NULL },
  907. { "3C575.DEBUG", ARG_ATOI, &debug_3c575 },
  908. { "3C59X.DEBUG", ARG_ATOI, &vortex_debug },
  909. { "3C59X.IFACE0", ARG_ATOI, &vortex_options[0] },
  910. { "3C59X.IFACE1", ARG_ATOI, &vortex_options[1] },
  911. { "3C59X.IFACE2", ARG_ATOI, &vortex_options[2] },
  912. { "3C59X.IFACE3", ARG_ATOI, &vortex_options[3] },
  913. { "3C90X.DEBUG", ARG_ATOX_W, &tc90xbc_debug },
  914. { "ACCT.DEBUG", ARG_ATOI, &ethpk_debug },
  915. { "CS89.DEBUG", ARG_ATOI, &cs89_debug },
  916. { "RTL8139.DEBUG", ARG_ATOI, &rtl8139_debug },
  917. /* { "RTL8139.FDUPLEX", ARG_ATOI, &rtl8139_options }, */
  918. { "SMC.DEBUG", ARG_ATOI, &ei_debug },
  919. /* { "E100.DEBUG", ARG_ATOI, &e100_debug }, */
  920. { "PCI.DEBUG", ARG_ATOI, &pci_debug },
  921. { "BIOS32.DEBUG", ARG_ATOI, &bios32_debug },
  922. { "IRQ.DEBUG", ARG_ATOI, &irq_debug },
  923. { "TIMER.IRQ", ARG_ATOI, &timer_irq },
  924. #endif
  925. { NULL }
  926. };
  927. /*
  928. * pcap_config_hook() is an extension to application's config
  929. * handling. Uses Watt-32's config-table function.
  930. */
  931. int pcap_config_hook (const char *keyword, const char *value)
  932. {
  933. return parse_config_table (debug_tab, NULL, keyword, value);
  934. }
  935. /*
  936. * Linked list of supported devices
  937. */
  938. struct device *active_dev = NULL; /* the device we have opened */
  939. struct device *probed_dev = NULL; /* the device we have probed */
  940. const struct device *dev_base = &pkt_dev; /* list of network devices */
  941. /*
  942. * PKTDRVR device functions
  943. */
  944. int pcap_pkt_debug = -1;
  945. static void pkt_close (struct device *dev)
  946. {
  947. BOOL okay = PktExitDriver();
  948. if (pcap_pkt_debug > 1)
  949. fprintf (stderr, "pkt_close(): %d\n", okay);
  950. if (dev->priv)
  951. free (dev->priv);
  952. dev->priv = NULL;
  953. }
  954. static int pkt_open (struct device *dev)
  955. {
  956. PKT_RX_MODE mode;
  957. if (dev->flags & IFF_PROMISC)
  958. mode = PDRX_ALL_PACKETS;
  959. else mode = PDRX_BROADCAST;
  960. if (!PktInitDriver(mode))
  961. return (0);
  962. PktResetStatistics (pktInfo.handle);
  963. PktQueueBusy (FALSE);
  964. return (1);
  965. }
  966. static int pkt_xmit (struct device *dev, const void *buf, int len)
  967. {
  968. struct net_device_stats *stats = (struct net_device_stats*) dev->priv;
  969. if (pcap_pkt_debug > 0)
  970. dbug_write ("pcap_xmit\n");
  971. if (!PktTransmit(buf,len))
  972. {
  973. stats->tx_errors++;
  974. return (0);
  975. }
  976. return (len);
  977. }
  978. static void *pkt_stats (struct device *dev)
  979. {
  980. struct net_device_stats *stats = (struct net_device_stats*) dev->priv;
  981. if (!stats || !PktSessStatistics(pktInfo.handle))
  982. return (NULL);
  983. stats->rx_packets = pktStat.inPackets;
  984. stats->rx_errors = pktStat.lost;
  985. stats->rx_missed_errors = PktRxDropped();
  986. return (stats);
  987. }
  988. static int pkt_probe (struct device *dev)
  989. {
  990. if (!PktSearchDriver())
  991. return (0);
  992. dev->open = pkt_open;
  993. dev->xmit = pkt_xmit;
  994. dev->close = pkt_close;
  995. dev->get_stats = pkt_stats;
  996. dev->copy_rx_buf = PktReceive; /* farmem peek and copy routine */
  997. dev->get_rx_buf = NULL;
  998. dev->peek_rx_buf = NULL;
  999. dev->release_rx_buf = NULL;
  1000. dev->priv = calloc (sizeof(struct net_device_stats), 1);
  1001. if (!dev->priv)
  1002. return (0);
  1003. return (1);
  1004. }
  1005. /*
  1006. * NDIS device functions
  1007. */
  1008. static void ndis_close (struct device *dev)
  1009. {
  1010. #ifdef USE_NDIS2
  1011. NdisShutdown();
  1012. #endif
  1013. ARGSUSED (dev);
  1014. }
  1015. static int ndis_open (struct device *dev)
  1016. {
  1017. int promis = (dev->flags & IFF_PROMISC);
  1018. #ifdef USE_NDIS2
  1019. if (!NdisInit(promis))
  1020. return (0);
  1021. return (1);
  1022. #else
  1023. ARGSUSED (promis);
  1024. return (0);
  1025. #endif
  1026. }
  1027. static void *ndis_stats (struct device *dev)
  1028. {
  1029. static struct net_device_stats stats;
  1030. /* to-do */
  1031. ARGSUSED (dev);
  1032. return (&stats);
  1033. }
  1034. static int ndis_probe (struct device *dev)
  1035. {
  1036. #ifdef USE_NDIS2
  1037. if (!NdisOpen())
  1038. return (0);
  1039. #endif
  1040. dev->open = ndis_open;
  1041. dev->xmit = NULL;
  1042. dev->close = ndis_close;
  1043. dev->get_stats = ndis_stats;
  1044. dev->copy_rx_buf = NULL; /* to-do */
  1045. dev->get_rx_buf = NULL; /* upcall is from rmode driver */
  1046. dev->peek_rx_buf = NULL;
  1047. dev->release_rx_buf = NULL;
  1048. return (0);
  1049. }
  1050. /*
  1051. * Search & probe for supported 32-bit (pmode) pcap devices
  1052. */
  1053. #if defined(USE_32BIT_DRIVERS)
  1054. struct device el2_dev LOCKED_VAR = {
  1055. "3c503",
  1056. "EtherLink II",
  1057. 0,
  1058. 0,0,0,0,0,0,
  1059. NULL,
  1060. el2_probe
  1061. };
  1062. struct device el3_dev LOCKED_VAR = {
  1063. "3c509",
  1064. "EtherLink III",
  1065. 0,
  1066. 0,0,0,0,0,0,
  1067. &el2_dev,
  1068. el3_probe
  1069. };
  1070. struct device tc515_dev LOCKED_VAR = {
  1071. "3c515",
  1072. "EtherLink PCI",
  1073. 0,
  1074. 0,0,0,0,0,0,
  1075. &el3_dev,
  1076. tc515_probe
  1077. };
  1078. struct device tc59_dev LOCKED_VAR = {
  1079. "3c59x",
  1080. "EtherLink PCI",
  1081. 0,
  1082. 0,0,0,0,0,0,
  1083. &tc515_dev,
  1084. tc59x_probe
  1085. };
  1086. struct device tc90xbc_dev LOCKED_VAR = {
  1087. "3c90x",
  1088. "EtherLink 90X",
  1089. 0,
  1090. 0,0,0,0,0,0,
  1091. &tc59_dev,
  1092. tc90xbc_probe
  1093. };
  1094. struct device wd_dev LOCKED_VAR = {
  1095. "wd",
  1096. "Westen Digital",
  1097. 0,
  1098. 0,0,0,0,0,0,
  1099. &tc90xbc_dev,
  1100. wd_probe
  1101. };
  1102. struct device ne_dev LOCKED_VAR = {
  1103. "ne",
  1104. "NEx000",
  1105. 0,
  1106. 0,0,0,0,0,0,
  1107. &wd_dev,
  1108. ne_probe
  1109. };
  1110. struct device acct_dev LOCKED_VAR = {
  1111. "acct",
  1112. "Accton EtherPocket",
  1113. 0,
  1114. 0,0,0,0,0,0,
  1115. &ne_dev,
  1116. ethpk_probe
  1117. };
  1118. struct device cs89_dev LOCKED_VAR = {
  1119. "cs89",
  1120. "Crystal Semiconductor",
  1121. 0,
  1122. 0,0,0,0,0,0,
  1123. &acct_dev,
  1124. cs89x0_probe
  1125. };
  1126. struct device rtl8139_dev LOCKED_VAR = {
  1127. "rtl8139",
  1128. "RealTek PCI",
  1129. 0,
  1130. 0,0,0,0,0,0,
  1131. &cs89_dev,
  1132. rtl8139_probe /* dev->probe routine */
  1133. };
  1134. /*
  1135. * Dequeue routine is called by polling.
  1136. * NOTE: the queue-element is not copied, only a pointer is
  1137. * returned at '*buf'
  1138. */
  1139. int peek_rxbuf (BYTE **buf)
  1140. {
  1141. struct rx_elem *tail, *head;
  1142. PCAP_ASSERT (pktq_check (&active_dev->queue));
  1143. DISABLE();
  1144. tail = pktq_out_elem (&active_dev->queue);
  1145. head = pktq_in_elem (&active_dev->queue);
  1146. ENABLE();
  1147. if (head != tail)
  1148. {
  1149. PCAP_ASSERT (tail->size < active_dev->queue.elem_size-4-2);
  1150. *buf = &tail->data[0];
  1151. return (tail->size);
  1152. }
  1153. *buf = NULL;
  1154. return (0);
  1155. }
  1156. /*
  1157. * Release buffer we peeked at above.
  1158. */
  1159. int release_rxbuf (BYTE *buf)
  1160. {
  1161. #ifndef NDEBUG
  1162. struct rx_elem *tail = pktq_out_elem (&active_dev->queue);
  1163. PCAP_ASSERT (&tail->data[0] == buf);
  1164. #else
  1165. ARGSUSED (buf);
  1166. #endif
  1167. pktq_inc_out (&active_dev->queue);
  1168. return (1);
  1169. }
  1170. /*
  1171. * get_rxbuf() routine (in locked code) is called from IRQ handler
  1172. * to request a buffer. Interrupts are disabled and we have a 32kB stack.
  1173. */
  1174. BYTE *get_rxbuf (int len)
  1175. {
  1176. int idx;
  1177. if (len < ETH_MIN || len > ETH_MAX)
  1178. return (NULL);
  1179. idx = pktq_in_index (&active_dev->queue);
  1180. #ifdef DEBUG
  1181. {
  1182. static int fan_idx LOCKED_VAR = 0;
  1183. writew ("-\\|/"[fan_idx++] | (15 << 8), /* white on black colour */
  1184. 0xB8000 + 2*79); /* upper-right corner, 80-col colour screen */
  1185. fan_idx &= 3;
  1186. }
  1187. /* writew (idx + '0' + 0x0F00, 0xB8000 + 2*78); */
  1188. #endif
  1189. if (idx != active_dev->queue.out_index)
  1190. {
  1191. struct rx_elem *head = pktq_in_elem (&active_dev->queue);
  1192. head->size = len;
  1193. active_dev->queue.in_index = idx;
  1194. return (&head->data[0]);
  1195. }
  1196. /* !!to-do: drop 25% of the oldest element
  1197. */
  1198. pktq_clear (&active_dev->queue);
  1199. return (NULL);
  1200. }
  1201. /*
  1202. * Simple ring-buffer queue handler for reception of packets
  1203. * from network driver.
  1204. */
  1205. #define PKTQ_MARKER 0xDEADBEEF
  1206. static int pktq_check (struct rx_ringbuf *q)
  1207. {
  1208. #ifndef NDEBUG
  1209. int i;
  1210. char *buf;
  1211. #endif
  1212. if (!q || !q->num_elem || !q->buf_start)
  1213. return (0);
  1214. #ifndef NDEBUG
  1215. buf = q->buf_start;
  1216. for (i = 0; i < q->num_elem; i++)
  1217. {
  1218. buf += q->elem_size;
  1219. if (*(DWORD*)(buf - sizeof(DWORD)) != PKTQ_MARKER)
  1220. return (0);
  1221. }
  1222. #endif
  1223. return (1);
  1224. }
  1225. static int pktq_init (struct rx_ringbuf *q, int size, int num, char *pool)
  1226. {
  1227. int i;
  1228. q->elem_size = size;
  1229. q->num_elem = num;
  1230. q->buf_start = pool;
  1231. q->in_index = 0;
  1232. q->out_index = 0;
  1233. PCAP_ASSERT (size >= sizeof(struct rx_elem) + sizeof(DWORD));
  1234. PCAP_ASSERT (num);
  1235. PCAP_ASSERT (pool);
  1236. for (i = 0; i < num; i++)
  1237. {
  1238. #if 0
  1239. struct rx_elem *elem = (struct rx_elem*) pool;
  1240. /* assert dword aligned elements
  1241. */
  1242. PCAP_ASSERT (((unsigned)(&elem->data[0]) & 3) == 0);
  1243. #endif
  1244. pool += size;
  1245. *(DWORD*) (pool - sizeof(DWORD)) = PKTQ_MARKER;
  1246. }
  1247. return (1);
  1248. }
  1249. /*
  1250. * Increment the queue 'out_index' (tail).
  1251. * Check for wraps.
  1252. */
  1253. static int pktq_inc_out (struct rx_ringbuf *q)
  1254. {
  1255. q->out_index++;
  1256. if (q->out_index >= q->num_elem)
  1257. q->out_index = 0;
  1258. return (q->out_index);
  1259. }
  1260. /*
  1261. * Return the queue's next 'in_index' (head).
  1262. * Check for wraps.
  1263. */
  1264. static int pktq_in_index (struct rx_ringbuf *q)
  1265. {
  1266. volatile int index = q->in_index + 1;
  1267. if (index >= q->num_elem)
  1268. index = 0;
  1269. return (index);
  1270. }
  1271. /*
  1272. * Return the queue's head-buffer.
  1273. */
  1274. static struct rx_elem *pktq_in_elem (struct rx_ringbuf *q)
  1275. {
  1276. return (struct rx_elem*) (q->buf_start + (q->elem_size * q->in_index));
  1277. }
  1278. /*
  1279. * Return the queue's tail-buffer.
  1280. */
  1281. static struct rx_elem *pktq_out_elem (struct rx_ringbuf *q)
  1282. {
  1283. return (struct rx_elem*) (q->buf_start + (q->elem_size * q->out_index));
  1284. }
  1285. /*
  1286. * Clear the queue ring-buffer by setting head=tail.
  1287. */
  1288. static void pktq_clear (struct rx_ringbuf *q)
  1289. {
  1290. q->in_index = q->out_index;
  1291. }
  1292. /*
  1293. * Symbols that must be linkable for "gcc -O0"
  1294. */
  1295. #undef __IOPORT_H
  1296. #undef __DMA_H
  1297. #define extern
  1298. #define __inline__
  1299. #include "msdos/pm_drvr/ioport.h"
  1300. #include "msdos/pm_drvr/dma.h"
  1301. #endif /* USE_32BIT_DRIVERS */
  1302. /*
  1303. * Libpcap version string.
  1304. */
  1305. const char *
  1306. pcap_lib_version(void)
  1307. {
  1308. return ("DOS-" PCAP_VERSION_STRING);
  1309. }