sctputil.c (170462) | sctputil.c (170606) |
---|---|
1/*- 2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. --- 17 unchanged lines hidden (view full) --- 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31/* $KAME: sctputil.c,v 1.37 2005/03/07 23:26:09 itojun Exp $ */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. --- 17 unchanged lines hidden (view full) --- 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31/* $KAME: sctputil.c,v 1.37 2005/03/07 23:26:09 itojun Exp $ */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 170462 2007-06-09 13:46:57Z rrs $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 170606 2007-06-12 11:21:00Z rrs $"); |
35 36#include <netinet/sctp_os.h> 37#include <netinet/sctp_pcb.h> 38#include <netinet/sctputil.h> 39#include <netinet/sctp_var.h> 40#include <netinet/sctp_sysctl.h> 41#ifdef INET6 42#include <netinet6/sctp6_var.h> --- 5829 unchanged lines hidden (view full) --- 5872 if ((at + incr) > (size_t)limit) { 5873 *totaddr = i; 5874 break; 5875 } 5876 sa = (struct sockaddr *)((caddr_t)sa + incr); 5877 } 5878 return ((struct sctp_tcb *)NULL); 5879} | 35 36#include <netinet/sctp_os.h> 37#include <netinet/sctp_pcb.h> 38#include <netinet/sctputil.h> 39#include <netinet/sctp_var.h> 40#include <netinet/sctp_sysctl.h> 41#ifdef INET6 42#include <netinet6/sctp6_var.h> --- 5829 unchanged lines hidden (view full) --- 5872 if ((at + incr) > (size_t)limit) { 5873 *totaddr = i; 5874 break; 5875 } 5876 sa = (struct sockaddr *)((caddr_t)sa + incr); 5877 } 5878 return ((struct sctp_tcb *)NULL); 5879} |
5880 5881 5882/* 5883 * sctp_bindx(ADD) for one address. 5884 * assumes all arguments are valid/checked by caller. 5885 */ 5886void 5887sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp, 5888 struct sockaddr *sa, sctp_assoc_t assoc_id, 5889 uint32_t vrf_id, int *error, void *p) 5890{ 5891 struct sockaddr *addr_touse; 5892 struct sockaddr_in sin; 5893 5894 /* see if we're bound all already! */ 5895 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 5896 *error = EINVAL; 5897 return; 5898 } 5899 addr_touse = sa; 5900#if defined(INET6) 5901 if (sa->sa_family == AF_INET6) { 5902 struct sockaddr_in6 *sin6; 5903 5904 if (sa->sa_len != sizeof(struct sockaddr_in6)) { 5905 *error = EINVAL; 5906 return; 5907 } 5908 sin6 = (struct sockaddr_in6 *)addr_touse; 5909 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 5910 in6_sin6_2_sin(&sin, sin6); 5911 addr_touse = (struct sockaddr *)&sin; 5912 } 5913 } 5914#endif 5915 if (sa->sa_family == AF_INET) { 5916 if (sa->sa_len != sizeof(struct sockaddr_in)) { 5917 *error = EINVAL; 5918 return; 5919 } 5920 } 5921 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) { 5922 if (p == NULL) { 5923 /* Can't get proc for Net/Open BSD */ 5924 *error = EINVAL; 5925 return; 5926 } 5927 *error = sctp_inpcb_bind(so, addr_touse, p); 5928 return; 5929 } 5930 /* 5931 * No locks required here since bind and mgmt_ep_sa all do their own 5932 * locking. If we do something for the FIX: below we may need to 5933 * lock in that case. 5934 */ 5935 if (assoc_id == 0) { 5936 /* add the address */ 5937 struct sctp_inpcb *lep; 5938 5939 ((struct sockaddr_in *)addr_touse)->sin_port = inp->sctp_lport; 5940 lep = sctp_pcb_findep(addr_touse, 1, 0, vrf_id); 5941 if (lep != NULL) { 5942 /* 5943 * We must decrement the refcount since we have the 5944 * ep already and are binding. No remove going on 5945 * here. 5946 */ 5947 SCTP_INP_DECR_REF(inp); 5948 } 5949 if (lep == inp) { 5950 /* already bound to it.. ok */ 5951 return; 5952 } else if (lep == NULL) { 5953 ((struct sockaddr_in *)addr_touse)->sin_port = 0; 5954 *error = sctp_addr_mgmt_ep_sa(inp, addr_touse, 5955 SCTP_ADD_IP_ADDRESS, 5956 vrf_id); 5957 } else { 5958 *error = EADDRINUSE; 5959 } 5960 if (*error) 5961 return; 5962 } else { 5963 /* 5964 * FIX: decide whether we allow assoc based bindx 5965 */ 5966 } 5967} 5968 5969/* 5970 * sctp_bindx(DELETE) for one address. 5971 * assumes all arguments are valid/checked by caller. 5972 */ 5973void 5974sctp_bindx_delete_address(struct socket *so, struct sctp_inpcb *inp, 5975 struct sockaddr *sa, sctp_assoc_t assoc_id, 5976 uint32_t vrf_id, int *error) 5977{ 5978 struct sockaddr *addr_touse; 5979 struct sockaddr_in sin; 5980 5981 /* see if we're bound all already! */ 5982 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 5983 *error = EINVAL; 5984 return; 5985 } 5986 addr_touse = sa; 5987#if defined(INET6) 5988 if (sa->sa_family == AF_INET6) { 5989 struct sockaddr_in6 *sin6; 5990 5991 if (sa->sa_len != sizeof(struct sockaddr_in6)) { 5992 *error = EINVAL; 5993 return; 5994 } 5995 sin6 = (struct sockaddr_in6 *)addr_touse; 5996 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 5997 in6_sin6_2_sin(&sin, sin6); 5998 addr_touse = (struct sockaddr *)&sin; 5999 } 6000 } 6001#endif 6002 if (sa->sa_family == AF_INET) { 6003 if (sa->sa_len != sizeof(struct sockaddr_in)) { 6004 *error = EINVAL; 6005 return; 6006 } 6007 } 6008 /* 6009 * No lock required mgmt_ep_sa does its own locking. If the FIX: 6010 * below is ever changed we may need to lock before calling 6011 * association level binding. 6012 */ 6013 if (assoc_id == 0) { 6014 /* delete the address */ 6015 *error = sctp_addr_mgmt_ep_sa(inp, addr_touse, 6016 SCTP_DEL_IP_ADDRESS, 6017 vrf_id); 6018 } else { 6019 /* 6020 * FIX: decide whether we allow assoc based bindx 6021 */ 6022 } 6023} |
|