Deleted Added
full compact
sctp_asconf.c (228653) sctp_asconf.c (228907)
1/*-
2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2008-2011, by Randall Stewart. All rights reserved.
4 * Copyright (c) 2008-2011, by Michael Tuexen. 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 are met:
8 *

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

28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/* $KAME: sctp_asconf.c,v 1.24 2005/03/06 16:04:16 itojun Exp $ */
34
35#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2008-2011, by Randall Stewart. All rights reserved.
4 * Copyright (c) 2008-2011, by Michael Tuexen. 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 are met:
8 *

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

28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/* $KAME: sctp_asconf.c,v 1.24 2005/03/06 16:04:16 itojun Exp $ */
34
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 228653 2011-12-17 19:21:40Z tuexen $");
36__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 228907 2011-12-27 10:16:24Z tuexen $");
37#include <netinet/sctp_os.h>
38#include <netinet/sctp_var.h>
39#include <netinet/sctp_sysctl.h>
40#include <netinet/sctp_pcb.h>
41#include <netinet/sctp_header.h>
42#include <netinet/sctputil.h>
43#include <netinet/sctp_output.h>
44#include <netinet/sctp_asconf.h>

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

133 struct mbuf *m_reply = NULL;
134 struct sctp_asconf_paramhdr *aph;
135
136 m_reply = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_paramhdr),
137 0, M_DONTWAIT, 1, MT_DATA);
138 if (m_reply == NULL) {
139 SCTPDBG(SCTP_DEBUG_ASCONF1,
140 "asconf_success_response: couldn't get mbuf!\n");
37#include <netinet/sctp_os.h>
38#include <netinet/sctp_var.h>
39#include <netinet/sctp_sysctl.h>
40#include <netinet/sctp_pcb.h>
41#include <netinet/sctp_header.h>
42#include <netinet/sctputil.h>
43#include <netinet/sctp_output.h>
44#include <netinet/sctp_asconf.h>

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

133 struct mbuf *m_reply = NULL;
134 struct sctp_asconf_paramhdr *aph;
135
136 m_reply = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_paramhdr),
137 0, M_DONTWAIT, 1, MT_DATA);
138 if (m_reply == NULL) {
139 SCTPDBG(SCTP_DEBUG_ASCONF1,
140 "asconf_success_response: couldn't get mbuf!\n");
141 return NULL;
141 return (NULL);
142 }
143 aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
144 aph->correlation_id = id;
145 aph->ph.param_type = htons(SCTP_SUCCESS_REPORT);
146 aph->ph.param_length = sizeof(struct sctp_asconf_paramhdr);
147 SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
148 aph->ph.param_length = htons(aph->ph.param_length);
149
142 }
143 aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
144 aph->correlation_id = id;
145 aph->ph.param_type = htons(SCTP_SUCCESS_REPORT);
146 aph->ph.param_length = sizeof(struct sctp_asconf_paramhdr);
147 SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
148 aph->ph.param_length = htons(aph->ph.param_length);
149
150 return m_reply;
150 return (m_reply);
151}
152
153static struct mbuf *
154sctp_asconf_error_response(uint32_t id, uint16_t cause, uint8_t * error_tlv,
155 uint16_t tlv_length)
156{
157 struct mbuf *m_reply = NULL;
158 struct sctp_asconf_paramhdr *aph;
159 struct sctp_error_cause *error;
160 uint8_t *tlv;
161
162 m_reply = sctp_get_mbuf_for_msg((sizeof(struct sctp_asconf_paramhdr) +
163 tlv_length +
164 sizeof(struct sctp_error_cause)),
165 0, M_DONTWAIT, 1, MT_DATA);
166 if (m_reply == NULL) {
167 SCTPDBG(SCTP_DEBUG_ASCONF1,
168 "asconf_error_response: couldn't get mbuf!\n");
151}
152
153static struct mbuf *
154sctp_asconf_error_response(uint32_t id, uint16_t cause, uint8_t * error_tlv,
155 uint16_t tlv_length)
156{
157 struct mbuf *m_reply = NULL;
158 struct sctp_asconf_paramhdr *aph;
159 struct sctp_error_cause *error;
160 uint8_t *tlv;
161
162 m_reply = sctp_get_mbuf_for_msg((sizeof(struct sctp_asconf_paramhdr) +
163 tlv_length +
164 sizeof(struct sctp_error_cause)),
165 0, M_DONTWAIT, 1, MT_DATA);
166 if (m_reply == NULL) {
167 SCTPDBG(SCTP_DEBUG_ASCONF1,
168 "asconf_error_response: couldn't get mbuf!\n");
169 return NULL;
169 return (NULL);
170 }
171 aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
172 error = (struct sctp_error_cause *)(aph + 1);
173
174 aph->correlation_id = id;
175 aph->ph.param_type = htons(SCTP_ERROR_CAUSE_IND);
176 error->code = htons(cause);
177 error->length = tlv_length + sizeof(struct sctp_error_cause);
178 aph->ph.param_length = error->length +
179 sizeof(struct sctp_asconf_paramhdr);
180
181 if (aph->ph.param_length > MLEN) {
182 SCTPDBG(SCTP_DEBUG_ASCONF1,
183 "asconf_error_response: tlv_length (%xh) too big\n",
184 tlv_length);
185 sctp_m_freem(m_reply); /* discard */
170 }
171 aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
172 error = (struct sctp_error_cause *)(aph + 1);
173
174 aph->correlation_id = id;
175 aph->ph.param_type = htons(SCTP_ERROR_CAUSE_IND);
176 error->code = htons(cause);
177 error->length = tlv_length + sizeof(struct sctp_error_cause);
178 aph->ph.param_length = error->length +
179 sizeof(struct sctp_asconf_paramhdr);
180
181 if (aph->ph.param_length > MLEN) {
182 SCTPDBG(SCTP_DEBUG_ASCONF1,
183 "asconf_error_response: tlv_length (%xh) too big\n",
184 tlv_length);
185 sctp_m_freem(m_reply); /* discard */
186 return NULL;
186 return (NULL);
187 }
188 if (error_tlv != NULL) {
189 tlv = (uint8_t *) (error + 1);
190 memcpy(tlv, error_tlv, tlv_length);
191 }
192 SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
193 error->length = htons(error->length);
194 aph->ph.param_length = htons(aph->ph.param_length);
195
187 }
188 if (error_tlv != NULL) {
189 tlv = (uint8_t *) (error + 1);
190 memcpy(tlv, error_tlv, tlv_length);
191 }
192 SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
193 error->length = htons(error->length);
194 aph->ph.param_length = htons(aph->ph.param_length);
195
196 return m_reply;
196 return (m_reply);
197}
198
199static struct mbuf *
200sctp_process_asconf_add_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
201 struct sctp_tcb *stcb, int send_hb, int response_required)
202{
203 struct sctp_nets *net;
204 struct mbuf *m_reply = NULL;

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

226 param_length = ntohs(ph->param_length);
227
228 sa = (struct sockaddr *)&sa_store;
229 switch (param_type) {
230#ifdef INET
231 case SCTP_IPV4_ADDRESS:
232 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
233 /* invalid param size */
197}
198
199static struct mbuf *
200sctp_process_asconf_add_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
201 struct sctp_tcb *stcb, int send_hb, int response_required)
202{
203 struct sctp_nets *net;
204 struct mbuf *m_reply = NULL;

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

226 param_length = ntohs(ph->param_length);
227
228 sa = (struct sockaddr *)&sa_store;
229 switch (param_type) {
230#ifdef INET
231 case SCTP_IPV4_ADDRESS:
232 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
233 /* invalid param size */
234 return NULL;
234 return (NULL);
235 }
236 v4addr = (struct sctp_ipv4addr_param *)ph;
237 sin = (struct sockaddr_in *)&sa_store;
238 bzero(sin, sizeof(*sin));
239 sin->sin_family = AF_INET;
240 sin->sin_len = sizeof(struct sockaddr_in);
241 sin->sin_port = stcb->rport;
242 sin->sin_addr.s_addr = v4addr->addr;

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

249 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
250 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
251 break;
252#endif
253#ifdef INET6
254 case SCTP_IPV6_ADDRESS:
255 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
256 /* invalid param size */
235 }
236 v4addr = (struct sctp_ipv4addr_param *)ph;
237 sin = (struct sockaddr_in *)&sa_store;
238 bzero(sin, sizeof(*sin));
239 sin->sin_family = AF_INET;
240 sin->sin_len = sizeof(struct sockaddr_in);
241 sin->sin_port = stcb->rport;
242 sin->sin_addr.s_addr = v4addr->addr;

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

249 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
250 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
251 break;
252#endif
253#ifdef INET6
254 case SCTP_IPV6_ADDRESS:
255 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
256 /* invalid param size */
257 return NULL;
257 return (NULL);
258 }
259 v6addr = (struct sctp_ipv6addr_param *)ph;
260 sin6 = (struct sockaddr_in6 *)&sa_store;
261 bzero(sin6, sizeof(*sin6));
262 sin6->sin6_family = AF_INET6;
263 sin6->sin6_len = sizeof(struct sockaddr_in6);
264 sin6->sin6_port = stcb->rport;
265 memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,

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

272 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
273 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
274 break;
275#endif
276 default:
277 m_reply = sctp_asconf_error_response(aph->correlation_id,
278 SCTP_CAUSE_INVALID_PARAM, (uint8_t *) aph,
279 aparam_length);
258 }
259 v6addr = (struct sctp_ipv6addr_param *)ph;
260 sin6 = (struct sockaddr_in6 *)&sa_store;
261 bzero(sin6, sizeof(*sin6));
262 sin6->sin6_family = AF_INET6;
263 sin6->sin6_len = sizeof(struct sockaddr_in6);
264 sin6->sin6_port = stcb->rport;
265 memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,

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

272 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
273 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
274 break;
275#endif
276 default:
277 m_reply = sctp_asconf_error_response(aph->correlation_id,
278 SCTP_CAUSE_INVALID_PARAM, (uint8_t *) aph,
279 aparam_length);
280 return m_reply;
280 return (m_reply);
281 } /* end switch */
282
283 /* if 0.0.0.0/::0, add the source address instead */
284 if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
285 sa = (struct sockaddr *)&sa_source;
286 sctp_asconf_get_source_ip(m, sa);
287 SCTPDBG(SCTP_DEBUG_ASCONF1,
288 "process_asconf_add_ip: using source addr ");

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

309 }
310 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb, net);
311 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
312 stcb, net);
313 if (send_hb) {
314 sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
315 }
316 }
281 } /* end switch */
282
283 /* if 0.0.0.0/::0, add the source address instead */
284 if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
285 sa = (struct sockaddr *)&sa_source;
286 sctp_asconf_get_source_ip(m, sa);
287 SCTPDBG(SCTP_DEBUG_ASCONF1,
288 "process_asconf_add_ip: using source addr ");

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

309 }
310 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb, net);
311 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
312 stcb, net);
313 if (send_hb) {
314 sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
315 }
316 }
317 return m_reply;
317 return (m_reply);
318}
319
320static int
321sctp_asconf_del_remote_addrs_except(struct sctp_tcb *stcb, struct sockaddr *src)
322{
323 struct sctp_nets *src_net, *net;
324
325 /* make sure the source address exists as a destination net */
326 src_net = sctp_findnet(stcb, src);
327 if (src_net == NULL) {
328 /* not found */
318}
319
320static int
321sctp_asconf_del_remote_addrs_except(struct sctp_tcb *stcb, struct sockaddr *src)
322{
323 struct sctp_nets *src_net, *net;
324
325 /* make sure the source address exists as a destination net */
326 src_net = sctp_findnet(stcb, src);
327 if (src_net == NULL) {
328 /* not found */
329 return -1;
329 return (-1);
330 }
331 /* delete all destination addresses except the source */
332 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
333 if (net != src_net) {
334 /* delete this address */
335 sctp_remove_net(stcb, net);
336 SCTPDBG(SCTP_DEBUG_ASCONF1,
337 "asconf_del_remote_addrs_except: deleting ");
338 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1,
339 (struct sockaddr *)&net->ro._l_addr);
340 /* notify upper layer */
341 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0,
342 (struct sockaddr *)&net->ro._l_addr, SCTP_SO_NOT_LOCKED);
343 }
344 }
330 }
331 /* delete all destination addresses except the source */
332 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
333 if (net != src_net) {
334 /* delete this address */
335 sctp_remove_net(stcb, net);
336 SCTPDBG(SCTP_DEBUG_ASCONF1,
337 "asconf_del_remote_addrs_except: deleting ");
338 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1,
339 (struct sockaddr *)&net->ro._l_addr);
340 /* notify upper layer */
341 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0,
342 (struct sockaddr *)&net->ro._l_addr, SCTP_SO_NOT_LOCKED);
343 }
344 }
345 return 0;
345 return (0);
346}
347
348static struct mbuf *
349sctp_process_asconf_delete_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
350 struct sctp_tcb *stcb, int response_required)
351{
352 struct mbuf *m_reply = NULL;
353 struct sockaddr_storage sa_source, sa_store;

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

377 param_length = ntohs(ph->param_length);
378
379 sa = (struct sockaddr *)&sa_store;
380 switch (param_type) {
381#ifdef INET
382 case SCTP_IPV4_ADDRESS:
383 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
384 /* invalid param size */
346}
347
348static struct mbuf *
349sctp_process_asconf_delete_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
350 struct sctp_tcb *stcb, int response_required)
351{
352 struct mbuf *m_reply = NULL;
353 struct sockaddr_storage sa_source, sa_store;

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

377 param_length = ntohs(ph->param_length);
378
379 sa = (struct sockaddr *)&sa_store;
380 switch (param_type) {
381#ifdef INET
382 case SCTP_IPV4_ADDRESS:
383 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
384 /* invalid param size */
385 return NULL;
385 return (NULL);
386 }
387 v4addr = (struct sctp_ipv4addr_param *)ph;
388 sin = (struct sockaddr_in *)&sa_store;
389 bzero(sin, sizeof(*sin));
390 sin->sin_family = AF_INET;
391 sin->sin_len = sizeof(struct sockaddr_in);
392 sin->sin_port = stcb->rport;
393 sin->sin_addr.s_addr = v4addr->addr;
394 if (sin->sin_addr.s_addr == INADDR_ANY)
395 zero_address = 1;
396 SCTPDBG(SCTP_DEBUG_ASCONF1,
397 "process_asconf_delete_ip: deleting ");
398 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
399 break;
400#endif
401#ifdef INET6
402 case SCTP_IPV6_ADDRESS:
403 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
404 /* invalid param size */
386 }
387 v4addr = (struct sctp_ipv4addr_param *)ph;
388 sin = (struct sockaddr_in *)&sa_store;
389 bzero(sin, sizeof(*sin));
390 sin->sin_family = AF_INET;
391 sin->sin_len = sizeof(struct sockaddr_in);
392 sin->sin_port = stcb->rport;
393 sin->sin_addr.s_addr = v4addr->addr;
394 if (sin->sin_addr.s_addr == INADDR_ANY)
395 zero_address = 1;
396 SCTPDBG(SCTP_DEBUG_ASCONF1,
397 "process_asconf_delete_ip: deleting ");
398 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
399 break;
400#endif
401#ifdef INET6
402 case SCTP_IPV6_ADDRESS:
403 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
404 /* invalid param size */
405 return NULL;
405 return (NULL);
406 }
407 v6addr = (struct sctp_ipv6addr_param *)ph;
408 sin6 = (struct sockaddr_in6 *)&sa_store;
409 bzero(sin6, sizeof(*sin6));
410 sin6->sin6_family = AF_INET6;
411 sin6->sin6_len = sizeof(struct sockaddr_in6);
412 sin6->sin6_port = stcb->rport;
413 memcpy(&sin6->sin6_addr, v6addr->addr,

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

418 "process_asconf_delete_ip: deleting ");
419 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
420 break;
421#endif
422 default:
423 m_reply = sctp_asconf_error_response(aph->correlation_id,
424 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
425 aparam_length);
406 }
407 v6addr = (struct sctp_ipv6addr_param *)ph;
408 sin6 = (struct sockaddr_in6 *)&sa_store;
409 bzero(sin6, sizeof(*sin6));
410 sin6->sin6_family = AF_INET6;
411 sin6->sin6_len = sizeof(struct sockaddr_in6);
412 sin6->sin6_port = stcb->rport;
413 memcpy(&sin6->sin6_addr, v6addr->addr,

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

418 "process_asconf_delete_ip: deleting ");
419 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
420 break;
421#endif
422 default:
423 m_reply = sctp_asconf_error_response(aph->correlation_id,
424 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
425 aparam_length);
426 return m_reply;
426 return (m_reply);
427 }
428
429 /* make sure the source address is not being deleted */
430 if (sctp_cmpaddr(sa, (struct sockaddr *)&sa_source)) {
431 /* trying to delete the source address! */
432 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: tried to delete source addr\n");
433 m_reply = sctp_asconf_error_response(aph->correlation_id,
434 SCTP_CAUSE_DELETING_SRC_ADDR, (uint8_t *) aph,
435 aparam_length);
427 }
428
429 /* make sure the source address is not being deleted */
430 if (sctp_cmpaddr(sa, (struct sockaddr *)&sa_source)) {
431 /* trying to delete the source address! */
432 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: tried to delete source addr\n");
433 m_reply = sctp_asconf_error_response(aph->correlation_id,
434 SCTP_CAUSE_DELETING_SRC_ADDR, (uint8_t *) aph,
435 aparam_length);
436 return m_reply;
436 return (m_reply);
437 }
438 /* if deleting 0.0.0.0/::0, delete all addresses except src addr */
439 if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
440 result = sctp_asconf_del_remote_addrs_except(stcb,
441 (struct sockaddr *)&sa_source);
442
443 if (result) {
444 /* src address did not exist? */
445 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: src addr does not exist?\n");
446 /* what error to reply with?? */
447 m_reply =
448 sctp_asconf_error_response(aph->correlation_id,
449 SCTP_CAUSE_REQUEST_REFUSED, (uint8_t *) aph,
450 aparam_length);
451 } else if (response_required) {
452 m_reply =
453 sctp_asconf_success_response(aph->correlation_id);
454 }
437 }
438 /* if deleting 0.0.0.0/::0, delete all addresses except src addr */
439 if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
440 result = sctp_asconf_del_remote_addrs_except(stcb,
441 (struct sockaddr *)&sa_source);
442
443 if (result) {
444 /* src address did not exist? */
445 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: src addr does not exist?\n");
446 /* what error to reply with?? */
447 m_reply =
448 sctp_asconf_error_response(aph->correlation_id,
449 SCTP_CAUSE_REQUEST_REFUSED, (uint8_t *) aph,
450 aparam_length);
451 } else if (response_required) {
452 m_reply =
453 sctp_asconf_success_response(aph->correlation_id);
454 }
455 return m_reply;
455 return (m_reply);
456 }
457 /* delete the address */
458 result = sctp_del_remote_addr(stcb, sa);
459 /*
460 * note if result == -2, the address doesn't exist in the asoc but
461 * since it's being deleted anyways, we just ack the delete -- but
462 * this probably means something has already gone awry
463 */

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

469 aparam_length);
470 } else {
471 if (response_required) {
472 m_reply = sctp_asconf_success_response(aph->correlation_id);
473 }
474 /* notify upper layer */
475 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
476 }
456 }
457 /* delete the address */
458 result = sctp_del_remote_addr(stcb, sa);
459 /*
460 * note if result == -2, the address doesn't exist in the asoc but
461 * since it's being deleted anyways, we just ack the delete -- but
462 * this probably means something has already gone awry
463 */

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

469 aparam_length);
470 } else {
471 if (response_required) {
472 m_reply = sctp_asconf_success_response(aph->correlation_id);
473 }
474 /* notify upper layer */
475 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
476 }
477 return m_reply;
477 return (m_reply);
478}
479
480static struct mbuf *
481sctp_process_asconf_set_primary(struct mbuf *m,
482 struct sctp_asconf_paramhdr *aph,
483 struct sctp_tcb *stcb, int response_required)
484{
485 struct mbuf *m_reply = NULL;

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

506 param_length = ntohs(ph->param_length);
507
508 sa = (struct sockaddr *)&sa_store;
509 switch (param_type) {
510#ifdef INET
511 case SCTP_IPV4_ADDRESS:
512 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
513 /* invalid param size */
478}
479
480static struct mbuf *
481sctp_process_asconf_set_primary(struct mbuf *m,
482 struct sctp_asconf_paramhdr *aph,
483 struct sctp_tcb *stcb, int response_required)
484{
485 struct mbuf *m_reply = NULL;

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

506 param_length = ntohs(ph->param_length);
507
508 sa = (struct sockaddr *)&sa_store;
509 switch (param_type) {
510#ifdef INET
511 case SCTP_IPV4_ADDRESS:
512 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
513 /* invalid param size */
514 return NULL;
514 return (NULL);
515 }
516 v4addr = (struct sctp_ipv4addr_param *)ph;
517 sin = (struct sockaddr_in *)&sa_store;
518 bzero(sin, sizeof(*sin));
519 sin->sin_family = AF_INET;
520 sin->sin_len = sizeof(struct sockaddr_in);
521 sin->sin_addr.s_addr = v4addr->addr;
522 if (sin->sin_addr.s_addr == INADDR_ANY)
523 zero_address = 1;
524 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
525 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
526 break;
527#endif
528#ifdef INET6
529 case SCTP_IPV6_ADDRESS:
530 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
531 /* invalid param size */
515 }
516 v4addr = (struct sctp_ipv4addr_param *)ph;
517 sin = (struct sockaddr_in *)&sa_store;
518 bzero(sin, sizeof(*sin));
519 sin->sin_family = AF_INET;
520 sin->sin_len = sizeof(struct sockaddr_in);
521 sin->sin_addr.s_addr = v4addr->addr;
522 if (sin->sin_addr.s_addr == INADDR_ANY)
523 zero_address = 1;
524 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
525 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
526 break;
527#endif
528#ifdef INET6
529 case SCTP_IPV6_ADDRESS:
530 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
531 /* invalid param size */
532 return NULL;
532 return (NULL);
533 }
534 v6addr = (struct sctp_ipv6addr_param *)ph;
535 sin6 = (struct sockaddr_in6 *)&sa_store;
536 bzero(sin6, sizeof(*sin6));
537 sin6->sin6_family = AF_INET6;
538 sin6->sin6_len = sizeof(struct sockaddr_in6);
539 memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,
540 sizeof(struct in6_addr));
541 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
542 zero_address = 1;
543 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
544 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
545 break;
546#endif
547 default:
548 m_reply = sctp_asconf_error_response(aph->correlation_id,
549 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
550 aparam_length);
533 }
534 v6addr = (struct sctp_ipv6addr_param *)ph;
535 sin6 = (struct sockaddr_in6 *)&sa_store;
536 bzero(sin6, sizeof(*sin6));
537 sin6->sin6_family = AF_INET6;
538 sin6->sin6_len = sizeof(struct sockaddr_in6);
539 memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,
540 sizeof(struct in6_addr));
541 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
542 zero_address = 1;
543 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
544 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
545 break;
546#endif
547 default:
548 m_reply = sctp_asconf_error_response(aph->correlation_id,
549 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
550 aparam_length);
551 return m_reply;
551 return (m_reply);
552 }
553
554 /* if 0.0.0.0/::0, use the source address instead */
555 if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
556 sa = (struct sockaddr *)&sa_source;
557 sctp_asconf_get_source_ip(m, sa);
558 SCTPDBG(SCTP_DEBUG_ASCONF1,
559 "process_asconf_set_primary: using source addr ");

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

615 SCTPDBG(SCTP_DEBUG_ASCONF1,
616 "process_asconf_set_primary: set primary failed!\n");
617 /* must have been an invalid address, so report */
618 m_reply = sctp_asconf_error_response(aph->correlation_id,
619 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
620 aparam_length);
621 }
622
552 }
553
554 /* if 0.0.0.0/::0, use the source address instead */
555 if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
556 sa = (struct sockaddr *)&sa_source;
557 sctp_asconf_get_source_ip(m, sa);
558 SCTPDBG(SCTP_DEBUG_ASCONF1,
559 "process_asconf_set_primary: using source addr ");

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

615 SCTPDBG(SCTP_DEBUG_ASCONF1,
616 "process_asconf_set_primary: set primary failed!\n");
617 /* must have been an invalid address, so report */
618 m_reply = sctp_asconf_error_response(aph->correlation_id,
619 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
620 aparam_length);
621 }
622
623 return m_reply;
623 return (m_reply);
624}
625
626/*
627 * handles an ASCONF chunk.
628 * if all parameters are processed ok, send a plain (empty) ASCONF-ACK
629 */
630void
631sctp_handle_asconf(struct mbuf *m, unsigned int offset,

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

2525 }
2526
2527 /*
2528 * we want to find the sequences which consist of ADD -> DEL -> ADD
2529 * or DEL -> ADD
2530 */
2531 if (add_cnt > del_cnt ||
2532 (add_cnt == del_cnt && last_param_type == SCTP_ADD_IP_ADDRESS)) {
624}
625
626/*
627 * handles an ASCONF chunk.
628 * if all parameters are processed ok, send a plain (empty) ASCONF-ACK
629 */
630void
631sctp_handle_asconf(struct mbuf *m, unsigned int offset,

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

2525 }
2526
2527 /*
2528 * we want to find the sequences which consist of ADD -> DEL -> ADD
2529 * or DEL -> ADD
2530 */
2531 if (add_cnt > del_cnt ||
2532 (add_cnt == del_cnt && last_param_type == SCTP_ADD_IP_ADDRESS)) {
2533 return 1;
2533 return (1);
2534 }
2534 }
2535 return 0;
2535 return (0);
2536}
2537
2538static struct sockaddr *
2539sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
2540{
2541 struct sctp_vrf *vrf = NULL;
2542 struct sctp_ifn *sctp_ifn;
2543 struct sctp_ifa *sctp_ifa;

--- 1046 unchanged lines hidden ---
2536}
2537
2538static struct sockaddr *
2539sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
2540{
2541 struct sctp_vrf *vrf = NULL;
2542 struct sctp_ifn *sctp_ifn;
2543 struct sctp_ifa *sctp_ifa;

--- 1046 unchanged lines hidden ---