|
|
1.1 root 1: #include "m68000.h"
2: #include "ethernet.h"
3: #include "enet_pcap.h"
4: #include "queue.h"
5: #include "host.h"
6:
7: #if HAVE_PCAP
8: #if defined _WIN32
9: #undef mkdir
10: #endif
11: #include <pcap.h>
12:
13: /****************/
14: /* --- PCAP --- */
15:
16:
17: /* PCAP prototypes */
18: pcap_t *pcap_handle;
19:
20: /* queue prototypes */
21: queueADT pcapq;
22:
23: int pcap_started;
24: static SDL_mutex *pcap_mutex = NULL;
25: SDL_Thread *pcap_tick_func_handle;
26:
27: //This function is to be periodically called
28: //to keep the internal packet state flowing.
29: static void pcap_tick(void)
30: {
31: struct pcap_pkthdr h;
32: const unsigned char *data;
33:
34: if (pcap_started) {
35: SDL_LockMutex(pcap_mutex);
36: data = pcap_next(pcap_handle,&h);
37: SDL_UnlockMutex(pcap_mutex);
38:
39: if (data && h.caplen > 0) {
40: if (h.caplen > 1516)
41: h.caplen = 1516;
42:
43: struct queuepacket *p;
44: p=(struct queuepacket *)malloc(sizeof(struct queuepacket));
45: SDL_LockMutex(pcap_mutex);
46: p->len=h.caplen;
47: memcpy(p->data,data,h.caplen);
48: QueueEnter(pcapq,p);
49: SDL_UnlockMutex(pcap_mutex);
50: Log_Printf(LOG_WARN, "[PCAP] Output packet with %i bytes to queue",h.caplen);
51: }
52: }
53: }
54:
55: static int tick_func(void *arg)
56: {
57: while(pcap_started)
58: {
59: host_sleep_ms(10);
60: pcap_tick();
61: }
62: return 0;
63: }
64:
65:
66: void enet_pcap_queue_poll(void)
67: {
68: if (pcap_started) {
69: SDL_LockMutex(pcap_mutex);
70: if (QueuePeek(pcapq)>0)
71: {
72: struct queuepacket *qp;
73: qp=QueueDelete(pcapq);
74: Log_Printf(LOG_WARN, "[PCAP] Getting packet from queue");
75: enet_receive(qp->data,qp->len);
76: free(qp);
77: }
78: SDL_UnlockMutex(pcap_mutex);
79: }
80: }
81:
82: void enet_pcap_input(Uint8 *pkt, int pkt_len) {
83: if (pcap_started) {
84: Log_Printf(LOG_WARN, "[PCAP] Input packet with %i bytes",enet_tx_buffer.size);
85: SDL_LockMutex(pcap_mutex);
86: if (pcap_sendpacket(pcap_handle, pkt, pkt_len) < 0) {
87: Log_Printf(LOG_WARN, "[PCAP] Error: Couldn't transmit packet!");
88: }
89: SDL_UnlockMutex(pcap_mutex);
90: }
91: }
92:
93: void enet_pcap_stop(void) {
94: int ret;
95:
96: if (pcap_started) {
97: Log_Printf(LOG_WARN, "Stopping PCAP");
98: pcap_started=0;
99: QueueDestroy(pcapq);
100: SDL_DestroyMutex(pcap_mutex);
101: SDL_WaitThread(pcap_tick_func_handle, &ret);
102: pcap_close(pcap_handle);
103: }
104: }
105:
106: void enet_pcap_start(Uint8 *mac) {
107: char errbuf[PCAP_ERRBUF_SIZE];
108: char *dev;
109: struct bpf_program fp;
110: char filter_exp[255];
111: bpf_u_int32 net = 0xffffffff;
112:
113: if (!pcap_started) {
114: Log_Printf(LOG_WARN, "Starting PCAP");
115:
116: #if 0
117: dev = pcap_lookupdev(errbuf);
118: #else
119: dev = ConfigureParams.Ethernet.szInterfaceName;
120: #endif
121: if (dev == NULL) {
122: Log_Printf(LOG_WARN, "[PCAP] Error: Couldn't find device: %s", errbuf);
123: return;
124: }
125: Log_Printf(LOG_WARN, "Device: %s", dev);
126:
127: pcap_handle = pcap_open_live(dev, 1518, 1, 1000, errbuf);
128:
129: if (pcap_handle == NULL) {
130: Log_Printf(LOG_WARN, "[PCAP] Error: Couldn't open device %s: %s", dev, errbuf);
131: return;
132: }
133:
134: if (pcap_getnonblock(pcap_handle, errbuf) == 0) {
135: Log_Printf(LOG_WARN, "[PCAP] Setting interface to non-blocking mode.");
136: if (pcap_setnonblock(pcap_handle, 1, errbuf) != 0) {
137: Log_Printf(LOG_WARN, "[PCAP] Error: Couldn't set interface to non-blocking mode: %s", errbuf);
138: return;
139: }
140: } else {
141: Log_Printf(LOG_WARN, "[PCAP] Error: Unexpected error: %s", errbuf);
142: return;
143: }
144:
145: #if 1 // TODO: Check if we need to take care of RXMODE_ADDR_SIZE and RX_PROMISCUOUS/RX_ANY
146: sprintf(filter_exp,"(((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x) or (ether[0] & 0x01 = 0x01)))",
147: mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
148:
149: if (pcap_compile(pcap_handle, &fp, filter_exp, 0, net) == -1) {
150: Log_Printf(LOG_WARN, "[PCAP] Warning: Couldn't parse filter %s: %s", filter_exp, pcap_geterr(pcap_handle));
151: } else {
152: if (pcap_setfilter(pcap_handle, &fp) == -1) {
153: Log_Printf(LOG_WARN, "[PCAP] Warning: Couldn't install filter %s: %s", filter_exp, pcap_geterr(pcap_handle));
154: }
155: }
156: #endif
157: pcap_started=1;
158: pcapq = QueueCreate();
159: pcap_mutex=SDL_CreateMutex();
160: pcap_tick_func_handle=SDL_CreateThread(tick_func,"PCAPTickThread", (void *)NULL);
161: }
162: }
163: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.