raw_ip.c (3b19fa3597e60f5525074c8f0905c7dcebf42fbe) raw_ip.c (9ed324c9a588f89a1f147114e2e02ddc765565a0)
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:

--- 95 unchanged lines hidden (view full) ---

104int (*legal_vif_num)(int);
105u_long (*ip_mcast_src)(int);
106
107void (*rsvp_input_p)(struct mbuf *m, int off);
108int (*ip_rsvp_vif)(struct socket *, struct sockopt *);
109void (*ip_rsvp_force_done)(struct socket *);
110
111/*
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:

--- 95 unchanged lines hidden (view full) ---

104int (*legal_vif_num)(int);
105u_long (*ip_mcast_src)(int);
106
107void (*rsvp_input_p)(struct mbuf *m, int off);
108int (*ip_rsvp_vif)(struct socket *, struct sockopt *);
109void (*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
119static void
120rip_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 && inp->inp_laddr.s_addr && inp->inp_faddr.s_addr) {
130 hash = INP_PCBHASH_RAW(inp->inp_ip_p, inp->inp_laddr.s_addr,
131 inp->inp_faddr.s_addr, pcbinfo->ipi_hashmask);
132 } else {
133 hash = 0;
134 }
135 pcbhash = &pcbinfo->ipi_hashbase[hash];
136 LIST_INSERT_HEAD(pcbhash, inp, inp_hash);
137}
138
139static void
140rip_delhash(struct inpcb *inp)
141{
142 INP_WLOCK_ASSERT(inp);
143 LIST_REMOVE(inp, inp_hash);
144}
145
146/*
112 * Raw interface to IP protocol.
113 */
114
115/*
116 * Initialize raw connection block q.
117 */
118static void
119rip_zone_change(void *tag)

--- 13 unchanged lines hidden (view full) ---

133
134void
135rip_init(void)
136{
137
138 INP_INFO_LOCK_INIT(&ripcbinfo, "rip");
139 LIST_INIT(&ripcb);
140 ripcbinfo.ipi_listhead = &ripcb;
147 * Raw interface to IP protocol.
148 */
149
150/*
151 * Initialize raw connection block q.
152 */
153static void
154rip_zone_change(void *tag)

--- 13 unchanged lines hidden (view full) ---

168
169void
170rip_init(void)
171{
172
173 INP_INFO_LOCK_INIT(&ripcbinfo, "rip");
174 LIST_INIT(&ripcb);
175 ripcbinfo.ipi_listhead = &ripcb;
141 /*
142 * XXX We don't use the hash list for raw IP, but it's easier to
143 * allocate a one entry hash list than it is to check all over the
144 * place for hashbase == NULL.
145 */
146 ripcbinfo.ipi_hashbase = hashinit(1, M_PCB, &ripcbinfo.ipi_hashmask);
176 ripcbinfo.ipi_hashbase = hashinit(INP_PCBHASH_RAW_SIZE, M_PCB,
177 &ripcbinfo.ipi_hashmask);
147 ripcbinfo.ipi_porthashbase = hashinit(1, M_PCB,
148 &ripcbinfo.ipi_porthashmask);
149 ripcbinfo.ipi_zone = uma_zcreate("ripcb", sizeof(struct inpcb),
150 NULL, NULL, rip_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
151 uma_zone_set_max(ripcbinfo.ipi_zone, maxsockets);
152 EVENTHANDLER_REGISTER(maxsockets_change, rip_zone_change, NULL,
153 EVENTHANDLER_PRI_ANY);
154}

--- 48 unchanged lines hidden (view full) ---

203 */
204void
205rip_input(struct mbuf *m, int off)
206{
207 struct ip *ip = mtod(m, struct ip *);
208 int proto = ip->ip_p;
209 struct inpcb *inp, *last;
210 struct sockaddr_in ripsrc;
178 ripcbinfo.ipi_porthashbase = hashinit(1, M_PCB,
179 &ripcbinfo.ipi_porthashmask);
180 ripcbinfo.ipi_zone = uma_zcreate("ripcb", sizeof(struct inpcb),
181 NULL, NULL, rip_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
182 uma_zone_set_max(ripcbinfo.ipi_zone, maxsockets);
183 EVENTHANDLER_REGISTER(maxsockets_change, rip_zone_change, NULL,
184 EVENTHANDLER_PRI_ANY);
185}

--- 48 unchanged lines hidden (view full) ---

234 */
235void
236rip_input(struct mbuf *m, int off)
237{
238 struct ip *ip = mtod(m, struct ip *);
239 int proto = ip->ip_p;
240 struct inpcb *inp, *last;
241 struct sockaddr_in ripsrc;
242 int hash;
211
212 bzero(&ripsrc, sizeof(ripsrc));
213 ripsrc.sin_len = sizeof(ripsrc);
214 ripsrc.sin_family = AF_INET;
215 ripsrc.sin_addr = ip->ip_src;
216 last = NULL;
217 INP_INFO_RLOCK(&ripcbinfo);
243
244 bzero(&ripsrc, sizeof(ripsrc));
245 ripsrc.sin_len = sizeof(ripsrc);
246 ripsrc.sin_family = AF_INET;
247 ripsrc.sin_addr = ip->ip_src;
248 last = NULL;
249 INP_INFO_RLOCK(&ripcbinfo);
218 LIST_FOREACH(inp, &ripcb, inp_list) {
250 hash = INP_PCBHASH_RAW(proto, ip->ip_src.s_addr,
251 ip->ip_dst.s_addr, ripcbinfo.ipi_hashmask);
252 LIST_FOREACH(inp, &ripcbinfo.ipi_hashbase[hash], inp_hash) {
219 INP_RLOCK(inp);
253 INP_RLOCK(inp);
254 if (inp->inp_ip_p != proto) {
255 docontinue1:
256 INP_RUNLOCK(inp);
257 continue;
258 }
259#ifdef INET6
260 if ((inp->inp_vflag & INP_IPV4) == 0)
261 goto docontinue1;
262#endif
263 if (inp->inp_laddr.s_addr != ip->ip_dst.s_addr)
264 goto docontinue1;
265 if (inp->inp_faddr.s_addr != ip->ip_src.s_addr)
266 goto docontinue1;
267 if (jailed(inp->inp_socket->so_cred) &&
268 (htonl(prison_getip(inp->inp_socket->so_cred)) !=
269 ip->ip_dst.s_addr))
270 goto docontinue1;
271 if (last) {
272 struct mbuf *n;
273
274 n = m_copy(m, 0, (int)M_COPYALL);
275 if (n != NULL)
276 (void) rip_append(last, ip, n, &ripsrc);
277 /* XXX count dropped packet */
278 INP_RUNLOCK(last);
279 }
280 last = inp;
281 }
282 LIST_FOREACH(inp, &ripcbinfo.ipi_hashbase[0], inp_hash) {
283 INP_RLOCK(inp);
220 if (inp->inp_ip_p && inp->inp_ip_p != proto) {
221 docontinue:
222 INP_RUNLOCK(inp);
223 continue;
224 }
225#ifdef INET6
226 if ((inp->inp_vflag & INP_IPV4) == 0)
227 goto docontinue;

--- 377 unchanged lines hidden (view full) ---

605 return (error);
606 INP_INFO_WLOCK(&ripcbinfo);
607 error = in_pcballoc(so, &ripcbinfo);
608 if (error) {
609 INP_INFO_WUNLOCK(&ripcbinfo);
610 return (error);
611 }
612 inp = (struct inpcb *)so->so_pcb;
284 if (inp->inp_ip_p && inp->inp_ip_p != proto) {
285 docontinue:
286 INP_RUNLOCK(inp);
287 continue;
288 }
289#ifdef INET6
290 if ((inp->inp_vflag & INP_IPV4) == 0)
291 goto docontinue;

--- 377 unchanged lines hidden (view full) ---

669 return (error);
670 INP_INFO_WLOCK(&ripcbinfo);
671 error = in_pcballoc(so, &ripcbinfo);
672 if (error) {
673 INP_INFO_WUNLOCK(&ripcbinfo);
674 return (error);
675 }
676 inp = (struct inpcb *)so->so_pcb;
613 INP_INFO_WUNLOCK(&ripcbinfo);
614 inp->inp_vflag |= INP_IPV4;
615 inp->inp_ip_p = proto;
616 inp->inp_ip_ttl = ip_defttl;
677 inp->inp_vflag |= INP_IPV4;
678 inp->inp_ip_p = proto;
679 inp->inp_ip_ttl = ip_defttl;
680 rip_inshash(inp);
681 INP_INFO_WUNLOCK(&ripcbinfo);
617 INP_WUNLOCK(inp);
618 return (0);
619}
620
621static void
622rip_detach(struct socket *so)
623{
624 struct inpcb *inp;
625
626 inp = sotoinpcb(so);
627 KASSERT(inp != NULL, ("rip_detach: inp == NULL"));
628 KASSERT(inp->inp_faddr.s_addr == INADDR_ANY,
629 ("rip_detach: not closed"));
630
631 INP_INFO_WLOCK(&ripcbinfo);
632 INP_WLOCK(inp);
682 INP_WUNLOCK(inp);
683 return (0);
684}
685
686static void
687rip_detach(struct socket *so)
688{
689 struct inpcb *inp;
690
691 inp = sotoinpcb(so);
692 KASSERT(inp != NULL, ("rip_detach: inp == NULL"));
693 KASSERT(inp->inp_faddr.s_addr == INADDR_ANY,
694 ("rip_detach: not closed"));
695
696 INP_INFO_WLOCK(&ripcbinfo);
697 INP_WLOCK(inp);
698 rip_delhash(inp);
633 if (so == ip_mrouter && ip_mrouter_done)
634 ip_mrouter_done();
635 if (ip_rsvp_force_done)
636 ip_rsvp_force_done(so);
637 if (so == ip_rsvpd)
638 ip_rsvp_done();
639 in_pcbdetach(inp);
640 in_pcbfree(inp);
641 INP_INFO_WUNLOCK(&ripcbinfo);
642}
643
644static void
645rip_dodisconnect(struct socket *so, struct inpcb *inp)
646{
699 if (so == ip_mrouter && ip_mrouter_done)
700 ip_mrouter_done();
701 if (ip_rsvp_force_done)
702 ip_rsvp_force_done(so);
703 if (so == ip_rsvpd)
704 ip_rsvp_done();
705 in_pcbdetach(inp);
706 in_pcbfree(inp);
707 INP_INFO_WUNLOCK(&ripcbinfo);
708}
709
710static void
711rip_dodisconnect(struct socket *so, struct inpcb *inp)
712{
647
648 INP_WLOCK_ASSERT(inp);
649
713 INP_WLOCK_ASSERT(inp);
714
715 rip_delhash(inp);
650 inp->inp_faddr.s_addr = INADDR_ANY;
716 inp->inp_faddr.s_addr = INADDR_ANY;
717 rip_inshash(inp);
651 SOCK_LOCK(so);
652 so->so_state &= ~SS_ISCONNECTED;
653 SOCK_UNLOCK(so);
654}
655
656static void
657rip_abort(struct socket *so)
658{

--- 66 unchanged lines hidden (view full) ---

725 ifa_ifwithaddr((struct sockaddr *)addr) == 0))
726 return (EADDRNOTAVAIL);
727
728 inp = sotoinpcb(so);
729 KASSERT(inp != NULL, ("rip_bind: inp == NULL"));
730
731 INP_INFO_WLOCK(&ripcbinfo);
732 INP_WLOCK(inp);
718 SOCK_LOCK(so);
719 so->so_state &= ~SS_ISCONNECTED;
720 SOCK_UNLOCK(so);
721}
722
723static void
724rip_abort(struct socket *so)
725{

--- 66 unchanged lines hidden (view full) ---

792 ifa_ifwithaddr((struct sockaddr *)addr) == 0))
793 return (EADDRNOTAVAIL);
794
795 inp = sotoinpcb(so);
796 KASSERT(inp != NULL, ("rip_bind: inp == NULL"));
797
798 INP_INFO_WLOCK(&ripcbinfo);
799 INP_WLOCK(inp);
800 rip_delhash(inp);
733 inp->inp_laddr = addr->sin_addr;
801 inp->inp_laddr = addr->sin_addr;
802 rip_inshash(inp);
734 INP_WUNLOCK(inp);
735 INP_INFO_WUNLOCK(&ripcbinfo);
736 return (0);
737}
738
739static int
740rip_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
741{

--- 7 unchanged lines hidden (view full) ---

749 if (addr->sin_family != AF_INET && addr->sin_family != AF_IMPLINK)
750 return (EAFNOSUPPORT);
751
752 inp = sotoinpcb(so);
753 KASSERT(inp != NULL, ("rip_connect: inp == NULL"));
754
755 INP_INFO_WLOCK(&ripcbinfo);
756 INP_WLOCK(inp);
803 INP_WUNLOCK(inp);
804 INP_INFO_WUNLOCK(&ripcbinfo);
805 return (0);
806}
807
808static int
809rip_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
810{

--- 7 unchanged lines hidden (view full) ---

818 if (addr->sin_family != AF_INET && addr->sin_family != AF_IMPLINK)
819 return (EAFNOSUPPORT);
820
821 inp = sotoinpcb(so);
822 KASSERT(inp != NULL, ("rip_connect: inp == NULL"));
823
824 INP_INFO_WLOCK(&ripcbinfo);
825 INP_WLOCK(inp);
826 rip_delhash(inp);
757 inp->inp_faddr = addr->sin_addr;
827 inp->inp_faddr = addr->sin_addr;
828 rip_inshash(inp);
758 soisconnected(so);
759 INP_WUNLOCK(inp);
760 INP_INFO_WUNLOCK(&ripcbinfo);
761 return (0);
762}
763
764static int
765rip_shutdown(struct socket *so)

--- 150 unchanged lines hidden ---
829 soisconnected(so);
830 INP_WUNLOCK(inp);
831 INP_INFO_WUNLOCK(&ripcbinfo);
832 return (0);
833}
834
835static int
836rip_shutdown(struct socket *so)

--- 150 unchanged lines hidden ---