⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slirp.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "slirp.h"/* host address */struct in_addr our_addr;/* host dns address */struct in_addr dns_addr;/* host loopback address */struct in_addr loopback_addr;/* address for slirp virtual addresses */struct in_addr special_addr;/* virtual address alias for host */struct in_addr alias_addr;const uint8_t special_ethaddr[6] = {     0x52, 0x54, 0x00, 0x12, 0x35, 0x00};uint8_t client_ethaddr[6];int do_slowtimo;int link_up;struct timeval tt;FILE *lfd;struct ex_list *exec_list;/* XXX: suppress those select globals */fd_set *global_readfds, *global_writefds, *global_xfds;char slirp_hostname[33];#ifdef _WIN32static int get_dns_addr(struct in_addr *pdns_addr){    FIXED_INFO *FixedInfo=NULL;    ULONG    BufLen;    DWORD    ret;    IP_ADDR_STRING *pIPAddr;    struct in_addr tmp_addr;        FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));    BufLen = sizeof(FIXED_INFO);       if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {        if (FixedInfo) {            GlobalFree(FixedInfo);            FixedInfo = NULL;        }        FixedInfo = GlobalAlloc(GPTR, BufLen);    }	    if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {        printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );        if (FixedInfo) {            GlobalFree(FixedInfo);            FixedInfo = NULL;        }        return -1;    }         pIPAddr = &(FixedInfo->DnsServerList);    inet_aton(pIPAddr->IpAddress.String, &tmp_addr);    *pdns_addr = tmp_addr;#if 0    printf( "DNS Servers:\n" );    printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String );        pIPAddr = FixedInfo -> DnsServerList.Next;    while ( pIPAddr ) {            printf( "DNS Addr:%s\n", pIPAddr ->IpAddress.String );            pIPAddr = pIPAddr ->Next;    }#endif    if (FixedInfo) {        GlobalFree(FixedInfo);        FixedInfo = NULL;    }    return 0;}#elsestatic int get_dns_addr(struct in_addr *pdns_addr){    char buff[512];    char buff2[256];    FILE *f;    int found = 0;    struct in_addr tmp_addr;        f = fopen("/etc/resolv.conf", "r");    if (!f)        return -1;    lprint("IP address of your DNS(s): ");    while (fgets(buff, 512, f) != NULL) {        if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {            if (!inet_aton(buff2, &tmp_addr))                continue;            if (tmp_addr.s_addr == loopback_addr.s_addr)                tmp_addr = our_addr;            /* If it's the first one, set it to dns_addr */            if (!found)                *pdns_addr = tmp_addr;            else                lprint(", ");            if (++found > 3) {                lprint("(more)");                break;            } else                lprint("%s", inet_ntoa(tmp_addr));        }    }    fclose(f);    if (!found)        return -1;    return 0;}#endif#ifdef _WIN32void slirp_cleanup(void){    WSACleanup();}#endifvoid slirp_init(void){    //    debug_init("/tmp/slirp.log", DEBUG_DEFAULT);    #ifdef _WIN32    {        WSADATA Data;        WSAStartup(MAKEWORD(2,0), &Data);	atexit(slirp_cleanup);    }#endif    link_up = 1;    if_init();    ip_init();    /* Initialise mbufs *after* setting the MTU */    m_init();    /* set default addresses */    inet_aton("127.0.0.1", &loopback_addr);    if (get_dns_addr(&dns_addr) < 0) {        dns_addr = loopback_addr;        fprintf (stderr, "Warning: No DNS servers found\n");    }    inet_aton(CTL_SPECIAL, &special_addr);    alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS);    getouraddr();}#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)#define UPD_NFDS(x) if (nfds < (x)) nfds = (x)/* * curtime kept to an accuracy of 1ms */#ifdef _WIN32static void updtime(void){    struct _timeb tb;    _ftime(&tb);    curtime = (u_int)tb.time * (u_int)1000;    curtime += (u_int)tb.millitm;}#elsestatic void updtime(void){	gettimeofday(&tt, 0);		curtime = (u_int)tt.tv_sec * (u_int)1000;	curtime += (u_int)tt.tv_usec / (u_int)1000;		if ((tt.tv_usec % 1000) >= 500)	   curtime++;}#endifvoid slirp_select_fill(int *pnfds,                        fd_set *readfds, fd_set *writefds, fd_set *xfds){    struct socket *so, *so_next;    struct timeval timeout;    int nfds;    int tmp_time;    /* fail safe */    global_readfds = NULL;    global_writefds = NULL;    global_xfds = NULL;        nfds = *pnfds;	/*	 * First, TCP sockets	 */	do_slowtimo = 0;	if (link_up) {		/* 		 * *_slowtimo needs calling if there are IP fragments		 * in the fragment queue, or there are TCP connections active		 */		do_slowtimo = ((tcb.so_next != &tcb) ||			       ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next));				for (so = tcb.so_next; so != &tcb; so = so_next) {			so_next = so->so_next;						/*			 * See if we need a tcp_fasttimo			 */			if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)			   time_fasttimo = curtime; /* Flag when we want a fasttimo */						/*			 * NOFDREF can include still connecting to local-host,			 * newly socreated() sockets etc. Don't want to select these.	 		 */			if (so->so_state & SS_NOFDREF || so->s == -1)			   continue;						/*			 * Set for reading sockets which are accepting			 */			if (so->so_state & SS_FACCEPTCONN) {                                FD_SET(so->s, readfds);				UPD_NFDS(so->s);				continue;			}						/*			 * Set for writing sockets which are connecting			 */			if (so->so_state & SS_ISFCONNECTING) {				FD_SET(so->s, writefds);				UPD_NFDS(so->s);				continue;			}						/*			 * Set for writing if we are connected, can send more, and			 * we have something to send			 */			if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {				FD_SET(so->s, writefds);				UPD_NFDS(so->s);			}						/*			 * Set for reading (and urgent data) if we are connected, can			 * receive more, and we have room for it XXX /2 ?			 */			if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {				FD_SET(so->s, readfds);				FD_SET(so->s, xfds);				UPD_NFDS(so->s);			}		}				/*		 * UDP sockets		 */		for (so = udb.so_next; so != &udb; so = so_next) {			so_next = so->so_next;						/*			 * See if it's timed out			 */			if (so->so_expire) {				if (so->so_expire <= curtime) {					udp_detach(so);					continue;				} else					do_slowtimo = 1; /* Let socket expire */			}						/*			 * When UDP packets are received from over the			 * link, they're sendto()'d straight away, so			 * no need for setting for writing			 * Limit the number of packets queued by this session			 * to 4.  Note that even though we try and limit this			 * to 4 packets, the session could have more queued			 * if the packets needed to be fragmented			 * (XXX <= 4 ?)			 */			if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {				FD_SET(so->s, readfds);				UPD_NFDS(so->s);			}		}	}		/*	 * Setup timeout to use minimum CPU usage, especially when idle	 */		/* 	 * First, see the timeout needed by *timo	 */	timeout.tv_sec = 0;	timeout.tv_usec = -1;	/*	 * If a slowtimo is needed, set timeout to 500ms from the last	 * slow timeout. If a fast timeout is needed, set timeout within	 * 200ms of when it was requested.	 */	if (do_slowtimo) {		/* XXX + 10000 because some select()'s aren't that accurate */		timeout.tv_usec = ((500 - (curtime - last_slowtimo)) * 1000) + 10000;		if (timeout.tv_usec < 0)		   timeout.tv_usec = 0;		else if (timeout.tv_usec > 510000)		   timeout.tv_usec = 510000;				/* Can only fasttimo if we also slowtimo */		if (time_fasttimo) {			tmp_time = (200 - (curtime - time_fasttimo)) * 1000;			if (tmp_time < 0)			   tmp_time = 0;			

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -