1 /*--------------------------------------------------------------------
3 * AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4 * DATE CREATED: 6/13/07
6 * PROJECT: Plasma CPU core
7 * COPYRIGHT: Software placed into the public domain by the author.
8 * Software 'as is' without warranty. Author liable for nothing.
10 * A terminal program supporting downloading new Plasma applications
11 * and Ethernet packet transfers. Based on WinPcap example code.
12 * Requires WinPcap library at http://www.winpcap.org/.
13 *--------------------------------------------------------------------*/
18 //#define SIMULATE_PLASMA
20 #ifdef SIMULATE_PLASMA
29 #define PCAP_ERRBUF_SIZE 256
30 typedef struct pcap_if {
32 char *name; /* name to hand to "pcap_open_live()" */
33 char *description; /* textual description of interface, or NULL */
34 struct pcap_addr *addresses;
35 unsigned long flags; /* PCAP_IF_ interface flags */
38 struct timeval ts; /* time stamp */
39 unsigned long caplen; /* length of portion present */
40 unsigned long len; /* length this packet (off wire) */
42 typedef struct pcap pcap_t;
44 int pcap_findalldevs(pcap_if_t **, char *);
45 void pcap_freealldevs(pcap_if_t *);
46 pcap_t *pcap_open_live(const char *, int, int, int, char *);
47 int pcap_setnonblock(pcap_t *, int, char *);
48 int pcap_sendpacket(pcap_t *, const u_char *, int);
49 const unsigned char *pcap_next(pcap_t *, struct pcap_pkthdr *);
52 //ETHER FIELD OFFSET LENGTH VALUE
53 #define ETHERNET_DEST 0 //6
54 #define ETHERNET_SOURCE 6 //6
55 #define ETHERNET_FRAME_TYPE 12 //2 IP=0x0800; ARP=0x0806
56 #define IP_PROTOCOL 23 //1 TCP=0x06;PING=0x01;UDP=0x11
57 #define IP_SOURCE 26 //4
59 static const unsigned char ethernetAddressNull[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
60 static const unsigned char ethernetAddressPhantom[] = {0x00, 0x10, 0xdd, 0xce, 0x15, 0xd4};
61 static const unsigned char ethernetAddressPhantom2[] = {0x00, 0x10, 0xdd, 0xce, 0x15, 0xd5};
63 static pcap_t *adhandle;
66 static HANDLE serial_handle;
67 static int PacketBytes, PacketLength, PacketChecksum, Checksum;
68 static int ChecksumOk, ChecksumError;
69 static unsigned char PacketData[2000];
70 static int EthernetActive;
72 #ifdef SIMULATE_PLASMA
73 extern void *IPFrameGet(int freeCount);
74 extern int IPProcessEthernetPacket(void *frameIn, int length);
75 extern void IPTick(void);
76 extern void IPInit(void (*frameSendFunction)(), unsigned char macAddress[6], char name[6]);
77 extern void HtmlInit(int UseFiles);
78 extern void ConsoleInit(void);
79 static void *ethFrame;
91 char errbuf[PCAP_ERRBUF_SIZE];
93 /* Retrieve the device list */
94 if(pcap_findalldevs(&alldevs, errbuf) == -1)
96 printf("Error in pcap_findalldevs: %s\n", errbuf);
101 for(d = alldevs; d; d=d->next)
103 printf("%d. %s", ++i, d->name);
105 printf(" (%s)\n", d->description);
107 printf(" (No description available)\n");
108 if(strstr(d->description, "eneric") == 0 && strstr(d->description, "Linux") == 0)
119 printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
129 printf("Enter the interface number (1-%d):",i);
132 printf("inum = %d\n", inum);
134 if(inum < 1 || inum > i)
136 printf("\nInterface number out of range.\n");
137 /* Free the device list */
138 pcap_freealldevs(alldevs);
142 /* Jump to the selected adapter */
143 for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
145 /* Open the adapter */
146 if ((adhandle = pcap_open_live(d->name, // name of the device
147 65536, // 65536 grants that the whole packet will be captured on all the MACs.
148 1, // promiscuous mode (nonzero means promiscuous)
150 errbuf // error buffer
153 printf("\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
154 /* Free the device list */
155 pcap_freealldevs(alldevs);
159 printf("\nlistening on %s...\n", d->description);
161 /* At this point, we don't need any more the device list. Free it */
162 pcap_freealldevs(alldevs);
164 /* start the capture */
165 pcap_setnonblock(adhandle, 1, errbuf);
171 void EthernetSendPacket(const unsigned char *packet, int length)
173 if(EthernetActive == 0)
175 EthernetActive = 1;
\r
176 //if((rand() % 8) == 0) return;
\r
177 pcap_sendpacket(adhandle, packet, length);
181 /* Callback function invoked by libpcap for every incoming packet */
182 void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
184 #ifndef SIMULATE_PLASMA
186 unsigned char buf[80];
193 if(EthernetActive == 0)
195 if(pkt_data[ETHERNET_FRAME_TYPE] != 0x08)
196 return; //not IP or ARP
197 if(pkt_data[ETHERNET_FRAME_TYPE+1] != 0x00 &&
198 pkt_data[ETHERNET_FRAME_TYPE+1] != 0x06)
199 return; //not IP or ARP
200 if(memcmp(pkt_data, ethernetAddressNull, 6) && //not broadcast address
201 memcmp(pkt_data+ETHERNET_DEST, ethernetAddressPhantom, 6) &&
202 memcmp(pkt_data+ETHERNET_DEST, ethernetAddressPhantom2, 6))
205 #ifndef SIMULATE_PLASMA
206 //Send the ethernet packet over the serial port
208 buf[1] = (unsigned char)(header->len >> 8);
209 buf[2] = (unsigned char)header->len;
211 for(i = 0; i < (int)header->len; ++i)
212 checksum += pkt_data[i];
213 buf[3] = (unsigned char)checksum;
214 WriteFile(serial_handle, buf, 4, &count, NULL);
215 WriteFile(serial_handle, pkt_data, header->len, &count, NULL);
218 ethFrame = IPFrameGet(0);
221 memcpy(ethFrame, pkt_data, header->len);
222 rc = IPProcessEthernetPacket(ethFrame, header->len);
229 static void UartPacketRead(int value)
231 if(PacketBytes == 0 && value == 0xff)
235 else if(PacketBytes == 1)
238 PacketLength = value << 8;
240 else if(PacketBytes == 2)
243 PacketLength |= value;
244 if(PacketLength > 1000)
247 printf("Eterm Length Bad! (%d)\n", PacketLength);
250 else if(PacketBytes == 3)
253 PacketChecksum = value;
256 else if(PacketBytes >= 4)
258 if(PacketBytes - 4 < sizeof(PacketData))
259 PacketData[PacketBytes - 4] = (unsigned char)value;
262 if(PacketBytes - 4 >= PacketLength)
264 if((unsigned char)Checksum == PacketChecksum)
267 EthernetSendPacket(PacketData, PacketLength);
272 //printf("ChecksumError(%d %d)!\n", ChecksumOk, ChecksumError);
280 /**************************************************************/
282 long SerialOpen(char *name, long baud)
285 COMMTIMEOUTS comm_timeouts;
287 serial_handle = CreateFile(name, GENERIC_READ|GENERIC_WRITE,
288 0, NULL, OPEN_EXISTING, 0, NULL);
289 if(serial_handle == INVALID_HANDLE_VALUE)
290 printf("Serial Port In Use!\n");
291 rc = SetupComm(serial_handle, 16000, 16000);
293 printf("Serial port already in use!!!\n");
294 rc = GetCommState(serial_handle, &dcb);
301 dcb.StopBits = 0; //ONESTOPBIT;
306 dcb.fOutxCtsFlow = 0;
307 dcb.fOutxDsrFlow = 0;
311 dcb.fDsrSensitivity = 0;
312 rc = SetCommState(serial_handle, &dcb);
315 rc = GetCommTimeouts(serial_handle, &comm_timeouts);
318 comm_timeouts.ReadIntervalTimeout = MAXDWORD; //non-blocking read
319 comm_timeouts.ReadTotalTimeoutMultiplier = 0;
320 comm_timeouts.ReadTotalTimeoutConstant = 0;
321 comm_timeouts.WriteTotalTimeoutMultiplier = 0; //blocking write
322 comm_timeouts.WriteTotalTimeoutConstant = 0;
323 rc = SetCommTimeouts(serial_handle, &comm_timeouts);
330 long SerialRead(unsigned char *data, unsigned long length)
333 unsigned char buf[8];
338 ReadFile(serial_handle, buf, 1, &bytes, NULL);
342 if(buf[0] == 0xff || PacketBytes)
343 UartPacketRead(buf[0]);
346 data[count++] = buf[0];
353 //****************************************************
355 #define BUF_SIZE 1024*1024
363 in=fopen("test.bin", "rb");
365 printf("Can't find test.bin\n");
368 buf = (unsigned char*)malloc(BUF_SIZE);
369 memset(buf, 0, BUF_SIZE);
370 length = (int)fread(buf, 1, BUF_SIZE, in);
372 printf("Sending test.bin (length=%d bytes) to target...\n", length);
373 WriteFile(serial_handle, buf, length, &count, NULL);
374 printf("Done downloading\n");
379 int main(int argc, char *argv[])
381 unsigned int ticksLast = GetTickCount();
383 unsigned char buf[80];
386 int downloadSkip = 0;
391 #ifndef SIMULATE_PLASMA
392 SerialOpen("COM1", 57600);
393 if(argc != 2 || strcmp(argv[1], "none"))
398 IPInit(EthernetSendPacket, NULL, NULL);
408 buf[0] = (unsigned char)getch();
409 if(downloadSkip && buf[0] == '`')
411 WriteFile(serial_handle, buf, 1, &count, NULL);
417 length = SerialRead(buf, sizeof(buf));
426 while(EthernetActive)
428 struct pcap_pkthdr header;
429 const u_char *pkt_data;
430 pkt_data = pcap_next(adhandle, &header);
434 packet_handler(NULL, &header, pkt_data);
438 ticks = GetTickCount();
439 if(ticks - ticksLast > 1000)
441 #ifdef SIMULATE_PLASMA