win32 compile
[qemu] / slirp / slirp.c
1 #include "slirp.h"
2
3 /* host address */
4 struct in_addr our_addr;
5 /* host dns address */
6 struct in_addr dns_addr;
7 /* host loopback address */
8 struct in_addr loopback_addr;
9
10 /* address for slirp virtual addresses */
11 struct in_addr special_addr;
12
13 const uint8_t special_ethaddr[6] = { 
14     0x52, 0x54, 0x00, 0x12, 0x35, 0x00
15 };
16
17 uint8_t client_ethaddr[6];
18
19 int do_slowtimo;
20 int link_up;
21 struct timeval tt;
22 FILE *lfd;
23
24 /* XXX: suppress those select globals */
25 fd_set *global_readfds, *global_writefds, *global_xfds;
26
27 #ifdef _WIN32
28
29 static int get_dns_addr(struct in_addr *pdns_addr)
30 {
31     FIXED_INFO *FixedInfo=NULL;
32     ULONG    BufLen;
33     DWORD    ret;
34     IP_ADDR_STRING *pIPAddr;
35     struct in_addr tmp_addr;
36     
37     FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
38     BufLen = sizeof(FIXED_INFO);
39    
40     if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
41         if (FixedInfo) {
42             GlobalFree(FixedInfo);
43             FixedInfo = NULL;
44         }
45         FixedInfo = GlobalAlloc(GPTR, BufLen);
46     }
47         
48     if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
49         printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
50         if (FixedInfo) {
51             GlobalFree(FixedInfo);
52             FixedInfo = NULL;
53         }
54         return -1;
55     }
56      
57     pIPAddr = &(FixedInfo->DnsServerList);
58     inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
59     *pdns_addr = tmp_addr;
60 #if 0
61     printf( "DNS Servers:\n" );
62     printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String );
63     
64     pIPAddr = FixedInfo -> DnsServerList.Next;
65     while ( pIPAddr ) {
66             printf( "DNS Addr:%s\n", pIPAddr ->IpAddress.String );
67             pIPAddr = pIPAddr ->Next;
68     }
69 #endif
70     if (FixedInfo) {
71         GlobalFree(FixedInfo);
72         FixedInfo = NULL;
73     }
74     return 0;
75 }
76
77 #else
78
79 static int get_dns_addr(struct in_addr *pdns_addr)
80 {
81     char buff[512];
82     char buff2[256];
83     FILE *f;
84     int found = 0;
85     struct in_addr tmp_addr;
86     
87     f = fopen("/etc/resolv.conf", "r");
88     if (!f)
89         return -1;
90
91     lprint("IP address of your DNS(s): ");
92     while (fgets(buff, 512, f) != NULL) {
93         if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
94             if (!inet_aton(buff2, &tmp_addr))
95                 continue;
96             if (tmp_addr.s_addr == loopback_addr.s_addr)
97                 tmp_addr = our_addr;
98             /* If it's the first one, set it to dns_addr */
99             if (!found)
100                 *pdns_addr = tmp_addr;
101             else
102                 lprint(", ");
103             if (++found > 3) {
104                 lprint("(more)");
105                 break;
106             } else
107                 lprint("%s", inet_ntoa(tmp_addr));
108         }
109     }
110     fclose(f);
111     if (!found)
112         return -1;
113     return 0;
114 }
115
116 #endif
117
118 #ifdef _WIN32
119 void slirp_cleanup(void)
120 {
121     WSACleanup();
122 }
123 #endif
124
125 void slirp_init(void)
126 {
127     //    debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
128     
129 #ifdef _WIN32
130     {
131         WSADATA Data;
132         WSAStartup(MAKEWORD(2,0), &Data);
133         atexit(slirp_cleanup);
134     }
135 #endif
136
137     link_up = 1;
138
139     if_init();
140     ip_init();
141
142     /* Initialise mbufs *after* setting the MTU */
143     m_init();
144
145     /* set default addresses */
146     getouraddr();
147     inet_aton("127.0.0.1", &loopback_addr);
148
149     if (get_dns_addr(&dns_addr) < 0) {
150         fprintf(stderr, "Could not get DNS address\n");
151         exit(1);
152     }
153
154     inet_aton(CTL_SPECIAL, &special_addr);
155 }
156
157 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
158 #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
159 #define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
160
161 /*
162  * curtime kept to an accuracy of 1ms
163  */
164 #ifdef _WIN32
165 static void updtime(void)
166 {
167     struct _timeb tb;
168
169     _ftime(&tb);
170     curtime = (u_int)tb.time * (u_int)1000;
171     curtime += (u_int)tb.millitm;
172 }
173 #else
174 static void updtime(void)
175 {
176         gettimeofday(&tt, 0);
177         
178         curtime = (u_int)tt.tv_sec * (u_int)1000;
179         curtime += (u_int)tt.tv_usec / (u_int)1000;
180         
181         if ((tt.tv_usec % 1000) >= 500)
182            curtime++;
183 }
184 #endif
185
186 void slirp_select_fill(int *pnfds, 
187                        fd_set *readfds, fd_set *writefds, fd_set *xfds)
188 {
189     struct socket *so, *so_next;
190     struct timeval timeout;
191     int nfds;
192     int tmp_time;
193
194     /* fail safe */
195     global_readfds = NULL;
196     global_writefds = NULL;
197     global_xfds = NULL;
198     
199     nfds = *pnfds;
200         /*
201          * First, TCP sockets
202          */
203         do_slowtimo = 0;
204         if (link_up) {
205                 /* 
206                  * *_slowtimo needs calling if there are IP fragments
207                  * in the fragment queue, or there are TCP connections active
208                  */
209                 do_slowtimo = ((tcb.so_next != &tcb) ||
210                                ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next));
211                 
212                 for (so = tcb.so_next; so != &tcb; so = so_next) {
213                         so_next = so->so_next;
214                         
215                         /*
216                          * See if we need a tcp_fasttimo
217                          */
218                         if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
219                            time_fasttimo = curtime; /* Flag when we want a fasttimo */
220                         
221                         /*
222                          * NOFDREF can include still connecting to local-host,
223                          * newly socreated() sockets etc. Don't want to select these.
224                          */
225                         if (so->so_state & SS_NOFDREF || so->s == -1)
226                            continue;
227                         
228                         /*
229                          * Set for reading sockets which are accepting
230                          */
231                         if (so->so_state & SS_FACCEPTCONN) {
232                                 FD_SET(so->s, readfds);
233                                 UPD_NFDS(so->s);
234                                 continue;
235                         }
236                         
237                         /*
238                          * Set for writing sockets which are connecting
239                          */
240                         if (so->so_state & SS_ISFCONNECTING) {
241                                 FD_SET(so->s, writefds);
242                                 UPD_NFDS(so->s);
243                                 continue;
244                         }
245                         
246                         /*
247                          * Set for writing if we are connected, can send more, and
248                          * we have something to send
249                          */
250                         if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
251                                 FD_SET(so->s, writefds);
252                                 UPD_NFDS(so->s);
253                         }
254                         
255                         /*
256                          * Set for reading (and urgent data) if we are connected, can
257                          * receive more, and we have room for it XXX /2 ?
258                          */
259                         if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
260                                 FD_SET(so->s, readfds);
261                                 FD_SET(so->s, xfds);
262                                 UPD_NFDS(so->s);
263                         }
264                 }
265                 
266                 /*
267                  * UDP sockets
268                  */
269                 for (so = udb.so_next; so != &udb; so = so_next) {
270                         so_next = so->so_next;
271                         
272                         /*
273                          * See if it's timed out
274                          */
275                         if (so->so_expire) {
276                                 if (so->so_expire <= curtime) {
277                                         udp_detach(so);
278                                         continue;
279                                 } else
280                                         do_slowtimo = 1; /* Let socket expire */
281                         }
282                         
283                         /*
284                          * When UDP packets are received from over the
285                          * link, they're sendto()'d straight away, so
286                          * no need for setting for writing
287                          * Limit the number of packets queued by this session
288                          * to 4.  Note that even though we try and limit this
289                          * to 4 packets, the session could have more queued
290                          * if the packets needed to be fragmented
291                          * (XXX <= 4 ?)
292                          */
293                         if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
294                                 FD_SET(so->s, readfds);
295                                 UPD_NFDS(so->s);
296                         }
297                 }
298         }
299         
300         /*
301          * Setup timeout to use minimum CPU usage, especially when idle
302          */
303         
304         /* 
305          * First, see the timeout needed by *timo
306          */
307         timeout.tv_sec = 0;
308         timeout.tv_usec = -1;
309         /*
310          * If a slowtimo is needed, set timeout to 500ms from the last
311          * slow timeout. If a fast timeout is needed, set timeout within
312          * 200ms of when it was requested.
313          */
314         if (do_slowtimo) {
315                 /* XXX + 10000 because some select()'s aren't that accurate */
316                 timeout.tv_usec = ((500 - (curtime - last_slowtimo)) * 1000) + 10000;
317                 if (timeout.tv_usec < 0)
318                    timeout.tv_usec = 0;
319                 else if (timeout.tv_usec > 510000)
320                    timeout.tv_usec = 510000;
321                 
322                 /* Can only fasttimo if we also slowtimo */
323                 if (time_fasttimo) {
324                         tmp_time = (200 - (curtime - time_fasttimo)) * 1000;
325                         if (tmp_time < 0)
326                            tmp_time = 0;
327                         
328                         /* Choose the smallest of the 2 */
329                         if (tmp_time < timeout.tv_usec)
330                            timeout.tv_usec = (u_int)tmp_time;
331                 }
332         }
333         *pnfds = nfds;
334 }       
335
336 void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
337 {
338     struct socket *so, *so_next;
339     int ret;
340
341     global_readfds = readfds;
342     global_writefds = writefds;
343     global_xfds = xfds;
344
345         /* Update time */
346         updtime();
347         
348         /*
349          * See if anything has timed out 
350          */
351         if (link_up) {
352                 if (time_fasttimo && ((curtime - time_fasttimo) >= 199)) {
353                         tcp_fasttimo();
354                         time_fasttimo = 0;
355                 }
356                 if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
357                         ip_slowtimo();
358                         tcp_slowtimo();
359                         last_slowtimo = curtime;
360                 }
361         }
362         
363         /*
364          * Check sockets
365          */
366         if (link_up) {
367                 /*
368                  * Check TCP sockets
369                  */
370                 for (so = tcb.so_next; so != &tcb; so = so_next) {
371                         so_next = so->so_next;
372                         
373                         /*
374                          * FD_ISSET is meaningless on these sockets
375                          * (and they can crash the program)
376                          */
377                         if (so->so_state & SS_NOFDREF || so->s == -1)
378                            continue;
379                         
380                         /*
381                          * Check for URG data
382                          * This will soread as well, so no need to
383                          * test for readfds below if this succeeds
384                          */
385                         if (FD_ISSET(so->s, xfds))
386                            sorecvoob(so);
387                         /*
388                          * Check sockets for reading
389                          */
390                         else if (FD_ISSET(so->s, readfds)) {
391                                 /*
392                                  * Check for incoming connections
393                                  */
394                                 if (so->so_state & SS_FACCEPTCONN) {
395                                         tcp_connect(so);
396                                         continue;
397                                 } /* else */
398                                 ret = soread(so);
399                                 
400                                 /* Output it if we read something */
401                                 if (ret > 0)
402                                    tcp_output(sototcpcb(so));
403                         }
404                         
405                         /*
406                          * Check sockets for writing
407                          */
408                         if (FD_ISSET(so->s, writefds)) {
409                           /*
410                            * Check for non-blocking, still-connecting sockets
411                            */
412                           if (so->so_state & SS_ISFCONNECTING) {
413                             /* Connected */
414                             so->so_state &= ~SS_ISFCONNECTING;
415                             
416                             ret = write(so->s, &ret, 0);
417                             if (ret < 0) {
418                               /* XXXXX Must fix, zero bytes is a NOP */
419                               if (errno == EAGAIN || errno == EWOULDBLOCK ||
420                                   errno == EINPROGRESS || errno == ENOTCONN)
421                                 continue;
422                               
423                               /* else failed */
424                               so->so_state = SS_NOFDREF;
425                             }
426                             /* else so->so_state &= ~SS_ISFCONNECTING; */
427                             
428                             /*
429                              * Continue tcp_input
430                              */
431                             tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
432                             /* continue; */
433                           } else
434                             ret = sowrite(so);
435                           /*
436                            * XXXXX If we wrote something (a lot), there 
437                            * could be a need for a window update.
438                            * In the worst case, the remote will send
439                            * a window probe to get things going again
440                            */
441                         }
442                         
443                         /*
444                          * Probe a still-connecting, non-blocking socket
445                          * to check if it's still alive
446                          */
447 #ifdef PROBE_CONN
448                         if (so->so_state & SS_ISFCONNECTING) {
449                           ret = read(so->s, (char *)&ret, 0);
450                           
451                           if (ret < 0) {
452                             /* XXX */
453                             if (errno == EAGAIN || errno == EWOULDBLOCK ||
454                                 errno == EINPROGRESS || errno == ENOTCONN)
455                               continue; /* Still connecting, continue */
456                             
457                             /* else failed */
458                             so->so_state = SS_NOFDREF;
459                             
460                             /* tcp_input will take care of it */
461                           } else {
462                             ret = write(so->s, &ret, 0);
463                             if (ret < 0) {
464                               /* XXX */
465                               if (errno == EAGAIN || errno == EWOULDBLOCK ||
466                                   errno == EINPROGRESS || errno == ENOTCONN)
467                                 continue;
468                               /* else failed */
469                               so->so_state = SS_NOFDREF;
470                             } else
471                               so->so_state &= ~SS_ISFCONNECTING;
472                             
473                           }
474                           tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
475                         } /* SS_ISFCONNECTING */
476 #endif
477                 }
478                 
479                 /*
480                  * Now UDP sockets.
481                  * Incoming packets are sent straight away, they're not buffered.
482                  * Incoming UDP data isn't buffered either.
483                  */
484                 for (so = udb.so_next; so != &udb; so = so_next) {
485                         so_next = so->so_next;
486                         
487                         if (so->s != -1 && FD_ISSET(so->s, readfds)) {
488                             sorecvfrom(so);
489                         }
490                 }
491         }
492         
493         /*
494          * See if we can start outputting
495          */
496         if (if_queued && link_up)
497            if_start();
498 }
499
500 #define ETH_ALEN 6
501 #define ETH_HLEN 14
502
503 #define ETH_P_IP        0x0800          /* Internet Protocol packet     */
504 #define ETH_P_ARP       0x0806          /* Address Resolution packet    */
505
506 #define ARPOP_REQUEST   1               /* ARP request                  */
507 #define ARPOP_REPLY     2               /* ARP reply                    */
508
509 struct ethhdr 
510 {
511         unsigned char   h_dest[ETH_ALEN];       /* destination eth addr */
512         unsigned char   h_source[ETH_ALEN];     /* source ether addr    */
513         unsigned short  h_proto;                /* packet type ID field */
514 };
515
516 struct arphdr
517 {
518         unsigned short  ar_hrd;         /* format of hardware address   */
519         unsigned short  ar_pro;         /* format of protocol address   */
520         unsigned char   ar_hln;         /* length of hardware address   */
521         unsigned char   ar_pln;         /* length of protocol address   */
522         unsigned short  ar_op;          /* ARP opcode (command)         */
523
524          /*
525           *      Ethernet looks like this : This bit is variable sized however...
526           */
527         unsigned char           ar_sha[ETH_ALEN];       /* sender hardware address      */
528         unsigned char           ar_sip[4];              /* sender IP address            */
529         unsigned char           ar_tha[ETH_ALEN];       /* target hardware address      */
530         unsigned char           ar_tip[4];              /* target IP address            */
531 };
532
533 void arp_input(const uint8_t *pkt, int pkt_len)
534 {
535     struct ethhdr *eh = (struct ethhdr *)pkt;
536     struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
537     uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
538     struct ethhdr *reh = (struct ethhdr *)arp_reply;
539     struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
540     int ar_op;
541
542     ar_op = ntohs(ah->ar_op);
543     switch(ar_op) {
544     case ARPOP_REQUEST:
545         if (!memcmp(ah->ar_tip, &special_addr, 3) &&
546             (ah->ar_tip[3] == CTL_DNS || ah->ar_tip[3] == CTL_ALIAS)) {
547
548             /* XXX: make an ARP request to have the client address */
549             memcpy(client_ethaddr, eh->h_source, ETH_ALEN);
550
551             /* ARP request for alias/dns mac address */
552             memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
553             memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
554             reh->h_source[5] = ah->ar_tip[3];
555             reh->h_proto = htons(ETH_P_ARP);
556
557             rah->ar_hrd = htons(1);
558             rah->ar_pro = htons(ETH_P_IP);
559             rah->ar_hln = ETH_ALEN;
560             rah->ar_pln = 4;
561             rah->ar_op = htons(ARPOP_REPLY);
562             memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
563             memcpy(rah->ar_sip, ah->ar_tip, 4);
564             memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
565             memcpy(rah->ar_tip, ah->ar_sip, 4);
566             slirp_output(arp_reply, sizeof(arp_reply));
567         }
568         break;
569     default:
570         break;
571     }
572 }
573
574 void slirp_input(const uint8_t *pkt, int pkt_len)
575 {
576     struct mbuf *m;
577     int proto;
578
579     if (pkt_len < ETH_HLEN)
580         return;
581     
582     proto = ntohs(*(uint16_t *)(pkt + 12));
583     switch(proto) {
584     case ETH_P_ARP:
585         arp_input(pkt, pkt_len);
586         break;
587     case ETH_P_IP:
588         m = m_get();
589         if (!m)
590             return;
591         m->m_len = pkt_len;
592         memcpy(m->m_data, pkt, pkt_len);
593
594         m->m_data += ETH_HLEN;
595         m->m_len -= ETH_HLEN;
596
597         ip_input(m);
598         break;
599     default:
600         break;
601     }
602 }
603
604 /* output the IP packet to the ethernet device */
605 void if_encap(const uint8_t *ip_data, int ip_data_len)
606 {
607     uint8_t buf[1600];
608     struct ethhdr *eh = (struct ethhdr *)buf;
609
610     if (ip_data_len + ETH_HLEN > sizeof(buf))
611         return;
612
613     memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
614     memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1);
615     eh->h_source[5] = CTL_ALIAS;
616     eh->h_proto = htons(ETH_P_IP);
617     memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
618     slirp_output(buf, ip_data_len + ETH_HLEN);
619 }