aboutsummaryrefslogtreecommitdiff
path: root/src/fake86/packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fake86/packet.c')
-rwxr-xr-xsrc/fake86/packet.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/src/fake86/packet.c b/src/fake86/packet.c
new file mode 100755
index 0000000..38ce12e
--- /dev/null
+++ b/src/fake86/packet.c
@@ -0,0 +1,185 @@
+/*
+ Fake86: A portable, open-source 8086 PC emulator.
+ Copyright (C)2010-2013 Mike Chambers
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+/* packet.c: functions to interface with libpcap/winpcap for ethernet emulation. */
+
+#include "config.h"
+
+#ifdef NETWORKING_ENABLED
+#define HAVE_REMOTE
+#define WPCAP
+#include <pcap.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <memory.h>
+
+#ifndef _WIN32
+#define PCAP_OPENFLAG_PROMISCUOUS 1
+#endif
+
+extern uint8_t RAM[0x100000];
+extern uint8_t verbose;
+uint8_t ethif, net_enabled = 0;
+uint8_t dopktrecv = 0;
+uint16_t rcvseg, rcvoff, hdrlen, handpkt;
+
+pcap_if_t *alldevs;
+pcap_if_t *d;
+pcap_t *adhandle;
+const u_char *pktdata;
+struct pcap_pkthdr *hdr;
+int inum;
+uint16_t curhandle = 0;
+char errbuf[PCAP_ERRBUF_SIZE];
+uint8_t maclocal[6] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x13, 0x37 };
+
+void initpcap() {
+ int i=0;
+
+ printf ("\nObtaining NIC list via libpcap...\n");
+
+ /* Retrieve the device list from the local machine */
+#if defined(_WIN32)
+ if (pcap_findalldevs_ex (PCAP_SRC_IF_STRING, NULL /* auth is not needed */, &alldevs, errbuf) == -1)
+#else
+ if (pcap_findalldevs (&alldevs, errbuf) == -1)
+#endif
+ {
+ printf ("Error in pcap_findalldevs_ex: %s\n", errbuf);
+ exit (1);
+ }
+
+ /* Print the list */
+ for (d= alldevs; d != NULL; d= d->next) {
+ i++;
+ if (ethif==255) {
+ printf ("%d. %s", i, d->name);
+ if (d->description) {
+ printf (" (%s)\n", d->description);
+ }
+ else {
+ printf (" (No description available)\n");
+ }
+ }
+ }
+
+ if (i == 0) {
+ printf ("\nNo interfaces found! Make sure WinPcap is installed.\n");
+ return;
+ }
+
+ printf ("\n");
+
+ if (ethif==255) exit (0);
+ else inum = ethif;
+ printf ("Using network interface %u.\n", ethif);
+
+
+ if (inum < 1 || inum > i) {
+ printf ("\nInterface number out of range.\n");
+ /* Free the device list */
+ pcap_freealldevs (alldevs);
+ return;
+ }
+
+ /* Jump to the selected adapter */
+ for (d=alldevs, i=0; i< inum-1 ; d=d->next, i++);
+
+ /* Open the device */
+#ifdef _WIN32
+ if ( (adhandle= pcap_open (d->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, -1, NULL, errbuf) ) == NULL)
+#else
+ if ( (adhandle= pcap_open_live (d->name, 65535, 1, -1, NULL) ) == NULL)
+#endif
+ {
+ printf ("\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
+ /* Free the device list */
+ pcap_freealldevs (alldevs);
+ return;
+ }
+
+ printf ("\nEthernet bridge on %s...\n", d->description);
+
+ /* At this point, we don't need any more the device list. Free it */
+ pcap_freealldevs (alldevs);
+ net_enabled = 1;
+}
+
+void setmac() {
+ memcpy (&RAM[0xE0000], &maclocal[0], 6);
+}
+
+#ifndef NETWORKING_OLDCARD
+extern int ne2000_can_receive();
+extern void ne2000_receive (const uint8_t *buf, int size);
+
+uint8_t newrecv[5000];
+
+void dispatch() {
+ uint16_t i;
+
+ if (pcap_next_ex (adhandle, &hdr, &pktdata) <=0) return;
+ if (hdr->len==0) return;
+ if (ne2000_can_receive() ) {
+ for (i=0; i<hdr->len; i++) {
+ newrecv[i<<1] = pktdata[i];
+ newrecv[ (i<<1) +1] = 0;
+ }
+ ne2000_receive (newrecv, hdr->len);
+ }
+ return;
+}
+
+void sendpkt (uint8_t *src, uint16_t len) {
+ uint16_t i;
+ for (i=0; i<len; i++) {
+ printf ("%02X ", src[i]);
+ }
+ printf ("\n");
+ pcap_sendpacket (adhandle, src, len);
+}
+#else
+extern struct netstruct {
+ uint8_t enabled;
+ uint8_t canrecv;
+ uint16_t pktlen;
+} net;
+
+extern void doirq (uint8_t irqnum);
+
+void dispatch() {
+ if (pcap_next_ex (adhandle, &hdr, &pktdata) <=0) return;
+ if (hdr->len==0) return;
+
+ net.canrecv = 0;
+ memcpy (&RAM[0xD0000], &pktdata[0], hdr->len);
+ net.pktlen = (uint16_t) hdr->len;
+ if (verbose) {
+ printf ("Received packet of %u bytes.\n", net.pktlen);
+ }
+ doirq (6);
+ return;
+}
+
+void sendpkt (uint8_t *src, uint16_t len) {
+ pcap_sendpacket (adhandle, src, len);
+}
+#endif
+
+#endif