diff -uprN net/dccp/dccp_options.c net/dccp/dccp_options.c
--- net/dccp/dccp_options.c	1969-12-31 22:00:00.000000000 -0200
+++ net/dccp/dccp_options.c	2005-04-15 20:05:06.000000000 -0200
@@ -0,0 +1,224 @@
+/*
+ *  net/dccp/dccp_options.c
+ *
+ *  An implementation of the DCCP protocol
+ *  Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/dccp.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/skbuff.h>
+#include <net/dccp.h>
+
+/* stores the default values for new connection. may be changed with sysctl */
+static struct dccp_options dccpo_default_values = {
+	.dccpo_sequence_window =	DCCPF_INITIAL_SEQUENCE_WINDOW,
+	.dccpo_ack_ratio = 		DCCPF_INITIAL_ACK_RATIO,
+	.dccpo_ccid = 			DCCPF_INITIAL_CCID,
+	.dccpo_allow_short_seqnos =	DCCPF_INITIAL_ALLOW_SHORT_SEQNOS,
+	.dccpo_ecn_incapable =		DCCPF_INITIAL_ECN_INCAPABLE,
+	.dccpo_send_ack_vector =	DCCPF_INITIAL_SEND_ACK_VECTOR,
+	.dccpo_send_ndp_count =		DCCPF_INITIAL_SEND_NDP_COUNT,
+	.dccpo_min_crc_coverage =	DCCPF_INITIAL_MIN_CRC_COVERAGE,
+	.dccpo_check_data =		DCCPF_INITIAL_CHECK_DATA,
+};
+static spinlock_t dccpo_default_values_lock = SPIN_LOCK_UNLOCKED;
+
+static inline void __dccp_options_init(struct dccp_options *dccpf)
+{
+	memcpy(dccpf, &dccpo_default_values, sizeof(struct dccp_options));
+}
+
+static inline void dccp_options_init(struct dccp_options *dccpf)
+{
+	spin_lock(&dccpo_default_values_lock);
+	__dccp_options_init(dccpf);
+	spin_unlock(&dccpo_default_values_lock);
+}
+
+/**
+  * dccp_check_option_size - returns the size of the next option
+  * 	@opt - begin of the next option
+  * 	@len - remaining size
+  */	
+static inline int dccp_check_option_size(char *opt, short len)
+{
+	return -1;
+}
+
+/**
+  * dccp_check_option_suitable - checks if an option is suitable to this kind of packet
+  * 	@dh - dccp header
+  * 	@opt - begin of the option, already checked
+  * returns:
+  * 		0 if the option is suitable for this kind of packet
+  * 		-1 in case it's not and should be ignored
+  * 		-2 in case it's not and this and next option should be ignored
+  */
+static inline int dccp_check_option_suitable(struct dccp_hdr *dh,
+					     unsigned char *opt)
+{
+	return 0;
+}
+
+/* TODO
+ * - we must check if the packet type may carry options
+ * - we must check for repeated options
+ */
+
+/**
+*/
+int dccp_parse_options(struct sk_buff *skb)
+{
+	struct dccp_hdr		*dh;
+	short			len;
+
+	dh = dccp_hdr(skb);
+
+	len = (dh->dccph_doff * 4) - dccp_hdr_len(skb);
+	if (len > 0) {
+		int		next_mandatory = 0,
+				ignore_next = 0,
+				skip = 0,
+				rc;
+		short		i;
+		unsigned char	*opt;
+
+		opt = (unsigned char *)dh->dccph_options;
+
+		for (i = 0; i < len; i += skip) {
+			skip = dccp_check_option_size(opt + i, len - i);
+			if (skip < 0) {
+				/*
+				 * we should ignore it but it's a bit difficult
+				 * to continue parsing for other options if
+				 * the size is wrong, so we'll ignore all the
+				 * rest
+				 */
+				/* FIXME: we should bump some
+				 * DCCP_MIB_INVALID_OPTION MIB variable */
+				if (net_ratelimit())
+					printk(KERN_ERR
+						"Invalid DCCP option size");
+				goto out;
+			}
+
+			if (ignore_next == 1) {
+				ignore_next = 0;
+				continue;
+			}
+
+			rc = dccp_check_option_suitable(dh, opt + i);
+			if (rc < 0) {
+				if (rc == -2)
+					ignore_next = 1;
+				continue;
+			}
+
+			switch(opt[i]) {
+			case DCCPO_PADDING:
+				/* do nothing, just ignore */
+				break;
+			case DCCPO_MANDATORY:
+				if (next_mandatory == 1) {
+					/* FIXME - now what? */
+					dprintk(KERN_ERR "A mandatory "
+							"mandatory!?!?\n");
+				}
+				next_mandatory = 1;
+				break;
+			case DCCPO_SLOW_RECEIVER:
+				dprintk(KERN_INFO "options: slow receiver\n");
+				break;
+			case DCCPO_CHANGE_L:
+				dprintk(KERN_INFO "options: change L\n");
+				break;
+			case DCCPO_CONFIRM_L:
+				dprintk(KERN_INFO "options: confirm L\n");
+				break;
+			case DCCPO_CHANGE_R:
+				dprintk(KERN_INFO "options: change R\n");
+				break;
+			case DCCPO_CONFIRM_R:
+				dprintk(KERN_INFO "options: confirm R\n");
+				break;
+			case DCCPO_INIT_COOKIE:
+				dprintk(KERN_INFO "options: init cookie\n");
+				break;
+			case DCCPO_NDP_COUNT:
+				dprintk(KERN_INFO "options: NDP count\n");
+				break;
+			case DCCPO_ACK_VECTOR_0:
+				dprintk(KERN_INFO "options: ACK vector 0\n");
+				break;
+			case DCCPO_ACK_VECTOR_1:
+				dprintk(KERN_INFO "options: ACK vector 1\n");
+				break;
+			case DCCPO_DATA_DROPPED:
+				dprintk(KERN_INFO "options: data dropped\n");
+				break;
+			case DCCPO_TIMESTAMP:
+				dprintk(KERN_INFO "options: timestamp\n");
+				break;
+			case DCCPO_TIMESTAMP_ECHO:
+				dprintk(KERN_INFO "options: timestamp echo\n");
+				break;
+			case DCCPO_ELAPSED_TIME:
+				dprintk(KERN_INFO "options: elapsed time\n");
+				break;
+			case DCCPO_DATA_CHECKSUM:
+				dprintk(KERN_INFO "options: data checksum\n");
+				break;
+			default:
+				if (opt[i] >= DCCPO_MIN_CCID_SPECIFIC) {
+					/* FIXME - send to CCID */
+					dprintk(KERN_INFO "options: specific "
+						"CCID option\n");
+					break;
+				}
+
+				if (next_mandatory == 1) {
+					/*
+					 * we don't understand a mandatory
+					 * option, we should reset with
+					 * "Mandatory Failure" (see 5.8.2)
+					 */
+					/* FIXME - reset here */
+					dprintk(KERN_ERR "mandatory option "
+						"not recognized!\n");
+				}
+
+				/*
+				 * we don't understand this option and it's not
+				 * mandatory. we should ignore it
+				 */
+			}
+			if (opt[i] != DCCPO_MANDATORY)
+				next_mandatory = 0;
+		}
+		if (next_mandatory == 1) {
+			/*
+			 * From the spec:
+			 * The connection is in error and should be reset with
+			 * Reset Code 5, "Option Error" if option O is absent
+			 * (Mandatory was the last byte of the option list),
+			 * or if option O equals Mandatory.
+			 */
+			/* FIXME - reset connection here */
+			dprintk(KERN_ERR "last option is a mandatory option "
+				"type!\n");
+		}
+	}
+
+	BUG_TRAP(len < 0);
+out:
+	return 0;
+}
+
diff -uprN net/dccp/Makefile net/dccp/Makefile
--- net/dccp/Makefile	2005-04-07 16:21:13.000000000 -0200
+++ net/dccp/Makefile	2005-04-15 20:04:19.000000000 -0200
@@ -5,4 +5,4 @@
 obj-$(CONFIG_IP_DCCP) += dccp.o
 
 dccp-y := dccp_proto.o dccp_input.o dccp_ipv4.o dccp_minisocks.o \
-	  dccp_output.o dccp_timer.o
+	  dccp_output.o dccp_timer.o dccp_options.o
