networking with qemu 0.8.0

Started by neozeed, April 20, 2006, 07:52:34 PM

Previous topic - Next topic

neozeed

I just telneted from nextstep!

First I hacked vl.c to include pcap support with some stuff I 'borrowed' from simh.  This way I could sniff the traffic.  The first packet that nextstep sends on boot seems to not agree with most things (a broadcast gratuitous arp).  However after altering the vlc.c to drop the 1st packet I could telnet out.


Here is my hacked source, at the moment the nick name is 'hacked' into the source... ugh its horrible.


Place this section under the CONFIG_SLIRP portion

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef CONFIG_PCAP
#include <pcap.h>
#include <string.h>

#if defined(_WIN32)
#include <winreg.h>
#endif

#include <pthread.h>

static VLANClientState *pcap_vc;
pcap_t* pcaphandle;
static void pcap_receive(void *opaque, const uint8_t *buf, int size);
char* eth_getname_bydesc(char* desc, char* name);
char* eth_getname(int number, char* name);
void eth_callback(u_char *user, struct pcap_pkthdr *phdr, u_char *pdata);
void *pcap_send(void *threadid);
int eth_open(char* name);

static int net_pcap_init(VLANState *vlan)
{
pcap_vc = qemu_new_vlan_client(vlan,pcap_receive,NULL);
snprintf(pcap_vc->info_str,sizeof(pcap_vc->info_str),"pcap redirector");
//LAN
//eth_open("\\Device\\NPF_{4D73FC25-F493-4E9B-8EE4-E5E458679D2F}");
eth_open("en0");
//eth_open("\\Device\\NPF_{0F8C9C7E-BA14-441A-88BF-71F25ADB9FD5}");
//eth_open("eth3");

pthread_attr_t attr;
pthread_t threads;
int rc;
//ethq_init (&dev->read_queue, 200); /* initialize FIFO queue */
//pthread_mutex_init (&dev->lock, NULL);
//pthread_attr_init(&attr);
//pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
//pthread_create (&dev->reader_thread, &attr, _eth_reader, (void *)dev);
//pthread_create (NULL, &attr, pcap_send, NULL);
rc=pthread_create (&threads,NULL,pcap_send,NULL);
pthread_attr_destroy(&attr);


return 0;
}

int wtf=0;
static void pcap_receive(void *opaque, const uint8_t *buf, int size)
{
//printf("pcap input:\n");
//hex_dump(stdout,buf,size);
//status = pcap_sendpacket((pcap_t*)dev->handle, (u_char*)packet->msg, packet->len);

//use wtf to drop the 1st packet.
if(wtf==0)
{wtf++;}
else{
pcap_sendpacket((pcap_t*)pcaphandle, (u_char*)buf, size);
}
}

void *pcap_send(void *threadid)
{
int sel_ret;
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 200*1000;
int status;

while(pcaphandle)
{
fd_set setl;
//sleep(1);
//printf("t");
FD_ZERO(&setl);
//FD_SET(pcap_get_selectable_fd((pcap_t *)pcaphandle), &setl);
//sel_ret = select(pcap_get_selectable_fd((pcap_t *)pcaphandle), &setl, NULL, NULL, &timeout);
//if (sel_ret < 0 && errno != EINTR) break;
//if (sel_ret > 0) {
/* dispatch read request queue available packets */
//printf("D");
//status = pcap_dispatch((pcap_t*)pcaphandle, -1, &eth_callback, "");
//printf("d");
// }
status = pcap_dispatch((pcap_t*)pcaphandle, 1, &eth_callback, NULL);
//printf("d");
}
}

void eth_callback(u_char *user, struct pcap_pkthdr *phdr, u_char *pdata)
{
//printf("eth_callback:\n");
//printf("%d\t\t\r",phdr->len);
//fflush(stdout);
//hex_dump(stdout,pdata,phdr->len);
if(phdr->len<1501)
qemu_send_packet(pcap_vc, pdata, phdr->len);
}

#define ETH_PROMISC 1
#define PCAP_READ_TIMEOUT 15

int eth_open(char* name)
{
const int bufsz = (BUFSIZ < 1520) ? 1520 : BUFSIZ;
char errbuf[PCAP_ERRBUF_SIZE];
char temp[1024];
char* savname = name;
int num;
char* msg;

/* translate name of type "ethX" to real device name */
if ((strlen(name) == 4)
&& (tolower(name[0]) == 'e')
&& (tolower(name[1]) == 't')
&& (tolower(name[2]) == 'h')
&& isdigit(name[3])
) {
num = atoi(&name[3]);
savname = eth_getname(num, temp);
if (savname == 0) /* didn't translate */
return -1;
} else {
/* are they trying to use device description? */
//savname = eth_getname_bydesc(name, temp);
if (savname == 0) /* didn't translate */
return -1;
}

/* attempt to connect device */
memset(errbuf, 0, sizeof(errbuf));
pcaphandle = (void*) pcap_open_live(savname, bufsz, ETH_PROMISC, PCAP_READ_TIMEOUT, errbuf);
if (!pcaphandle) { /* can't open device */
msg = "Eth: pcap_open_live error - %s\r\n";
printf (msg, errbuf);
return -1;
} else {
msg = "Eth: opened %s\r\n";
printf (msg, savname);
}

/* save name of device */
//dev->name = malloc(strlen(savname)+1);
//strcpy(dev->name, savname);

/* save debugging information */
//dev->dptr = dptr;
//dev->dbit = dbit;

#if !defined(HAS_PCAP_SENDPACKET) && defined (xBSD) && !defined (__APPLE__)
/* Tell the kernel that the header is fully-formed when it gets it.
This is required in order to fake the src address. */
{
int one = 1;
ioctl(pcap_fileno(dev->pcaphandle), BIOCSHDRCMPLT, &one);
}
#endif /* xBSD */

#if defined (USE_READER_THREAD)
{
pthread_attr_t attr;

ethq_init (&dev->read_queue, 200); /* initialize FIFO queue */
pthread_mutex_init (&dev->lock, NULL);
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_create (&dev->reader_thread, &attr, _pcap_send, (void *)dev);
pthread_attr_destroy(&attr);
}
#else /* !defined (USE_READER_THREAD */
#ifdef USE_SETNONBLOCK
/* set ethernet device non-blocking so pcap_dispatch() doesn't hang */
if (pcap_setnonblock (dev->pcaphandle, 1, errbuf) == -1) {
msg = "Eth: Failed to set non-blocking: %s\r\n";
printf (msg, errbuf);
if (sim_log) fprintf (sim_log, msg, errbuf);
}
#endif
#endif /* !defined (USE_READER_THREAD */
return 0;
}

#define ETH_MAX_DEVICE 10
char* eth_getname_bydesc(char* desc, char* name)
{
// ETH_LIST list[ETH_MAX_DEVICE];
struct slist {
int num;
char name[50];
char desc[50];
}list[10];
int count = 1;//eth_devices(ETH_MAX_DEVICE, list);
int i;
int j=strlen(desc);

for (i=0; i<count; i++) {
int found = 1;
int k = strlen(list.desc);

if (j != k) continue;
for (k=0; k<j; k++)
if (tolower(list.desc[k]) != tolower(desc[k]))
found = 0;
if (found == 0) continue;

/* found a case-insensitive description match */
strcpy(name, list.name);
return name;
}
/* not found */
return 0;
}

char* eth_getname(int number, char* name)
{
//ETH_LIST list[ETH_MAX_DEVICE];
struct slist {
int num;
char name[50];
char desc[50];
}list[10];
int count =1;// eth_devices(ETH_MAX_DEVICE, list);

if (count < number) return 0;
strcpy(name, list[number].name);
return name;
}


#endif //CONFIG_PCAP
/////////////////////////////////////////////////////////////////////////////////////////////////////////////





And this right after the second CONFIG_SLIRP


#ifdef CONFIG_PCAP
   if (!strcmp(device, "pcap")) {
   ret = net_pcap_init(vlan);
   } else
#endif
# include <wittycomment.h>

nuss

Hi,

What network adapter to use with your network hack would you recommend on the NS virtual box?

Thanks & greetings
-nuss
DON'T PANIC

neozeed

ill dig up an exact name/link for it.
# include <wittycomment.h>

neozeed

ftp://ftp.cs.tu-berlin.de/pub/NeXT/hardware/driver/intel/NE2K_0.91beta.m.I.b.tar.gz

If you look the source to the driver is there as well:

ftp://ftp.cs.tu-berlin.de/pub/NeXT/hardware/driver/intel/NE2K_0.91beta.m.I.s.tar.gz

it detects right away!  Although right now I think there is a race condition with large packets.... try setting the MTU low (say 256 or 512?).
# include <wittycomment.h>

nuss

Thank you very much. Driver itselfs seems to work fine on Openstep 4.2 (no errormessage during boot).
Sadly, all network settings I tried so far did not work out. But I am still trying.. :wink:

Thanks again and NeXTish greetings
-nuss
DON'T PANIC

neozeed

-net nic -net pcap
in your args.. or even -net nic -net user

that way you will have installed the nic.  Ill try to patch something a little more sensible in the week.  work has been insane, i just had to rebuild a wan/lan setup for 200 users....
# include <wittycomment.h>