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