These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / slirp / ip_input.c
1 /*
2  * Copyright (c) 1982, 1986, 1988, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  *      @(#)ip_input.c  8.2 (Berkeley) 1/4/94
30  * ip_input.c,v 1.11 1994/11/16 10:17:08 jkh Exp
31  */
32
33 /*
34  * Changes and additions relating to SLiRP are
35  * Copyright (c) 1995 Danny Gasparovski.
36  *
37  * Please read the file COPYRIGHT for the
38  * terms and conditions of the copyright.
39  */
40
41 #include "qemu/osdep.h"
42 #include <slirp.h>
43 #include <qemu/osdep.h>
44 #include "ip_icmp.h"
45
46 static struct ip *ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp);
47 static void ip_freef(Slirp *slirp, struct ipq *fp);
48 static void ip_enq(register struct ipasfrag *p,
49                    register struct ipasfrag *prev);
50 static void ip_deq(register struct ipasfrag *p);
51
52 /*
53  * IP initialization: fill in IP protocol switch table.
54  * All protocols not implemented in kernel go to raw IP protocol handler.
55  */
56 void
57 ip_init(Slirp *slirp)
58 {
59     slirp->ipq.ip_link.next = slirp->ipq.ip_link.prev = &slirp->ipq.ip_link;
60     udp_init(slirp);
61     tcp_init(slirp);
62     icmp_init(slirp);
63 }
64
65 void ip_cleanup(Slirp *slirp)
66 {
67     udp_cleanup(slirp);
68     tcp_cleanup(slirp);
69     icmp_cleanup(slirp);
70 }
71
72 /*
73  * Ip input routine.  Checksum and byte swap header.  If fragmented
74  * try to reassemble.  Process options.  Pass to next level.
75  */
76 void
77 ip_input(struct mbuf *m)
78 {
79         Slirp *slirp = m->slirp;
80         register struct ip *ip;
81         int hlen;
82
83         if (!slirp->in_enabled) {
84                 goto bad;
85         }
86
87         DEBUG_CALL("ip_input");
88         DEBUG_ARG("m = %p", m);
89         DEBUG_ARG("m_len = %d", m->m_len);
90
91         if (m->m_len < sizeof (struct ip)) {
92                 goto bad;
93         }
94
95         ip = mtod(m, struct ip *);
96
97         if (ip->ip_v != IPVERSION) {
98                 goto bad;
99         }
100
101         hlen = ip->ip_hl << 2;
102         if (hlen<sizeof(struct ip ) || hlen>m->m_len) {/* min header length */
103           goto bad;                                  /* or packet too short */
104         }
105
106         /* keep ip header intact for ICMP reply
107          * ip->ip_sum = cksum(m, hlen);
108          * if (ip->ip_sum) {
109          */
110         if(cksum(m,hlen)) {
111           goto bad;
112         }
113
114         /*
115          * Convert fields to host representation.
116          */
117         NTOHS(ip->ip_len);
118         if (ip->ip_len < hlen) {
119                 goto bad;
120         }
121         NTOHS(ip->ip_id);
122         NTOHS(ip->ip_off);
123
124         /*
125          * Check that the amount of data in the buffers
126          * is as at least much as the IP header would have us expect.
127          * Trim mbufs if longer than we expect.
128          * Drop packet if shorter than we expect.
129          */
130         if (m->m_len < ip->ip_len) {
131                 goto bad;
132         }
133
134         /* Should drop packet if mbuf too long? hmmm... */
135         if (m->m_len > ip->ip_len)
136            m_adj(m, ip->ip_len - m->m_len);
137
138         /* check ip_ttl for a correct ICMP reply */
139         if (ip->ip_ttl == 0) {
140             icmp_send_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, "ttl");
141             goto bad;
142         }
143
144         /*
145          * If offset or IP_MF are set, must reassemble.
146          * Otherwise, nothing need be done.
147          * (We could look in the reassembly queue to see
148          * if the packet was previously fragmented,
149          * but it's not worth the time; just let them time out.)
150          *
151          * XXX This should fail, don't fragment yet
152          */
153         if (ip->ip_off &~ IP_DF) {
154           register struct ipq *fp;
155       struct qlink *l;
156                 /*
157                  * Look for queue of fragments
158                  * of this datagram.
159                  */
160                 for (l = slirp->ipq.ip_link.next; l != &slirp->ipq.ip_link;
161                      l = l->next) {
162             fp = container_of(l, struct ipq, ip_link);
163             if (ip->ip_id == fp->ipq_id &&
164                     ip->ip_src.s_addr == fp->ipq_src.s_addr &&
165                     ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&
166                     ip->ip_p == fp->ipq_p)
167                     goto found;
168         }
169         fp = NULL;
170         found:
171
172                 /*
173                  * Adjust ip_len to not reflect header,
174                  * set ip_mff if more fragments are expected,
175                  * convert offset of this to bytes.
176                  */
177                 ip->ip_len -= hlen;
178                 if (ip->ip_off & IP_MF)
179                   ip->ip_tos |= 1;
180                 else
181                   ip->ip_tos &= ~1;
182
183                 ip->ip_off <<= 3;
184
185                 /*
186                  * If datagram marked as having more fragments
187                  * or if this is not the first fragment,
188                  * attempt reassembly; if it succeeds, proceed.
189                  */
190                 if (ip->ip_tos & 1 || ip->ip_off) {
191                         ip = ip_reass(slirp, ip, fp);
192                         if (ip == NULL)
193                                 return;
194                         m = dtom(slirp, ip);
195                 } else
196                         if (fp)
197                            ip_freef(slirp, fp);
198
199         } else
200                 ip->ip_len -= hlen;
201
202         /*
203          * Switch out to protocol's input routine.
204          */
205         switch (ip->ip_p) {
206          case IPPROTO_TCP:
207                 tcp_input(m, hlen, (struct socket *)NULL, AF_INET);
208                 break;
209          case IPPROTO_UDP:
210                 udp_input(m, hlen);
211                 break;
212          case IPPROTO_ICMP:
213                 icmp_input(m, hlen);
214                 break;
215          default:
216                 m_free(m);
217         }
218         return;
219 bad:
220         m_free(m);
221 }
222
223 #define iptofrag(P) ((struct ipasfrag *)(((char*)(P)) - sizeof(struct qlink)))
224 #define fragtoip(P) ((struct ip*)(((char*)(P)) + sizeof(struct qlink)))
225 /*
226  * Take incoming datagram fragment and try to
227  * reassemble it into whole datagram.  If a chain for
228  * reassembly of this datagram already exists, then it
229  * is given as fp; otherwise have to make a chain.
230  */
231 static struct ip *
232 ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp)
233 {
234         register struct mbuf *m = dtom(slirp, ip);
235         register struct ipasfrag *q;
236         int hlen = ip->ip_hl << 2;
237         int i, next;
238
239         DEBUG_CALL("ip_reass");
240         DEBUG_ARG("ip = %p", ip);
241         DEBUG_ARG("fp = %p", fp);
242         DEBUG_ARG("m = %p", m);
243
244         /*
245          * Presence of header sizes in mbufs
246          * would confuse code below.
247          * Fragment m_data is concatenated.
248          */
249         m->m_data += hlen;
250         m->m_len -= hlen;
251
252         /*
253          * If first fragment to arrive, create a reassembly queue.
254          */
255         if (fp == NULL) {
256           struct mbuf *t = m_get(slirp);
257
258           if (t == NULL) {
259               goto dropfrag;
260           }
261           fp = mtod(t, struct ipq *);
262           insque(&fp->ip_link, &slirp->ipq.ip_link);
263           fp->ipq_ttl = IPFRAGTTL;
264           fp->ipq_p = ip->ip_p;
265           fp->ipq_id = ip->ip_id;
266           fp->frag_link.next = fp->frag_link.prev = &fp->frag_link;
267           fp->ipq_src = ip->ip_src;
268           fp->ipq_dst = ip->ip_dst;
269           q = (struct ipasfrag *)fp;
270           goto insert;
271         }
272
273         /*
274          * Find a segment which begins after this one does.
275          */
276         for (q = fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link;
277             q = q->ipf_next)
278                 if (q->ipf_off > ip->ip_off)
279                         break;
280
281         /*
282          * If there is a preceding segment, it may provide some of
283          * our data already.  If so, drop the data from the incoming
284          * segment.  If it provides all of our data, drop us.
285          */
286         if (q->ipf_prev != &fp->frag_link) {
287         struct ipasfrag *pq = q->ipf_prev;
288                 i = pq->ipf_off + pq->ipf_len - ip->ip_off;
289                 if (i > 0) {
290                         if (i >= ip->ip_len)
291                                 goto dropfrag;
292                         m_adj(dtom(slirp, ip), i);
293                         ip->ip_off += i;
294                         ip->ip_len -= i;
295                 }
296         }
297
298         /*
299          * While we overlap succeeding segments trim them or,
300          * if they are completely covered, dequeue them.
301          */
302         while (q != (struct ipasfrag*)&fp->frag_link &&
303             ip->ip_off + ip->ip_len > q->ipf_off) {
304                 i = (ip->ip_off + ip->ip_len) - q->ipf_off;
305                 if (i < q->ipf_len) {
306                         q->ipf_len -= i;
307                         q->ipf_off += i;
308                         m_adj(dtom(slirp, q), i);
309                         break;
310                 }
311                 q = q->ipf_next;
312                 m_free(dtom(slirp, q->ipf_prev));
313                 ip_deq(q->ipf_prev);
314         }
315
316 insert:
317         /*
318          * Stick new segment in its place;
319          * check for complete reassembly.
320          */
321         ip_enq(iptofrag(ip), q->ipf_prev);
322         next = 0;
323         for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link;
324             q = q->ipf_next) {
325                 if (q->ipf_off != next)
326                         return NULL;
327                 next += q->ipf_len;
328         }
329         if (((struct ipasfrag *)(q->ipf_prev))->ipf_tos & 1)
330                 return NULL;
331
332         /*
333          * Reassembly is complete; concatenate fragments.
334          */
335     q = fp->frag_link.next;
336         m = dtom(slirp, q);
337
338         q = (struct ipasfrag *) q->ipf_next;
339         while (q != (struct ipasfrag*)&fp->frag_link) {
340           struct mbuf *t = dtom(slirp, q);
341           q = (struct ipasfrag *) q->ipf_next;
342           m_cat(m, t);
343         }
344
345         /*
346          * Create header for new ip packet by
347          * modifying header of first packet;
348          * dequeue and discard fragment reassembly header.
349          * Make header visible.
350          */
351         q = fp->frag_link.next;
352
353         /*
354          * If the fragments concatenated to an mbuf that's
355          * bigger than the total size of the fragment, then and
356          * m_ext buffer was alloced. But fp->ipq_next points to
357          * the old buffer (in the mbuf), so we must point ip
358          * into the new buffer.
359          */
360         if (m->m_flags & M_EXT) {
361           int delta = (char *)q - m->m_dat;
362           q = (struct ipasfrag *)(m->m_ext + delta);
363         }
364
365     ip = fragtoip(q);
366         ip->ip_len = next;
367         ip->ip_tos &= ~1;
368         ip->ip_src = fp->ipq_src;
369         ip->ip_dst = fp->ipq_dst;
370         remque(&fp->ip_link);
371         (void) m_free(dtom(slirp, fp));
372         m->m_len += (ip->ip_hl << 2);
373         m->m_data -= (ip->ip_hl << 2);
374
375         return ip;
376
377 dropfrag:
378         m_free(m);
379         return NULL;
380 }
381
382 /*
383  * Free a fragment reassembly header and all
384  * associated datagrams.
385  */
386 static void
387 ip_freef(Slirp *slirp, struct ipq *fp)
388 {
389         register struct ipasfrag *q, *p;
390
391         for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link; q = p) {
392                 p = q->ipf_next;
393                 ip_deq(q);
394                 m_free(dtom(slirp, q));
395         }
396         remque(&fp->ip_link);
397         (void) m_free(dtom(slirp, fp));
398 }
399
400 /*
401  * Put an ip fragment on a reassembly chain.
402  * Like insque, but pointers in middle of structure.
403  */
404 static void
405 ip_enq(register struct ipasfrag *p, register struct ipasfrag *prev)
406 {
407         DEBUG_CALL("ip_enq");
408         DEBUG_ARG("prev = %p", prev);
409         p->ipf_prev =  prev;
410         p->ipf_next = prev->ipf_next;
411         ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = p;
412         prev->ipf_next = p;
413 }
414
415 /*
416  * To ip_enq as remque is to insque.
417  */
418 static void
419 ip_deq(register struct ipasfrag *p)
420 {
421         ((struct ipasfrag *)(p->ipf_prev))->ipf_next = p->ipf_next;
422         ((struct ipasfrag *)(p->ipf_next))->ipf_prev = p->ipf_prev;
423 }
424
425 /*
426  * IP timer processing;
427  * if a timer expires on a reassembly
428  * queue, discard it.
429  */
430 void
431 ip_slowtimo(Slirp *slirp)
432 {
433     struct qlink *l;
434
435         DEBUG_CALL("ip_slowtimo");
436
437     l = slirp->ipq.ip_link.next;
438
439         if (l == NULL)
440            return;
441
442     while (l != &slirp->ipq.ip_link) {
443         struct ipq *fp = container_of(l, struct ipq, ip_link);
444         l = l->next;
445                 if (--fp->ipq_ttl == 0) {
446                         ip_freef(slirp, fp);
447                 }
448     }
449 }
450
451 /*
452  * Do option processing on a datagram,
453  * possibly discarding it if bad options are encountered,
454  * or forwarding it if source-routed.
455  * Returns 1 if packet has been forwarded/freed,
456  * 0 if the packet should be processed further.
457  */
458
459 #ifdef notdef
460
461 int
462 ip_dooptions(m)
463         struct mbuf *m;
464 {
465         register struct ip *ip = mtod(m, struct ip *);
466         register u_char *cp;
467         register struct ip_timestamp *ipt;
468         register struct in_ifaddr *ia;
469         int opt, optlen, cnt, off, code, type, forward = 0;
470         struct in_addr *sin, dst;
471 typedef uint32_t n_time;
472         n_time ntime;
473
474         dst = ip->ip_dst;
475         cp = (u_char *)(ip + 1);
476         cnt = (ip->ip_hl << 2) - sizeof (struct ip);
477         for (; cnt > 0; cnt -= optlen, cp += optlen) {
478                 opt = cp[IPOPT_OPTVAL];
479                 if (opt == IPOPT_EOL)
480                         break;
481                 if (opt == IPOPT_NOP)
482                         optlen = 1;
483                 else {
484                         optlen = cp[IPOPT_OLEN];
485                         if (optlen <= 0 || optlen > cnt) {
486                                 code = &cp[IPOPT_OLEN] - (u_char *)ip;
487                                 goto bad;
488                         }
489                 }
490                 switch (opt) {
491
492                 default:
493                         break;
494
495                 /*
496                  * Source routing with record.
497                  * Find interface with current destination address.
498                  * If none on this machine then drop if strictly routed,
499                  * or do nothing if loosely routed.
500                  * Record interface address and bring up next address
501                  * component.  If strictly routed make sure next
502                  * address is on directly accessible net.
503                  */
504                 case IPOPT_LSRR:
505                 case IPOPT_SSRR:
506                         if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
507                                 code = &cp[IPOPT_OFFSET] - (u_char *)ip;
508                                 goto bad;
509                         }
510                         ipaddr.sin_addr = ip->ip_dst;
511                         ia = (struct in_ifaddr *)
512                                 ifa_ifwithaddr((struct sockaddr *)&ipaddr);
513                         if (ia == 0) {
514                                 if (opt == IPOPT_SSRR) {
515                                         type = ICMP_UNREACH;
516                                         code = ICMP_UNREACH_SRCFAIL;
517                                         goto bad;
518                                 }
519                                 /*
520                                  * Loose routing, and not at next destination
521                                  * yet; nothing to do except forward.
522                                  */
523                                 break;
524                         }
525                         off--; /* 0 origin */
526                         if (off > optlen - sizeof(struct in_addr)) {
527                                 /*
528                                  * End of source route.  Should be for us.
529                                  */
530                                 save_rte(cp, ip->ip_src);
531                                 break;
532                         }
533                         /*
534                          * locate outgoing interface
535                          */
536                         bcopy((caddr_t)(cp + off), (caddr_t)&ipaddr.sin_addr,
537                             sizeof(ipaddr.sin_addr));
538                         if (opt == IPOPT_SSRR) {
539 #define INA     struct in_ifaddr *
540 #define SA      struct sockaddr *
541                             if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == 0)
542                                 ia = (INA)ifa_ifwithnet((SA)&ipaddr);
543                         } else
544                                 ia = ip_rtaddr(ipaddr.sin_addr);
545                         if (ia == 0) {
546                                 type = ICMP_UNREACH;
547                                 code = ICMP_UNREACH_SRCFAIL;
548                                 goto bad;
549                         }
550                         ip->ip_dst = ipaddr.sin_addr;
551                         bcopy((caddr_t)&(IA_SIN(ia)->sin_addr),
552                             (caddr_t)(cp + off), sizeof(struct in_addr));
553                         cp[IPOPT_OFFSET] += sizeof(struct in_addr);
554                         /*
555                          * Let ip_intr's mcast routing check handle mcast pkts
556                          */
557                         forward = !IN_MULTICAST(ntohl(ip->ip_dst.s_addr));
558                         break;
559
560                 case IPOPT_RR:
561                         if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
562                                 code = &cp[IPOPT_OFFSET] - (u_char *)ip;
563                                 goto bad;
564                         }
565                         /*
566                          * If no space remains, ignore.
567                          */
568                         off--; /* 0 origin */
569                         if (off > optlen - sizeof(struct in_addr))
570                                 break;
571                         bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr,
572                             sizeof(ipaddr.sin_addr));
573                         /*
574                          * locate outgoing interface; if we're the destination,
575                          * use the incoming interface (should be same).
576                          */
577                         if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == 0 &&
578                             (ia = ip_rtaddr(ipaddr.sin_addr)) == 0) {
579                                 type = ICMP_UNREACH;
580                                 code = ICMP_UNREACH_HOST;
581                                 goto bad;
582                         }
583                         bcopy((caddr_t)&(IA_SIN(ia)->sin_addr),
584                             (caddr_t)(cp + off), sizeof(struct in_addr));
585                         cp[IPOPT_OFFSET] += sizeof(struct in_addr);
586                         break;
587
588                 case IPOPT_TS:
589                         code = cp - (u_char *)ip;
590                         ipt = (struct ip_timestamp *)cp;
591                         if (ipt->ipt_len < 5)
592                                 goto bad;
593                         if (ipt->ipt_ptr > ipt->ipt_len - sizeof (int32_t)) {
594                                 if (++ipt->ipt_oflw == 0)
595                                         goto bad;
596                                 break;
597                         }
598                         sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1);
599                         switch (ipt->ipt_flg) {
600
601                         case IPOPT_TS_TSONLY:
602                                 break;
603
604                         case IPOPT_TS_TSANDADDR:
605                                 if (ipt->ipt_ptr + sizeof(n_time) +
606                                     sizeof(struct in_addr) > ipt->ipt_len)
607                                         goto bad;
608                                 ipaddr.sin_addr = dst;
609                                 ia = (INA)ifaof_ i f p foraddr((SA)&ipaddr,
610                                                             m->m_pkthdr.rcvif);
611                                 if (ia == 0)
612                                         continue;
613                                 bcopy((caddr_t)&IA_SIN(ia)->sin_addr,
614                                     (caddr_t)sin, sizeof(struct in_addr));
615                                 ipt->ipt_ptr += sizeof(struct in_addr);
616                                 break;
617
618                         case IPOPT_TS_PRESPEC:
619                                 if (ipt->ipt_ptr + sizeof(n_time) +
620                                     sizeof(struct in_addr) > ipt->ipt_len)
621                                         goto bad;
622                                 bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr,
623                                     sizeof(struct in_addr));
624                                 if (ifa_ifwithaddr((SA)&ipaddr) == 0)
625                                         continue;
626                                 ipt->ipt_ptr += sizeof(struct in_addr);
627                                 break;
628
629                         default:
630                                 goto bad;
631                         }
632                         ntime = iptime();
633                         bcopy((caddr_t)&ntime, (caddr_t)cp + ipt->ipt_ptr - 1,
634                             sizeof(n_time));
635                         ipt->ipt_ptr += sizeof(n_time);
636                 }
637         }
638         if (forward) {
639                 ip_forward(m, 1);
640                 return (1);
641         }
642         return (0);
643 bad:
644         icmp_send_error(m, type, code, 0, 0);
645
646         return (1);
647 }
648
649 #endif /* notdef */
650
651 /*
652  * Strip out IP options, at higher
653  * level protocol in the kernel.
654  * Second argument is buffer to which options
655  * will be moved, and return value is their length.
656  * (XXX) should be deleted; last arg currently ignored.
657  */
658 void
659 ip_stripoptions(register struct mbuf *m, struct mbuf *mopt)
660 {
661         register int i;
662         struct ip *ip = mtod(m, struct ip *);
663         register caddr_t opts;
664         int olen;
665
666         olen = (ip->ip_hl<<2) - sizeof (struct ip);
667         opts = (caddr_t)(ip + 1);
668         i = m->m_len - (sizeof (struct ip) + olen);
669         memcpy(opts, opts  + olen, (unsigned)i);
670         m->m_len -= olen;
671
672         ip->ip_hl = sizeof(struct ip) >> 2;
673 }