--- linux-2.4.21/net/bluetooth/l2cap.c 2004-10-19 11:14:43.000000000 -0700 +++ linux-2.4.21_mods/net/bluetooth/l2cap.c 2004-11-30 16:28:37.000000000 -0800 @@ -81,6 +81,8 @@ static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data); static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data); +static void l2cap_add_conf_opt(void **ptr, __u8 type, __u8 len, unsigned long val); + /* ----- L2CAP timers ------ */ static void l2cap_sock_timeout(unsigned long arg) { @@ -1235,11 +1237,12 @@ return len; } -static inline void l2cap_parse_conf_req(struct sock *sk, void *data, int len) +static inline int l2cap_parse_conf_req(struct sock *sk, void *data, int len, void **rsp_ptr) { int type, hint, olen; unsigned long val; void *ptr = data; + int result = 0; BT_DBG("sk %p len %d", sk, len); @@ -1265,10 +1268,13 @@ if (hint) break; - /* FIXME: Reject unknown option */ + /* Reject unknown option */ + l2cap_add_conf_opt(rsp_ptr, type, olen, val); + result = L2CAP_CONF_UNKNOWN_OPT; break; }; } + return result; } static void l2cap_add_conf_opt(void **ptr, __u8 type, __u8 len, unsigned long val) @@ -1341,16 +1347,16 @@ return result; } -static int l2cap_build_conf_rsp(struct sock *sk, void *data, int *result) +static int l2cap_build_conf_rsp(struct sock *sk, void *data, void **ptr, int *result, int conf_output) { - l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data; - void *ptr = rsp->data; + l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data; + // void *ptr = rsp->data; u16 flags = 0; BT_DBG("sk %p complete %d", sk, result ? 1 : 0); - if (result) - *result = l2cap_conf_output(sk, &ptr); + if (result && conf_output) + *result = l2cap_conf_output(sk, ptr); else flags |= 0x0001; @@ -1358,7 +1364,7 @@ rsp->result = __cpu_to_le16(result ? *result : 0); rsp->flags = __cpu_to_le16(flags); - return ptr - data; + return *ptr - data; } static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data) @@ -1493,6 +1499,7 @@ __u8 rsp[64]; struct sock *sk; int result; + void *ptr = ((l2cap_conf_rsp *)rsp)->data; dcid = __le16_to_cpu(req->dcid); flags = __le16_to_cpu(req->flags); @@ -1502,16 +1509,22 @@ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid))) return -ENOENT; - l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE); + result = l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE, &ptr); + + if (result) { + /* Unknown option */ + l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &ptr, &result, 0), rsp); + goto unlock; + } if (flags & 0x0001) { /* Incomplete config. Send empty response. */ - l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp); + l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &ptr, NULL, 0), rsp); goto unlock; } /* Complete config. */ - l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp); + l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &ptr, &result, 1), rsp); if (result) goto unlock; --- linux-2.4.21/include/net/bluetooth/l2cap.h 2004-08-26 11:39:27.000000000 -0700 +++ linux-2.4.21_mods/include/net/bluetooth/l2cap.h 2004-11-30 15:43:17.000000000 -0800 @@ -151,6 +151,7 @@ #define L2CAP_CONF_SUCCESS 0x00 #define L2CAP_CONF_UNACCEPT 0x01 +#define L2CAP_CONF_UNKNOWN_OPT 0x03 typedef struct { __u8 type;