]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/netinet/raw_ip.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / netinet / raw_ip.c
1 /*-
2  * Copyright (c) 1982, 1986, 1988, 1993
3  *      The Regents of the University of California.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 4. Neither the name of the University nor the names of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  *      @(#)raw_ip.c    8.7 (Berkeley) 5/15/95
31  */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include "opt_inet6.h"
37 #include "opt_ipsec.h"
38 #include "opt_mac.h"
39
40 #include <sys/param.h>
41 #include <sys/jail.h>
42 #include <sys/kernel.h>
43 #include <sys/lock.h>
44 #include <sys/malloc.h>
45 #include <sys/mbuf.h>
46 #include <sys/priv.h>
47 #include <sys/proc.h>
48 #include <sys/protosw.h>
49 #include <sys/signalvar.h>
50 #include <sys/socket.h>
51 #include <sys/socketvar.h>
52 #include <sys/sx.h>
53 #include <sys/sysctl.h>
54 #include <sys/systm.h>
55
56 #include <vm/uma.h>
57
58 #include <net/if.h>
59 #include <net/route.h>
60
61 #include <netinet/in.h>
62 #include <netinet/in_systm.h>
63 #include <netinet/in_pcb.h>
64 #include <netinet/in_var.h>
65 #include <netinet/ip.h>
66 #include <netinet/ip_var.h>
67 #include <netinet/ip_mroute.h>
68
69 #include <netinet/ip_fw.h>
70 #include <netinet/ip_dummynet.h>
71
72 #ifdef IPSEC
73 #include <netipsec/ipsec.h>
74 #endif /*IPSEC*/
75
76 #include <security/mac/mac_framework.h>
77
78 struct  inpcbhead ripcb;
79 struct  inpcbinfo ripcbinfo;
80
81 /* control hooks for ipfw and dummynet */
82 ip_fw_ctl_t *ip_fw_ctl_ptr = NULL;
83 ip_dn_ctl_t *ip_dn_ctl_ptr = NULL;
84
85 /*
86  * Hooks for multicast routing. They all default to NULL, so leave them not
87  * initialized and rely on BSS being set to 0.
88  */
89
90 /*
91  * The socket used to communicate with the multicast routing daemon.
92  */
93 struct socket  *ip_mrouter;
94
95 /*
96  * The various mrouter and rsvp functions.
97  */
98 int (*ip_mrouter_set)(struct socket *, struct sockopt *);
99 int (*ip_mrouter_get)(struct socket *, struct sockopt *);
100 int (*ip_mrouter_done)(void);
101 int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
102                    struct ip_moptions *);
103 int (*mrt_ioctl)(int, caddr_t, int);
104 int (*legal_vif_num)(int);
105 u_long (*ip_mcast_src)(int);
106
107 void (*rsvp_input_p)(struct mbuf *m, int off);
108 int (*ip_rsvp_vif)(struct socket *, struct sockopt *);
109 void (*ip_rsvp_force_done)(struct socket *);
110
111 /*
112  * Hash functions
113  */
114
115 #define INP_PCBHASH_RAW_SIZE    256
116 #define INP_PCBHASH_RAW(proto, laddr, faddr, mask) \
117         (((proto) + (laddr) + (faddr)) % (mask) + 1)
118
119 static void
120 rip_inshash(struct inpcb *inp)
121 {
122         struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
123         struct inpcbhead *pcbhash;
124         int hash;
125
126         INP_INFO_WLOCK_ASSERT(pcbinfo);
127         INP_WLOCK_ASSERT(inp);
128         
129         if (inp->inp_ip_p != 0 &&
130             inp->inp_laddr.s_addr != INADDR_ANY &&
131             inp->inp_faddr.s_addr != INADDR_ANY) {
132                 hash = INP_PCBHASH_RAW(inp->inp_ip_p, inp->inp_laddr.s_addr,
133                     inp->inp_faddr.s_addr, pcbinfo->ipi_hashmask);
134         } else
135                 hash = 0;
136         pcbhash = &pcbinfo->ipi_hashbase[hash];
137         LIST_INSERT_HEAD(pcbhash, inp, inp_hash);
138 }
139
140 static void
141 rip_delhash(struct inpcb *inp)
142 {
143
144         INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo);
145         INP_WLOCK_ASSERT(inp);
146
147         LIST_REMOVE(inp, inp_hash);
148 }
149
150 /*
151  * Raw interface to IP protocol.
152  */
153
154 /*
155  * Initialize raw connection block q.
156  */
157 static void
158 rip_zone_change(void *tag)
159 {
160
161         uma_zone_set_max(ripcbinfo.ipi_zone, maxsockets);
162 }
163
164 static int
165 rip_inpcb_init(void *mem, int size, int flags)
166 {
167         struct inpcb *inp = mem;
168
169         INP_LOCK_INIT(inp, "inp", "rawinp");
170         return (0);
171 }
172
173 void
174 rip_init(void)
175 {
176
177         INP_INFO_LOCK_INIT(&ripcbinfo, "rip");
178         LIST_INIT(&ripcb);
179         ripcbinfo.ipi_listhead = &ripcb;
180         ripcbinfo.ipi_hashbase = hashinit(INP_PCBHASH_RAW_SIZE, M_PCB,
181             &ripcbinfo.ipi_hashmask);
182         ripcbinfo.ipi_porthashbase = hashinit(1, M_PCB,
183             &ripcbinfo.ipi_porthashmask);
184         ripcbinfo.ipi_zone = uma_zcreate("ripcb", sizeof(struct inpcb),
185             NULL, NULL, rip_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
186         uma_zone_set_max(ripcbinfo.ipi_zone, maxsockets);
187         EVENTHANDLER_REGISTER(maxsockets_change, rip_zone_change, NULL,
188             EVENTHANDLER_PRI_ANY);
189 }
190
191 static int
192 rip_append(struct inpcb *last, struct ip *ip, struct mbuf *n,
193     struct sockaddr_in *ripsrc)
194 {
195         int policyfail = 0;
196
197         INP_RLOCK_ASSERT(last);
198
199 #ifdef IPSEC
200         /* check AH/ESP integrity. */
201         if (ipsec4_in_reject(n, last)) {
202                 policyfail = 1;
203         }
204 #endif /* IPSEC */
205 #ifdef MAC
206         if (!policyfail && mac_check_inpcb_deliver(last, n) != 0)
207                 policyfail = 1;
208 #endif
209         /* Check the minimum TTL for socket. */
210         if (last->inp_ip_minttl && last->inp_ip_minttl > ip->ip_ttl)
211                 policyfail = 1;
212         if (!policyfail) {
213                 struct mbuf *opts = NULL;
214                 struct socket *so;
215
216                 so = last->inp_socket;
217                 if ((last->inp_flags & INP_CONTROLOPTS) ||
218                     (so->so_options & (SO_TIMESTAMP | SO_BINTIME)))
219                         ip_savecontrol(last, &opts, ip, n);
220                 SOCKBUF_LOCK(&so->so_rcv);
221                 if (sbappendaddr_locked(&so->so_rcv,
222                     (struct sockaddr *)ripsrc, n, opts) == 0) {
223                         /* should notify about lost packet */
224                         m_freem(n);
225                         if (opts)
226                                 m_freem(opts);
227                         SOCKBUF_UNLOCK(&so->so_rcv);
228                 } else
229                         sorwakeup_locked(so);
230         } else
231                 m_freem(n);
232         return (policyfail);
233 }
234
235 /*
236  * Setup generic address and protocol structures for raw_input routine, then
237  * pass them along with mbuf chain.
238  */
239 void
240 rip_input(struct mbuf *m, int off)
241 {
242         struct ip *ip = mtod(m, struct ip *);
243         int proto = ip->ip_p;
244         struct inpcb *inp, *last;
245         struct sockaddr_in ripsrc;
246         int hash;
247
248         bzero(&ripsrc, sizeof(ripsrc));
249         ripsrc.sin_len = sizeof(ripsrc);
250         ripsrc.sin_family = AF_INET;
251         ripsrc.sin_addr = ip->ip_src;
252         last = NULL;
253         hash = INP_PCBHASH_RAW(proto, ip->ip_src.s_addr,
254             ip->ip_dst.s_addr, ripcbinfo.ipi_hashmask);
255         INP_INFO_RLOCK(&ripcbinfo);
256         LIST_FOREACH(inp, &ripcbinfo.ipi_hashbase[hash], inp_hash) {
257                 if (inp->inp_ip_p != proto)
258                         continue;
259 #ifdef INET6
260                 /* XXX inp locking */
261                 if ((inp->inp_vflag & INP_IPV4) == 0)
262                         continue;
263 #endif
264                 if (inp->inp_laddr.s_addr != ip->ip_dst.s_addr)
265                         continue;
266                 if (inp->inp_faddr.s_addr != ip->ip_src.s_addr)
267                         continue;
268                 if (prison_check_ip4(inp->inp_cred, &ip->ip_dst) != 0)
269                         continue;
270                 if (last) {
271                         struct mbuf *n;
272
273                         n = m_copy(m, 0, (int)M_COPYALL);
274                         if (n != NULL)
275                             (void) rip_append(last, ip, n, &ripsrc);
276                         /* XXX count dropped packet */
277                         INP_RUNLOCK(last);
278                 }
279                 INP_RLOCK(inp);
280                 last = inp;
281         }
282         LIST_FOREACH(inp, &ripcbinfo.ipi_hashbase[0], inp_hash) {
283                 if (inp->inp_ip_p && inp->inp_ip_p != proto)
284                         continue;
285 #ifdef INET6
286                 /* XXX inp locking */
287                 if ((inp->inp_vflag & INP_IPV4) == 0)
288                         continue;
289 #endif
290                 if (inp->inp_laddr.s_addr &&
291                     inp->inp_laddr.s_addr != ip->ip_dst.s_addr)
292                         continue;
293                 if (inp->inp_faddr.s_addr &&
294                     inp->inp_faddr.s_addr != ip->ip_src.s_addr)
295                         continue;
296                 if (prison_check_ip4(inp->inp_cred, &ip->ip_dst) != 0)
297                         continue;
298                 if (last) {
299                         struct mbuf *n;
300
301                         n = m_copy(m, 0, (int)M_COPYALL);
302                         if (n != NULL)
303                                 (void) rip_append(last, ip, n, &ripsrc);
304                         /* XXX count dropped packet */
305                         INP_RUNLOCK(last);
306                 }
307                 INP_RLOCK(inp);
308                 last = inp;
309         }
310         INP_INFO_RUNLOCK(&ripcbinfo);
311         if (last != NULL) {
312                 if (rip_append(last, ip, m, &ripsrc) != 0)
313                         ipstat.ips_delivered--;
314                 INP_RUNLOCK(last);
315         } else {
316                 m_freem(m);
317                 ipstat.ips_noproto++;
318                 ipstat.ips_delivered--;
319         }
320 }
321
322 /*
323  * Generate IP header and pass packet to ip_output.  Tack on options user may
324  * have setup with control call.
325  */
326 int
327 rip_output(struct mbuf *m, struct socket *so, u_long dst)
328 {
329         struct ip *ip;
330         int error;
331         struct inpcb *inp = sotoinpcb(so);
332         int flags = ((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0) |
333             IP_ALLOWBROADCAST;
334
335         /*
336          * If the user handed us a complete IP packet, use it.  Otherwise,
337          * allocate an mbuf for a header and fill it in.
338          */
339         if ((inp->inp_flags & INP_HDRINCL) == 0) {
340                 if (m->m_pkthdr.len + sizeof(struct ip) > IP_MAXPACKET) {
341                         m_freem(m);
342                         return(EMSGSIZE);
343                 }
344                 M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
345                 if (m == NULL)
346                         return(ENOBUFS);
347
348                 INP_RLOCK(inp);
349                 ip = mtod(m, struct ip *);
350                 ip->ip_tos = inp->inp_ip_tos;
351                 if (inp->inp_flags & INP_DONTFRAG)
352                         ip->ip_off = IP_DF;
353                 else
354                         ip->ip_off = 0;
355                 ip->ip_p = inp->inp_ip_p;
356                 ip->ip_len = m->m_pkthdr.len;
357                 ip->ip_src = inp->inp_laddr;
358                 error = prison_get_ip4(inp->inp_cred, &ip->ip_src);
359                 if (error != 0) {
360                         INP_RUNLOCK(inp);
361                         m_freem(m);
362                         return (error);
363                 }
364                 ip->ip_dst.s_addr = dst;
365                 ip->ip_ttl = inp->inp_ip_ttl;
366         } else {
367                 if (m->m_pkthdr.len > IP_MAXPACKET) {
368                         m_freem(m);
369                         return(EMSGSIZE);
370                 }
371                 INP_RLOCK(inp);
372                 ip = mtod(m, struct ip *);
373                 error = prison_check_ip4(inp->inp_cred, &ip->ip_src);
374                 if (error != 0) {
375                         INP_RUNLOCK(inp);
376                         m_freem(m);
377                         return (error);
378                 }
379
380                 /*
381                  * Don't allow both user specified and setsockopt options,
382                  * and don't allow packet length sizes that will crash.
383                  */
384                 if (((ip->ip_hl != (sizeof (*ip) >> 2)) && inp->inp_options)
385                     || (ip->ip_len > m->m_pkthdr.len)
386                     || (ip->ip_len < (ip->ip_hl << 2))) {
387                         INP_RUNLOCK(inp);
388                         m_freem(m);
389                         return (EINVAL);
390                 }
391                 if (ip->ip_id == 0)
392                         ip->ip_id = ip_newid();
393
394                 /*
395                  * XXX prevent ip_output from overwriting header fields.
396                  */
397                 flags |= IP_RAWOUTPUT;
398                 ipstat.ips_rawout++;
399         }
400
401         if (inp->inp_flags & INP_ONESBCAST)
402                 flags |= IP_SENDONES;
403
404 #ifdef MAC
405         mac_create_mbuf_from_inpcb(inp, m);
406 #endif
407
408         error = ip_output(m, inp->inp_options, NULL, flags,
409             inp->inp_moptions, inp);
410         INP_RUNLOCK(inp);
411         return (error);
412 }
413
414 /*
415  * Raw IP socket option processing.
416  *
417  * IMPORTANT NOTE regarding access control: Traditionally, raw sockets could
418  * only be created by a privileged process, and as such, socket option
419  * operations to manage system properties on any raw socket were allowed to
420  * take place without explicit additional access control checks.  However,
421  * raw sockets can now also be created in jail(), and therefore explicit
422  * checks are now required.  Likewise, raw sockets can be used by a process
423  * after it gives up privilege, so some caution is required.  For options
424  * passed down to the IP layer via ip_ctloutput(), checks are assumed to be
425  * performed in ip_ctloutput() and therefore no check occurs here.
426  * Unilaterally checking priv_check() here breaks normal IP socket option
427  * operations on raw sockets.
428  *
429  * When adding new socket options here, make sure to add access control
430  * checks here as necessary.
431  */
432 int
433 rip_ctloutput(struct socket *so, struct sockopt *sopt)
434 {
435         struct  inpcb *inp = sotoinpcb(so);
436         int     error, optval;
437
438         if (sopt->sopt_level != IPPROTO_IP) {
439                 if ((sopt->sopt_level == SOL_SOCKET) &&
440                     (sopt->sopt_name == SO_SETFIB)) {
441                         inp->inp_inc.inc_fibnum = so->so_fibnum;
442                         return (0);
443                 }
444                 return (EINVAL);
445         }
446
447         error = 0;
448         switch (sopt->sopt_dir) {
449         case SOPT_GET:
450                 switch (sopt->sopt_name) {
451                 case IP_HDRINCL:
452                         optval = inp->inp_flags & INP_HDRINCL;
453                         error = sooptcopyout(sopt, &optval, sizeof optval);
454                         break;
455
456                 case IP_FW_ADD: /* ADD actually returns the body... */
457                 case IP_FW_GET:
458                 case IP_FW_TABLE_GETSIZE:
459                 case IP_FW_TABLE_LIST:
460                 case IP_FW_NAT_GET_CONFIG:
461                 case IP_FW_NAT_GET_LOG:
462                         if (ip_fw_ctl_ptr != NULL)
463                                 error = ip_fw_ctl_ptr(sopt);
464                         else
465                                 error = ENOPROTOOPT;
466                         break;
467
468                 case IP_DUMMYNET_GET:
469                         if (ip_dn_ctl_ptr != NULL)
470                                 error = ip_dn_ctl_ptr(sopt);
471                         else
472                                 error = ENOPROTOOPT;
473                         break ;
474
475                 case MRT_INIT:
476                 case MRT_DONE:
477                 case MRT_ADD_VIF:
478                 case MRT_DEL_VIF:
479                 case MRT_ADD_MFC:
480                 case MRT_DEL_MFC:
481                 case MRT_VERSION:
482                 case MRT_ASSERT:
483                 case MRT_API_SUPPORT:
484                 case MRT_API_CONFIG:
485                 case MRT_ADD_BW_UPCALL:
486                 case MRT_DEL_BW_UPCALL:
487                         error = priv_check(curthread, PRIV_NETINET_MROUTE);
488                         if (error != 0)
489                                 return (error);
490                         error = ip_mrouter_get ? ip_mrouter_get(so, sopt) :
491                                 EOPNOTSUPP;
492                         break;
493
494                 default:
495                         error = ip_ctloutput(so, sopt);
496                         break;
497                 }
498                 break;
499
500         case SOPT_SET:
501                 switch (sopt->sopt_name) {
502                 case IP_HDRINCL:
503                         error = sooptcopyin(sopt, &optval, sizeof optval,
504                                             sizeof optval);
505                         if (error)
506                                 break;
507                         if (optval)
508                                 inp->inp_flags |= INP_HDRINCL;
509                         else
510                                 inp->inp_flags &= ~INP_HDRINCL;
511                         break;
512
513                 case IP_FW_ADD:
514                 case IP_FW_DEL:
515                 case IP_FW_FLUSH:
516                 case IP_FW_ZERO:
517                 case IP_FW_RESETLOG:
518                 case IP_FW_TABLE_ADD:
519                 case IP_FW_TABLE_DEL:
520                 case IP_FW_TABLE_FLUSH:
521                 case IP_FW_NAT_CFG:
522                 case IP_FW_NAT_DEL:
523                         if (ip_fw_ctl_ptr != NULL)
524                                 error = ip_fw_ctl_ptr(sopt);
525                         else
526                                 error = ENOPROTOOPT;
527                         break;
528
529                 case IP_DUMMYNET_CONFIGURE:
530                 case IP_DUMMYNET_DEL:
531                 case IP_DUMMYNET_FLUSH:
532                         if (ip_dn_ctl_ptr != NULL)
533                                 error = ip_dn_ctl_ptr(sopt);
534                         else
535                                 error = ENOPROTOOPT ;
536                         break ;
537
538                 case IP_RSVP_ON:
539                         error = priv_check(curthread, PRIV_NETINET_MROUTE);
540                         if (error != 0)
541                                 return (error);
542                         error = ip_rsvp_init(so);
543                         break;
544
545                 case IP_RSVP_OFF:
546                         error = priv_check(curthread, PRIV_NETINET_MROUTE);
547                         if (error != 0)
548                                 return (error);
549                         error = ip_rsvp_done();
550                         break;
551
552                 case IP_RSVP_VIF_ON:
553                 case IP_RSVP_VIF_OFF:
554                         error = priv_check(curthread, PRIV_NETINET_MROUTE);
555                         if (error != 0)
556                                 return (error);
557                         error = ip_rsvp_vif ?
558                                 ip_rsvp_vif(so, sopt) : EINVAL;
559                         break;
560
561                 case MRT_INIT:
562                 case MRT_DONE:
563                 case MRT_ADD_VIF:
564                 case MRT_DEL_VIF:
565                 case MRT_ADD_MFC:
566                 case MRT_DEL_MFC:
567                 case MRT_VERSION:
568                 case MRT_ASSERT:
569                 case MRT_API_SUPPORT:
570                 case MRT_API_CONFIG:
571                 case MRT_ADD_BW_UPCALL:
572                 case MRT_DEL_BW_UPCALL:
573                         error = priv_check(curthread, PRIV_NETINET_MROUTE);
574                         if (error != 0)
575                                 return (error);
576                         error = ip_mrouter_set ? ip_mrouter_set(so, sopt) :
577                                         EOPNOTSUPP;
578                         break;
579
580                 default:
581                         error = ip_ctloutput(so, sopt);
582                         break;
583                 }
584                 break;
585         }
586
587         return (error);
588 }
589
590 /*
591  * This function exists solely to receive the PRC_IFDOWN messages which are
592  * sent by if_down().  It looks for an ifaddr whose ifa_addr is sa, and calls
593  * in_ifadown() to remove all routes corresponding to that address.  It also
594  * receives the PRC_IFUP messages from if_up() and reinstalls the interface
595  * routes.
596  */
597 void
598 rip_ctlinput(int cmd, struct sockaddr *sa, void *vip)
599 {
600         struct in_ifaddr *ia;
601         struct ifnet *ifp;
602         int err;
603         int flags;
604
605         switch (cmd) {
606         case PRC_IFDOWN:
607                 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) {
608                         if (ia->ia_ifa.ifa_addr == sa
609                             && (ia->ia_flags & IFA_ROUTE)) {
610                                 /*
611                                  * in_ifscrub kills the interface route.
612                                  */
613                                 in_ifscrub(ia->ia_ifp, ia);
614                                 /*
615                                  * in_ifadown gets rid of all the rest of the
616                                  * routes.  This is not quite the right thing
617                                  * to do, but at least if we are running a
618                                  * routing process they will come back.
619                                  */
620                                 in_ifadown(&ia->ia_ifa, 0);
621                                 break;
622                         }
623                 }
624                 break;
625
626         case PRC_IFUP:
627                 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) {
628                         if (ia->ia_ifa.ifa_addr == sa)
629                                 break;
630                 }
631                 if (ia == 0 || (ia->ia_flags & IFA_ROUTE))
632                         return;
633                 flags = RTF_UP;
634                 ifp = ia->ia_ifa.ifa_ifp;
635
636                 if ((ifp->if_flags & IFF_LOOPBACK)
637                     || (ifp->if_flags & IFF_POINTOPOINT))
638                         flags |= RTF_HOST;
639
640                 err = rtinit(&ia->ia_ifa, RTM_ADD, flags);
641                 if (err == 0)
642                         ia->ia_flags |= IFA_ROUTE;
643                 break;
644         }
645 }
646
647 u_long  rip_sendspace = 9216;
648 u_long  rip_recvspace = 9216;
649
650 SYSCTL_ULONG(_net_inet_raw, OID_AUTO, maxdgram, CTLFLAG_RW,
651     &rip_sendspace, 0, "Maximum outgoing raw IP datagram size");
652 SYSCTL_ULONG(_net_inet_raw, OID_AUTO, recvspace, CTLFLAG_RW,
653     &rip_recvspace, 0, "Maximum space for incoming raw IP datagrams");
654
655 static int
656 rip_attach(struct socket *so, int proto, struct thread *td)
657 {
658         struct inpcb *inp;
659         int error;
660
661         inp = sotoinpcb(so);
662         KASSERT(inp == NULL, ("rip_attach: inp != NULL"));
663
664         error = priv_check(td, PRIV_NETINET_RAW);
665         if (error)
666                 return (error);
667         if (proto >= IPPROTO_MAX || proto < 0)
668                 return EPROTONOSUPPORT;
669         error = soreserve(so, rip_sendspace, rip_recvspace);
670         if (error)
671                 return (error);
672         INP_INFO_WLOCK(&ripcbinfo);
673         error = in_pcballoc(so, &ripcbinfo);
674         if (error) {
675                 INP_INFO_WUNLOCK(&ripcbinfo);
676                 return (error);
677         }
678         inp = (struct inpcb *)so->so_pcb;
679         inp->inp_vflag |= INP_IPV4;
680         inp->inp_ip_p = proto;
681         inp->inp_ip_ttl = ip_defttl;
682         rip_inshash(inp);
683         INP_INFO_WUNLOCK(&ripcbinfo);
684         INP_WUNLOCK(inp);
685         return (0);
686 }
687
688 static void
689 rip_detach(struct socket *so)
690 {
691         struct inpcb *inp;
692
693         inp = sotoinpcb(so);
694         KASSERT(inp != NULL, ("rip_detach: inp == NULL"));
695         KASSERT(inp->inp_faddr.s_addr == INADDR_ANY, 
696             ("rip_detach: not closed"));
697
698         INP_INFO_WLOCK(&ripcbinfo);
699         INP_WLOCK(inp);
700         rip_delhash(inp);
701         if (so == ip_mrouter && ip_mrouter_done)
702                 ip_mrouter_done();
703         if (ip_rsvp_force_done)
704                 ip_rsvp_force_done(so);
705         if (so == ip_rsvpd)
706                 ip_rsvp_done();
707         in_pcbdetach(inp);
708         in_pcbfree(inp);
709         INP_INFO_WUNLOCK(&ripcbinfo);
710 }
711
712 static void
713 rip_dodisconnect(struct socket *so, struct inpcb *inp)
714 {
715
716         INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo);
717         INP_WLOCK_ASSERT(inp);
718
719         rip_delhash(inp);
720         inp->inp_faddr.s_addr = INADDR_ANY;
721         rip_inshash(inp);
722         SOCK_LOCK(so);
723         so->so_state &= ~SS_ISCONNECTED;
724         SOCK_UNLOCK(so);
725 }
726
727 static void
728 rip_abort(struct socket *so)
729 {
730         struct inpcb *inp;
731
732         inp = sotoinpcb(so);
733         KASSERT(inp != NULL, ("rip_abort: inp == NULL"));
734
735         INP_INFO_WLOCK(&ripcbinfo);
736         INP_WLOCK(inp);
737         rip_dodisconnect(so, inp);
738         INP_WUNLOCK(inp);
739         INP_INFO_WUNLOCK(&ripcbinfo);
740 }
741
742 static void
743 rip_close(struct socket *so)
744 {
745         struct inpcb *inp;
746
747         inp = sotoinpcb(so);
748         KASSERT(inp != NULL, ("rip_close: inp == NULL"));
749
750         INP_INFO_WLOCK(&ripcbinfo);
751         INP_WLOCK(inp);
752         rip_dodisconnect(so, inp);
753         INP_WUNLOCK(inp);
754         INP_INFO_WUNLOCK(&ripcbinfo);
755 }
756
757 static int
758 rip_disconnect(struct socket *so)
759 {
760         struct inpcb *inp;
761
762         if ((so->so_state & SS_ISCONNECTED) == 0)
763                 return (ENOTCONN);
764
765         inp = sotoinpcb(so);
766         KASSERT(inp != NULL, ("rip_disconnect: inp == NULL"));
767
768         INP_INFO_WLOCK(&ripcbinfo);
769         INP_WLOCK(inp);
770         rip_dodisconnect(so, inp);
771         INP_WUNLOCK(inp);
772         INP_INFO_WUNLOCK(&ripcbinfo);
773         return (0);
774 }
775
776 static int
777 rip_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
778 {
779         struct sockaddr_in *addr = (struct sockaddr_in *)nam;
780         struct inpcb *inp;
781         int error;
782
783         if (nam->sa_len != sizeof(*addr))
784                 return (EINVAL);
785
786         error = prison_check_ip4(td->td_ucred, &addr->sin_addr);
787         if (error != 0)
788                 return (error);
789
790         if (TAILQ_EMPTY(&ifnet) ||
791             (addr->sin_family != AF_INET && addr->sin_family != AF_IMPLINK) ||
792             (addr->sin_addr.s_addr &&
793              ifa_ifwithaddr((struct sockaddr *)addr) == 0))
794                 return (EADDRNOTAVAIL);
795
796         inp = sotoinpcb(so);
797         KASSERT(inp != NULL, ("rip_bind: inp == NULL"));
798
799         INP_INFO_WLOCK(&ripcbinfo);
800         INP_WLOCK(inp);
801         rip_delhash(inp);
802         inp->inp_laddr = addr->sin_addr;
803         rip_inshash(inp);
804         INP_WUNLOCK(inp);
805         INP_INFO_WUNLOCK(&ripcbinfo);
806         return (0);
807 }
808
809 static int
810 rip_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
811 {
812         struct sockaddr_in *addr = (struct sockaddr_in *)nam;
813         struct inpcb *inp;
814
815         if (nam->sa_len != sizeof(*addr))
816                 return (EINVAL);
817         if (TAILQ_EMPTY(&ifnet))
818                 return (EADDRNOTAVAIL);
819         if (addr->sin_family != AF_INET && addr->sin_family != AF_IMPLINK)
820                 return (EAFNOSUPPORT);
821
822         inp = sotoinpcb(so);
823         KASSERT(inp != NULL, ("rip_connect: inp == NULL"));
824
825         INP_INFO_WLOCK(&ripcbinfo);
826         INP_WLOCK(inp);
827         rip_delhash(inp);
828         inp->inp_faddr = addr->sin_addr;
829         rip_inshash(inp);
830         soisconnected(so);
831         INP_WUNLOCK(inp);
832         INP_INFO_WUNLOCK(&ripcbinfo);
833         return (0);
834 }
835
836 static int
837 rip_shutdown(struct socket *so)
838 {
839         struct inpcb *inp;
840
841         inp = sotoinpcb(so);
842         KASSERT(inp != NULL, ("rip_shutdown: inp == NULL"));
843
844         INP_WLOCK(inp);
845         socantsendmore(so);
846         INP_WUNLOCK(inp);
847         return (0);
848 }
849
850 static int
851 rip_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
852     struct mbuf *control, struct thread *td)
853 {
854         struct inpcb *inp;
855         u_long dst;
856
857         inp = sotoinpcb(so);
858         KASSERT(inp != NULL, ("rip_send: inp == NULL"));
859
860         /*
861          * Note: 'dst' reads below are unlocked.
862          */
863         if (so->so_state & SS_ISCONNECTED) {
864                 if (nam) {
865                         m_freem(m);
866                         return (EISCONN);
867                 }
868                 dst = inp->inp_faddr.s_addr;    /* Unlocked read. */
869         } else {
870                 if (nam == NULL) {
871                         m_freem(m);
872                         return (ENOTCONN);
873                 }
874                 dst = ((struct sockaddr_in *)nam)->sin_addr.s_addr;
875         }
876         return (rip_output(m, so, dst));
877 }
878
879 static int
880 rip_pcblist(SYSCTL_HANDLER_ARGS)
881 {
882         int error, i, n;
883         struct inpcb *inp, **inp_list;
884         inp_gen_t gencnt;
885         struct xinpgen xig;
886
887         /*
888          * The process of preparing the TCB list is too time-consuming and
889          * resource-intensive to repeat twice on every request.
890          */
891         if (req->oldptr == 0) {
892                 n = ripcbinfo.ipi_count;
893                 req->oldidx = 2 * (sizeof xig)
894                     + (n + n/8) * sizeof(struct xinpcb);
895                 return (0);
896         }
897
898         if (req->newptr != 0)
899                 return (EPERM);
900
901         /*
902          * OK, now we're committed to doing something.
903          */
904         INP_INFO_RLOCK(&ripcbinfo);
905         gencnt = ripcbinfo.ipi_gencnt;
906         n = ripcbinfo.ipi_count;
907         INP_INFO_RUNLOCK(&ripcbinfo);
908
909         xig.xig_len = sizeof xig;
910         xig.xig_count = n;
911         xig.xig_gen = gencnt;
912         xig.xig_sogen = so_gencnt;
913         error = SYSCTL_OUT(req, &xig, sizeof xig);
914         if (error)
915                 return (error);
916
917         inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK);
918         if (inp_list == 0)
919                 return (ENOMEM);
920
921         INP_INFO_RLOCK(&ripcbinfo);
922         for (inp = LIST_FIRST(ripcbinfo.ipi_listhead), i = 0; inp && i < n;
923              inp = LIST_NEXT(inp, inp_list)) {
924                 INP_RLOCK(inp);
925                 if (inp->inp_gencnt <= gencnt &&
926                     cr_canseeinpcb(req->td->td_ucred, inp) == 0) {
927                         /* XXX held references? */
928                         inp_list[i++] = inp;
929                 }
930                 INP_RUNLOCK(inp);
931         }
932         INP_INFO_RUNLOCK(&ripcbinfo);
933         n = i;
934
935         error = 0;
936         for (i = 0; i < n; i++) {
937                 inp = inp_list[i];
938                 INP_RLOCK(inp);
939                 if (inp->inp_gencnt <= gencnt) {
940                         struct xinpcb xi;
941                         bzero(&xi, sizeof(xi));
942                         xi.xi_len = sizeof xi;
943                         /* XXX should avoid extra copy */
944                         bcopy(inp, &xi.xi_inp, sizeof *inp);
945                         if (inp->inp_socket)
946                                 sotoxsocket(inp->inp_socket, &xi.xi_socket);
947                         INP_RUNLOCK(inp);
948                         error = SYSCTL_OUT(req, &xi, sizeof xi);
949                 } else
950                         INP_RUNLOCK(inp);
951         }
952         if (!error) {
953                 /*
954                  * Give the user an updated idea of our state.  If the
955                  * generation differs from what we told her before, she knows
956                  * that something happened while we were processing this
957                  * request, and it might be necessary to retry.
958                  */
959                 INP_INFO_RLOCK(&ripcbinfo);
960                 xig.xig_gen = ripcbinfo.ipi_gencnt;
961                 xig.xig_sogen = so_gencnt;
962                 xig.xig_count = ripcbinfo.ipi_count;
963                 INP_INFO_RUNLOCK(&ripcbinfo);
964                 error = SYSCTL_OUT(req, &xig, sizeof xig);
965         }
966         free(inp_list, M_TEMP);
967         return (error);
968 }
969
970 SYSCTL_PROC(_net_inet_raw, OID_AUTO/*XXX*/, pcblist, CTLFLAG_RD, 0, 0,
971     rip_pcblist, "S,xinpcb", "List of active raw IP sockets");
972
973 struct pr_usrreqs rip_usrreqs = {
974         .pru_abort =            rip_abort,
975         .pru_attach =           rip_attach,
976         .pru_bind =             rip_bind,
977         .pru_connect =          rip_connect,
978         .pru_control =          in_control,
979         .pru_detach =           rip_detach,
980         .pru_disconnect =       rip_disconnect,
981         .pru_peeraddr =         in_getpeeraddr,
982         .pru_send =             rip_send,
983         .pru_shutdown =         rip_shutdown,
984         .pru_sockaddr =         in_getsockaddr,
985         .pru_sosetlabel =       in_pcbsosetlabel,
986         .pru_close =            rip_close,
987 };