Deleted Added
full compact
sctp_bsd_addr.c (170094) sctp_bsd_addr.c (170138)
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: sctp_output.c,v 1.46 2005/03/06 16:04:17 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: sctp_output.c,v 1.46 2005/03/06 16:04:17 itojun Exp $ */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 170094 2007-05-29 11:53:27Z rrs $");
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 170138 2007-05-30 17:39:45Z rrs $");
35
36#include <netinet/sctp_os.h>
37#include <netinet/sctp_var.h>
38#include <netinet/sctp_pcb.h>
39#include <netinet/sctp_header.h>
40#include <netinet/sctputil.h>
41#include <netinet/sctp_output.h>
42#include <netinet/sctp_bsd_addr.h>

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

369 }
370#endif
371 return (m);
372}
373
374
375#ifdef SCTP_PACKET_LOGGING
376
35
36#include <netinet/sctp_os.h>
37#include <netinet/sctp_var.h>
38#include <netinet/sctp_pcb.h>
39#include <netinet/sctp_header.h>
40#include <netinet/sctputil.h>
41#include <netinet/sctp_output.h>
42#include <netinet/sctp_bsd_addr.h>

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

369 }
370#endif
371 return (m);
372}
373
374
375#ifdef SCTP_PACKET_LOGGING
376
377int packet_log_start = 0;
377int packet_log_writers = 0;
378int packet_log_end = 0;
378int packet_log_end = 0;
379int packet_log_old_end = SCTP_PACKET_LOG_SIZE;
380int packet_log_wrapped = 0;
381uint8_t packet_log_buffer[SCTP_PACKET_LOG_SIZE];
382
383
384void
385sctp_packet_log(struct mbuf *m, int length)
386{
379uint8_t packet_log_buffer[SCTP_PACKET_LOG_SIZE];
380
381
382void
383sctp_packet_log(struct mbuf *m, int length)
384{
387 int *lenat, needed, thisone;
385 int *lenat, thisone;
388 void *copyto;
389 uint32_t *tick_tock;
386 void *copyto;
387 uint32_t *tick_tock;
390 int total_len, spare;
388 int total_len;
389 int grabbed_lock = 0;
390 int value, newval, thisend, thisbegin;
391
391
392 total_len = SCTP_SIZE32((length + (2 * sizeof(int))));
392 /*
393 * Buffer layout. -sizeof this entry (total_len) -previous end
394 * (value) -ticks of log (ticks) o -ip packet o -as logged -
395 * where this started (thisbegin) x <--end points here
396 */
397 total_len = SCTP_SIZE32((length + (4 * sizeof(int))));
393 /* Log a packet to the buffer. */
394 if (total_len > SCTP_PACKET_LOG_SIZE) {
395 /* Can't log this packet I have not a buffer big enough */
396 return;
397 }
398 if (length < (SCTP_MIN_V4_OVERHEAD + sizeof(struct sctp_cookie_ack_chunk))) {
398 /* Log a packet to the buffer. */
399 if (total_len > SCTP_PACKET_LOG_SIZE) {
400 /* Can't log this packet I have not a buffer big enough */
401 return;
402 }
403 if (length < (SCTP_MIN_V4_OVERHEAD + sizeof(struct sctp_cookie_ack_chunk))) {
399 printf("Huh, length is %d to small for sctp min:%d\n",
400 length,
401 (SCTP_MIN_V4_OVERHEAD + sizeof(struct sctp_cookie_ack_chunk)));
402 return;
403 }
404 return;
405 }
404 SCTP_IP_PKTLOG_LOCK();
405 if ((SCTP_PACKET_LOG_SIZE - packet_log_end) <= total_len) {
406 /*
407 * it won't fit on the end. We must go back to the
408 * beginning. To do this we go back and cahnge
409 * packet_log_start.
410 */
411 int orig_end;
412
413 lenat = (int *)packet_log_buffer;
414 orig_end = packet_log_end;
415 packet_log_old_end = packet_log_end;
416 packet_log_end = 0;
417 if (packet_log_start > packet_log_old_end) {
418 /* calculate the head room */
419 spare = packet_log_start - packet_log_old_end;
406 atomic_add_int(&packet_log_writers, 1);
407try_again:
408 if (packet_log_writers > SCTP_PKTLOG_WRITERS_NEED_LOCK) {
409 SCTP_IP_PKTLOG_LOCK();
410 grabbed_lock = 1;
411again_locked:
412 value = packet_log_end;
413 newval = packet_log_end + total_len;
414 if (newval >= SCTP_PACKET_LOG_SIZE) {
415 /* we wrapped */
416 thisbegin = 0;
417 thisend = total_len;
420 } else {
418 } else {
421 spare = 0;
419 thisbegin = packet_log_end;
420 thisend = newval;
422 }
421 }
423 needed = total_len - spare;
424 packet_log_wrapped = 1;
425 /* Now update the start */
426 while (needed > 0) {
427 thisone = (*(int *)(&packet_log_buffer[packet_log_start]));
428 needed -= thisone;
429 if (thisone == 0) {
430 int *foo;
431
432 foo = (int *)(&packet_log_buffer[packet_log_start]);
433 goto insane;
434 }
435 /* move to next one */
436 packet_log_start += thisone;
422 if (!(atomic_cmpset_int(&packet_log_end, value, thisend))) {
423 goto again_locked;
437 }
438 } else {
424 }
425 } else {
439 lenat = (int *)&packet_log_buffer[packet_log_end];
440 if (packet_log_start > packet_log_end) {
441 if ((packet_log_end + total_len) > packet_log_start) {
442 /* Now need to update killing some packets */
443 needed = total_len - ((packet_log_start - packet_log_end));
444 while (needed > 0) {
445 thisone = (*(int *)(&packet_log_buffer[packet_log_start]));
446 needed -= thisone;
447 if (thisone == 0) {
448 goto insane;
449 }
450 /* move to next one */
451 packet_log_start += thisone;
452 if (((packet_log_start + sizeof(struct ip)) > SCTP_PACKET_LOG_SIZE) ||
453 (packet_log_wrapped && (packet_log_start >= packet_log_old_end))) {
454 packet_log_start = 0;
455 packet_log_old_end = 0;
456 packet_log_wrapped = 0;
457 break;
458 }
459 }
460 }
426 value = packet_log_end;
427 newval = packet_log_end + total_len;
428 if (newval >= SCTP_PACKET_LOG_SIZE) {
429 /* we wrapped */
430 thisbegin = 0;
431 thisend = total_len;
432 } else {
433 thisbegin = packet_log_end;
434 thisend = newval;
461 }
435 }
436 if (!(atomic_cmpset_int(&packet_log_end, value, thisend))) {
437 goto try_again;
438 }
462 }
439 }
463 if (((packet_log_end + total_len) >= SCTP_PACKET_LOG_SIZE) ||
464 ((void *)((caddr_t)lenat) < (void *)packet_log_buffer) ||
465 ((void *)((caddr_t)lenat + total_len) > (void *)&packet_log_buffer[SCTP_PACKET_LOG_SIZE])) {
466 /* Madness protection */
467insane:
468 printf("Went mad, end:%d start:%d len:%d wrapped:%d oe:%d - zapping\n",
469 packet_log_end, packet_log_start, total_len, packet_log_wrapped, packet_log_old_end);
470 packet_log_start = packet_log_end = packet_log_old_end = packet_log_wrapped = 0;
471 lenat = (int *)&packet_log_buffer[0];
440 /* Sanity check */
441 if (thisend >= SCTP_PACKET_LOG_SIZE) {
442 printf("Insanity stops a log thisbegin:%d thisend:%d writers:%d lock:%d end:%d\n",
443 thisbegin,
444 thisend,
445 packet_log_writers,
446 grabbed_lock,
447 packet_log_end);
448 packet_log_end = 0;
449 goto no_log;
450
472 }
451 }
452 lenat = (int *)&packet_log_buffer[thisbegin];
473 *lenat = total_len;
474 lenat++;
453 *lenat = total_len;
454 lenat++;
455 *lenat = value;
456 lenat++;
475 tick_tock = (uint32_t *) lenat;
476 lenat++;
477 *tick_tock = sctp_get_tick_count();
478 copyto = (void *)lenat;
457 tick_tock = (uint32_t *) lenat;
458 lenat++;
459 *tick_tock = sctp_get_tick_count();
460 copyto = (void *)lenat;
479 packet_log_end = (((caddr_t)copyto + length) - (caddr_t)packet_log_buffer);
480 SCTP_IP_PKTLOG_UNLOCK();
461 thisone = thisend - sizeof(int);
462 lenat = (int *)&packet_log_buffer[thisone];
463 *lenat = thisbegin;
464 if (grabbed_lock) {
465 SCTP_IP_PKTLOG_UNLOCK();
466 grabbed_lock = 0;
467 }
481 m_copydata(m, 0, length, (caddr_t)copyto);
468 m_copydata(m, 0, length, (caddr_t)copyto);
482
469no_log:
470 if (grabbed_lock) {
471 SCTP_IP_PKTLOG_UNLOCK();
472 }
473 atomic_subtract_int(&packet_log_writers, 1);
483}
484
485
486int
487sctp_copy_out_packet_log(uint8_t * target, int length)
488{
489 /*
490 * We wind through the packet log starting at start copying up to
491 * length bytes out. We return the number of bytes copied.
492 */
474}
475
476
477int
478sctp_copy_out_packet_log(uint8_t * target, int length)
479{
480 /*
481 * We wind through the packet log starting at start copying up to
482 * length bytes out. We return the number of bytes copied.
483 */
493 int tocopy, this_copy, copied = 0;
494 void *at;
484 int tocopy, this_copy;
485 int *lenat;
486 int did_delay = 0;
495
496 tocopy = length;
487
488 tocopy = length;
497 if (packet_log_start == packet_log_end) {
498 /* no data */
489 if (length < (2 * sizeof(int))) {
490 /* not enough room */
499 return (0);
500 }
491 return (0);
492 }
501 if (packet_log_wrapped) {
502 /*
503 * we have a wrapped buffer, we must copy from start to the
504 * old end. Then copy from the top of the buffer to the end.
505 */
506 SCTP_IP_PKTLOG_LOCK();
507 at = (void *)&packet_log_buffer[packet_log_start];
508 this_copy = min(tocopy, (packet_log_old_end - packet_log_start));
509 memcpy(target, at, this_copy);
510 tocopy -= this_copy;
511 copied += this_copy;
512 if (tocopy == 0) {
513 SCTP_IP_PKTLOG_UNLOCK();
514 return (copied);
493 if (SCTP_PKTLOG_WRITERS_NEED_LOCK) {
494 atomic_add_int(&packet_log_writers, SCTP_PKTLOG_WRITERS_NEED_LOCK);
495again:
496 if ((did_delay == 0) && (packet_log_writers != SCTP_PKTLOG_WRITERS_NEED_LOCK)) {
497 /*
498 * we delay here for just a moment hoping the
499 * writer(s) that were present when we entered will
500 * have left and we only have locking ones that will
501 * contend with us for the lock. This does not
502 * assure 100% access, but its good enough for a
503 * logging facility like this.
504 */
505 did_delay = 1;
506 DELAY(10);
507 goto again;
515 }
508 }
516 this_copy = min(tocopy, packet_log_end);
517 at = (void *)&packet_log_buffer;
518 memcpy(&target[copied], at, this_copy);
519 copied += this_copy;
520 SCTP_IP_PKTLOG_UNLOCK();
521 return (copied);
522 } else {
523 /* we have one contiguous buffer */
524 SCTP_IP_PKTLOG_LOCK();
525 at = (void *)&packet_log_buffer;
526 this_copy = min(length, packet_log_end);
527 memcpy(target, at, this_copy);
528 SCTP_IP_PKTLOG_UNLOCK();
529 return (this_copy);
530 }
509 }
510 SCTP_IP_PKTLOG_LOCK();
511 lenat = (int *)target;
512 *lenat = packet_log_end;
513 lenat++;
514 this_copy = min((length - sizeof(int)), packet_log_end);
515 memcpy((void *)lenat, (void *)packet_log_buffer, this_copy);
516 if (SCTP_PKTLOG_WRITERS_NEED_LOCK) {
517 atomic_subtract_int(&packet_log_writers, SCTP_PKTLOG_WRITERS_NEED_LOCK);
518 }
519 SCTP_IP_PKTLOG_UNLOCK();
520 return (this_copy + sizeof(int));
531}
532
533#endif
521}
522
523#endif