summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_bsd_addr.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2007-05-29 09:29:03 +0000
committerrrs <rrs@FreeBSD.org>2007-05-29 09:29:03 +0000
commitf827c93ac67113093cd06e755372cf7cd9302d8f (patch)
treeb0a3898608d9bf9a7a2b4c780e734bf27af057e1 /sys/netinet/sctp_bsd_addr.c
parent0cadc213d533d92acab0d770376baacbd16de8bf (diff)
downloadFreeBSD-src-f827c93ac67113093cd06e755372cf7cd9302d8f.zip
FreeBSD-src-f827c93ac67113093cd06e755372cf7cd9302d8f.tar.gz
- Fixes so we won't try to start a timer when we
hold a wq lock for the iterator. Panda uses a silly recursive lock they hold through the timer. - Add poor mans wireshark compile option.. - Allocate and start using SCTP_M_XXX for all SCTP_MALLOC() calls. - sysctl now will get back the refcnt for viewing by onlookers. Reviewed by: gnn
Diffstat (limited to 'sys/netinet/sctp_bsd_addr.c')
-rw-r--r--sys/netinet/sctp_bsd_addr.c193
1 files changed, 193 insertions, 0 deletions
diff --git a/sys/netinet/sctp_bsd_addr.c b/sys/netinet/sctp_bsd_addr.c
index 4d6fd60..d188a12 100644
--- a/sys/netinet/sctp_bsd_addr.c
+++ b/sys/netinet/sctp_bsd_addr.c
@@ -49,6 +49,38 @@ __FBSDID("$FreeBSD$");
#include <sys/unistd.h>
+/* Declare all of our malloc named types */
+
+/* Not to Michael/Peter for mac-os,
+ * I think mac has this to since I
+ * do see the M_PCB type, so I
+ * will also put in the mac file the
+ * MALLOC_DELCARE. If this does not
+ * work for mac uncomment the defines for
+ * the strings that we use in Panda, I put
+ * them in comments in the mac-os file.
+ */
+MALLOC_DEFINE(SCTP_M_MAP, "sctp_map", "sctp asoc map descriptor");
+MALLOC_DEFINE(SCTP_M_STRMI, "sctp_stri", "sctp stream in array");
+MALLOC_DEFINE(SCTP_M_STRMO, "sctp_stro", "sctp stream out array");
+MALLOC_DEFINE(SCTP_M_ASC_ADDR, "sctp_aadr", "sctp asconf address");
+MALLOC_DEFINE(SCTP_M_ASC_IT, "sctp_a_it", "sctp asconf iterator");
+MALLOC_DEFINE(SCTP_M_AUTH_CL, "sctp_atcl", "sctp auth chunklist");
+MALLOC_DEFINE(SCTP_M_AUTH_KY, "sctp_atky", "sctp auth key");
+MALLOC_DEFINE(SCTP_M_AUTH_HL, "sctp_athm", "sctp auth hmac list");
+MALLOC_DEFINE(SCTP_M_AUTH_IF, "sctp_athi", "sctp auth info");
+MALLOC_DEFINE(SCTP_M_STRESET, "sctp_stre", "sctp stream reset");
+MALLOC_DEFINE(SCTP_M_CMSG, "sctp_cmsg", "sctp CMSG buffer");
+MALLOC_DEFINE(SCTP_M_COPYAL, "sctp_cpal", "sctp copy all");
+MALLOC_DEFINE(SCTP_M_VRF, "sctp_vrf", "sctp vrf struct");
+MALLOC_DEFINE(SCTP_M_IFA, "sctp_ifa", "sctp ifa struct");
+MALLOC_DEFINE(SCTP_M_IFN, "sctp_ifn", "sctp ifn struct");
+MALLOC_DEFINE(SCTP_M_TIMW, "sctp_timw", "sctp time block");
+MALLOC_DEFINE(SCTP_M_MVRF, "sctp_mvrf", "sctp mvrf pcb list");
+MALLOC_DEFINE(SCTP_M_ITER, "sctp_iter", "sctp iterator control");
+MALLOC_DEFINE(SCTP_M_SOCKOPT, "sctp_socko", "sctp socket option");
+
+
#if defined(SCTP_USE_THREAD_BASED_ITERATOR)
void
sctp_wakeup_iterator(void)
@@ -338,3 +370,164 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
#endif
return (m);
}
+
+
+#ifdef SCTP_PACKET_LOGGING
+
+int packet_log_start = 0;
+int packet_log_end = 0;
+int packet_log_old_end = SCTP_PACKET_LOG_SIZE;
+int packet_log_wrapped = 0;
+uint8_t packet_log_buffer[SCTP_PACKET_LOG_SIZE];
+
+
+void
+sctp_packet_log(struct mbuf *m, int length)
+{
+ int *lenat, needed, thisone;
+ void *copyto;
+ uint32_t *tick_tock;
+ int total_len, spare;
+
+ total_len = SCTP_SIZE32((length + (2 * sizeof(int))));
+ /* Log a packet to the buffer. */
+ if (total_len > SCTP_PACKET_LOG_SIZE) {
+ /* Can't log this packet I have not a buffer big enough */
+ return;
+ }
+ if (length < (SCTP_MIN_V4_OVERHEAD + sizeof(struct sctp_cookie_ack_chunk))) {
+ printf("Huh, length is %d to small for sctp min:%d\n",
+ length,
+ (SCTP_MIN_V4_OVERHEAD + sizeof(struct sctp_cookie_ack_chunk)));
+ return;
+ }
+ SCTP_IP_PKTLOG_LOCK();
+ if ((SCTP_PACKET_LOG_SIZE - packet_log_end) <= total_len) {
+ /*
+ * it won't fit on the end. We must go back to the
+ * beginning. To do this we go back and cahnge
+ * packet_log_start.
+ */
+ int orig_end;
+
+ lenat = (int *)packet_log_buffer;
+ orig_end = packet_log_end;
+ packet_log_old_end = packet_log_end;
+ packet_log_end = 0;
+ if (packet_log_start > packet_log_old_end) {
+ /* calculate the head room */
+ spare = packet_log_start - packet_log_old_end;
+ } else {
+ spare = 0;
+ }
+ needed = total_len - spare;
+ packet_log_wrapped = 1;
+ /* Now update the start */
+ while (needed > 0) {
+ thisone = (*(int *)(&packet_log_buffer[packet_log_start]));
+ needed -= thisone;
+ if (thisone == 0) {
+ int *foo;
+
+ foo = (int *)(&packet_log_buffer[packet_log_start]);
+ goto insane;
+ }
+ /* move to next one */
+ packet_log_start += thisone;
+ }
+ } else {
+ lenat = (int *)&packet_log_buffer[packet_log_end];
+ if (packet_log_start > packet_log_end) {
+ if ((packet_log_end + total_len) > packet_log_start) {
+ /* Now need to update killing some packets */
+ needed = total_len - ((packet_log_start - packet_log_end));
+ while (needed > 0) {
+ thisone = (*(int *)(&packet_log_buffer[packet_log_start]));
+ needed -= thisone;
+ if (thisone == 0) {
+ goto insane;
+ }
+ /* move to next one */
+ packet_log_start += thisone;
+ if (((packet_log_start + sizeof(struct ip)) > SCTP_PACKET_LOG_SIZE) ||
+ (packet_log_wrapped && (packet_log_start >= packet_log_old_end))) {
+ packet_log_start = 0;
+ packet_log_old_end = 0;
+ packet_log_wrapped = 0;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (((packet_log_end + total_len) >= SCTP_PACKET_LOG_SIZE) ||
+ ((void *)((caddr_t)lenat) < (void *)packet_log_buffer) ||
+ ((void *)((caddr_t)lenat + total_len) > (void *)&packet_log_buffer[SCTP_PACKET_LOG_SIZE])) {
+ /* Madness protection */
+insane:
+ printf("Went mad, end:%d start:%d len:%d wrapped:%d oe:%d - zapping\n",
+ packet_log_end, packet_log_start, total_len, packet_log_wrapped, packet_log_old_end);
+ packet_log_start = packet_log_end = packet_log_old_end = packet_log_wrapped = 0;
+ lenat = (int *)&packet_log_buffer[0];
+ }
+ *lenat = total_len;
+ lenat++;
+ tick_tock = (uint32_t *) lenat;
+ lenat++;
+ *tick_tock = sctp_get_tick_count();
+ copyto = (void *)lenat;
+ packet_log_end = (((caddr_t)copyto + length) - (caddr_t)packet_log_buffer);
+ SCTP_IP_PKTLOG_UNLOCK();
+ m_copydata(m, 0, length, (caddr_t)copyto);
+
+}
+
+
+int
+sctp_copy_out_packet_log(uint8_t * target, int length)
+{
+ /*
+ * We wind through the packet log starting at start copying up to
+ * length bytes out. We return the number of bytes copied.
+ */
+ int tocopy, this_copy, copied = 0;
+ void *at;
+
+ tocopy = length;
+ if (packet_log_start == packet_log_end) {
+ /* no data */
+ return (0);
+ }
+ if (packet_log_wrapped) {
+ /*
+ * we have a wrapped buffer, we must copy from start to the
+ * old end. Then copy from the top of the buffer to the end.
+ */
+ SCTP_IP_PKTLOG_LOCK();
+ at = (void *)&packet_log_buffer[packet_log_start];
+ this_copy = min(tocopy, (packet_log_old_end - packet_log_start));
+ memcpy(target, at, this_copy);
+ tocopy -= this_copy;
+ copied += this_copy;
+ if (tocopy == 0) {
+ SCTP_IP_PKTLOG_UNLOCK();
+ return (copied);
+ }
+ this_copy = min(tocopy, packet_log_end);
+ at = (void *)&packet_log_buffer;
+ memcpy(&target[copied], at, this_copy);
+ copied += this_copy;
+ SCTP_IP_PKTLOG_UNLOCK();
+ return (copied);
+ } else {
+ /* we have one contiguous buffer */
+ SCTP_IP_PKTLOG_LOCK();
+ at = (void *)&packet_log_buffer;
+ this_copy = min(length, packet_log_end);
+ memcpy(target, at, this_copy);
+ SCTP_IP_PKTLOG_UNLOCK();
+ return (this_copy);
+ }
+}
+
+#endif
OpenPOWER on IntegriCloud