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 --- |