Annotation of previous_trunk/src/enet_pcap.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.