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