patch-2.3.16 linux/net/irda/irlap_frame.c
Next file: linux/net/irda/irlmp.c
Previous file: linux/net/irda/irlap_event.c
Back to the patch index
Back to the overall index
- Lines: 457
- Date:
Mon Aug 30 10:26:28 1999
- Orig file:
v2.3.15/linux/net/irda/irlap_frame.c
- Orig date:
Wed Aug 18 11:38:49 1999
diff -u --recursive --new-file v2.3.15/linux/net/irda/irlap_frame.c linux/net/irda/irlap_frame.c
@@ -6,10 +6,11 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Tue Aug 19 10:27:26 1997
- * Modified at: Mon May 31 09:29:13 1999
+ * Modified at: Wed Aug 25 13:15:53 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
- * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Resrved.
+ * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
+ * All Rights Resrved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -50,10 +51,12 @@
*/
static inline void irlap_insert_mtt(struct irlap_cb *self, struct sk_buff *skb)
{
- struct irlap_skb_cb *cb;
+ struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
- cb = (struct irlap_skb_cb *) skb->cb;
-
+ /*
+ * Insert MTT (min. turn time) into skb, so that the device driver
+ * knows which MTT to use
+ */
cb->magic = LAP_MAGIC;
cb->mtt = self->mtt_required;
@@ -78,18 +81,21 @@
*/
void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb)
{
+ /* Make sure data is not larger than max data size plus LAP header */
+ if (skb->len > 2050) {
+ ERROR(__FUNCTION__ "(), size=%d of sk_buff to big!\n",
+ (int) skb->len);
+ return;
+ }
+
/* Some common init stuff */
skb->dev = self->netdev;
skb->h.raw = skb->nh.raw = skb->mac.raw = skb->data;
skb->protocol = htons(ETH_P_IRDA);
skb->priority = TC_PRIO_BESTEFFORT;
- /*
- * Insert MTT (min. turn time) into skb, so that the device driver
- * knows which MTT to use
- */
irlap_insert_mtt(self, skb);
-
+
dev_queue_xmit(skb);
self->stats.tx_packets++;
}
@@ -103,7 +109,7 @@
{
struct sk_buff *skb;
struct snrm_frame *frame;
- int len;
+ int ret;
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
@@ -135,9 +141,11 @@
frame->ncaddr = self->caddr;
- len = irda_insert_qos_negotiation_params(qos, frame->params);
- /* Should not be dangerous to do this afterwards */
- skb_put(skb, len);
+ ret = irlap_insert_qos_negotiation_params(self, skb);
+ if (ret < 0) {
+ dev_kfree_skb(skb);
+ return;
+ }
}
irlap_queue_xmit(self, skb);
}
@@ -186,7 +194,7 @@
{
struct sk_buff *skb;
struct ua_frame *frame;
- int len;
+ int ret;
DEBUG(2, __FUNCTION__ "() <%ld>\n", jiffies);
@@ -200,7 +208,7 @@
if (!skb)
return;
- skb_put( skb, 10);
+ skb_put(skb, 10);
frame = (struct ua_frame *) skb->data;
/* Build UA response */
@@ -212,8 +220,11 @@
/* Should we send QoS negotiation parameters? */
if (qos) {
- len = irda_insert_qos_negotiation_params(qos, frame->params);
- skb_put(skb, len);
+ ret = irlap_insert_qos_negotiation_params(self, skb);
+ if (ret < 0) {
+ dev_kfree_skb(skb);
+ return;
+ }
}
irlap_queue_xmit(self, skb);
@@ -292,12 +303,13 @@
struct sk_buff *skb = NULL;
struct xid_frame *frame;
__u32 bcast = BROADCAST;
+ __u8 *info;
- DEBUG( 4, __FUNCTION__ "(), s=%d, S=%d, command=%d\n", s, S, command);
+ DEBUG(4, __FUNCTION__ "(), s=%d, S=%d, command=%d\n", s, S, command);
- ASSERT( self != NULL, return;);
- ASSERT( self->magic == LAP_MAGIC, return;);
- ASSERT( discovery != NULL, return;);
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == LAP_MAGIC, return;);
+ ASSERT(discovery != NULL, return;);
skb = dev_alloc_skb(64);
if (!skb)
@@ -348,28 +360,24 @@
* responses. Send the second byte of the hint only if the
* EXTENSION bit is set in the first byte.
*/
- if ( !command || ( frame->slotnr == 0xff)) {
+ if (!command || (frame->slotnr == 0xff)) {
int i;
if (discovery->hints.byte[0] & HINT_EXTENSION)
- skb_put( skb, 3+discovery->info_len);
+ info = skb_put(skb, 3+discovery->name_len);
else
- skb_put( skb, 2+discovery->info_len);
+ info = skb_put(skb, 2+discovery->name_len);
i = 0;
- frame->discovery_info[i++] = discovery->hints.byte[0];
- if(discovery->hints.byte[0] & HINT_EXTENSION)
- frame->discovery_info[i++] = discovery->hints.byte[1];
+ info[i++] = discovery->hints.byte[0];
+ if (discovery->hints.byte[0] & HINT_EXTENSION)
+ info[i++] = discovery->hints.byte[1];
- frame->discovery_info[i++] = discovery->charset;
-
- ASSERT( discovery->info_len < 30, return;);
-
- memcpy( &frame->discovery_info[i++], discovery->info,
- discovery->info_len);
-
+ info[i++] = discovery->charset;
+
+ memcpy(&info[i++], discovery->nickname, discovery->name_len);
}
- ASSERT( self->netdev != NULL, return;);
+ ASSERT(self->netdev != NULL, return;);
irlap_queue_xmit(self, skb);
}
@@ -386,14 +394,13 @@
{
struct xid_frame *xid;
discovery_t *discovery = NULL;
+ __u8 *discovery_info;
char *text;
DEBUG(4, __FUNCTION__ "()\n");
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
- ASSERT(skb != NULL, return;);
- ASSERT(info != NULL, return;);
if ((discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) {
DEBUG(0, __FUNCTION__ "(), kmalloc failed!\n");
@@ -413,24 +420,27 @@
DEBUG(4, __FUNCTION__ "(), daddr=%08x\n", discovery->daddr);
+ discovery_info = skb_pull(skb, sizeof(struct xid_frame));
+
/* Get info returned from peer */
- discovery->hints.byte[0] = xid->discovery_info[0];
- if (xid->discovery_info[0] & HINT_EXTENSION) {
+ discovery->hints.byte[0] = discovery_info[0];
+ if (discovery_info[0] & HINT_EXTENSION) {
DEBUG(4, "EXTENSION\n");
- discovery->hints.byte[1] = xid->discovery_info[1];
- discovery->charset = xid->discovery_info[2];
- text = (char *) &xid->discovery_info[3];
+ discovery->hints.byte[1] = discovery_info[1];
+ discovery->charset = discovery_info[2];
+ text = (char *) &discovery_info[3];
} else {
discovery->hints.byte[1] = 0;
- discovery->charset = xid->discovery_info[1];
- text = (char *) &xid->discovery_info[2];
+ discovery->charset = discovery_info[1];
+ text = (char *) &discovery_info[2];
}
/*
* Terminate string, should be safe since this is where the
* FCS bytes resides.
*/
skb->data[skb->len] = '\0';
- strcpy(discovery->info, text);
+ strncpy(discovery->nickname, text, NICKNAME_MAX_LEN);
+ discovery->name_len = strlen(discovery->nickname);
info->discovery = discovery;
@@ -443,27 +453,28 @@
* Received a XID discovery command
*
*/
-static void irlap_recv_discovery_xid_cmd( struct irlap_cb *self,
- struct sk_buff *skb,
- struct irlap_info *info)
+static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self,
+ struct sk_buff *skb,
+ struct irlap_info *info)
{
struct xid_frame *xid;
discovery_t *discovery = NULL;
+ __u8 *discovery_info;
char *text;
- DEBUG( 4, __FUNCTION__ "()\n");
+ DEBUG(4, __FUNCTION__ "()\n");
- ASSERT( self != NULL, return;);
- ASSERT( self->magic == LAP_MAGIC, return;);
- ASSERT( skb != NULL, return;);
- ASSERT( info != NULL, return;);
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == LAP_MAGIC, return;);
+ ASSERT(skb != NULL, return;);
+ ASSERT(info != NULL, return;);
xid = (struct xid_frame *) skb->data;
/* Copy peer device address */
info->daddr = le32_to_cpu(xid->saddr);
- switch ( xid->flags & 0x03) {
+ switch (xid->flags & 0x03) {
case 0x00:
info->S = 1;
break;
@@ -482,46 +493,48 @@
}
info->s = xid->slotnr;
+ discovery_info = skb_pull(skb, sizeof(struct xid_frame));
+
/*
* Check if last frame
*/
- if ( info->s == 0xff) {
+ if (info->s == 0xff) {
/*
* We now have some discovery info to deliver!
*/
- discovery = kmalloc( sizeof(discovery_t), GFP_ATOMIC);
- if (!discovery)
+ discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC);
+ if (!discovery) {
+ WARNING(__FUNCTION__ "(), unable to malloc!\n");
return;
+ }
discovery->daddr = info->daddr;
discovery->saddr = self->saddr;
discovery->timestamp = jiffies;
- DEBUG( 4, __FUNCTION__ "(), daddr=%08x\n",
- discovery->daddr);
-
- discovery->hints.byte[0] = xid->discovery_info[0];
- if ( xid->discovery_info[0] & HINT_EXTENSION) {
- discovery->hints.byte[1] = xid->discovery_info[1];
- discovery->charset = xid->discovery_info[2];
- text = (char *) &xid->discovery_info[3];
+ discovery->hints.byte[0] = discovery_info[0];
+ if (discovery_info[0] & HINT_EXTENSION) {
+ discovery->hints.byte[1] = discovery_info[1];
+ discovery->charset = discovery_info[2];
+ text = (char *) &discovery_info[3];
} else {
discovery->hints.byte[1] = 0;
- discovery->charset = xid->discovery_info[1];
- text = (char *) &xid->discovery_info[2];
+ discovery->charset = discovery_info[1];
+ text = (char *) &discovery_info[2];
}
/*
* Terminate string, should be safe since this is where the
* FCS bytes resides.
*/
skb->data[skb->len] = '\0';
- strcpy( discovery->info, text);
+ strncpy(discovery->nickname, text, NICKNAME_MAX_LEN);
+ discovery->name_len = strlen(discovery->nickname);
info->discovery = discovery;
} else
info->discovery = NULL;
- irlap_do_event( self, RECV_DISCOVERY_XID_CMD, skb, info);
+ irlap_do_event(self, RECV_DISCOVERY_XID_CMD, skb, info);
}
/*
@@ -1027,9 +1040,6 @@
info->pf = skb->data[1] & PF_BIT; /* Final bit */
info->ns = (skb->data[1] >> 1) & 0x07; /* Next to send */
- DEBUG(4, __FUNCTION__"(), ns=%d, nr=%d, pf=%d, %ld\n",
- info->ns, info->nr, info->pf>>4, jiffies);
-
/* Check if this is a command or a response frame */
if (command)
irlap_do_event(self, RECV_I_CMD, skb, info);
@@ -1054,7 +1064,7 @@
info->pf = frame[1] & PF_BIT; /* Final bit */
- irlap_do_event( self, RECV_UI_FRAME, skb, info);
+ irlap_do_event(self, RECV_UI_FRAME, skb, info);
}
/*
@@ -1118,7 +1128,8 @@
{
struct sk_buff *skb;
struct test_frame *frame;
-
+ __u8 *info;
+
skb = dev_alloc_skb(32);
if (!skb)
return;
@@ -1140,8 +1151,8 @@
frame->daddr = cpu_to_le32(daddr);
/* Copy info */
- skb_put(skb, cmd->len);
- memcpy(frame->info, cmd->data, cmd->len);
+ info = skb_put(skb, cmd->len);
+ memcpy(info, cmd->data, cmd->len);
/* Return to sender */
irlap_wait_min_turn_around(self, &self->qos_tx);
@@ -1191,32 +1202,23 @@
struct irlap_info info;
struct irlap_cb *self;
struct irda_device *idev;
- __u8 *frame;
int command;
__u8 control;
idev = (struct irda_device *) dev->priv;
-
- ASSERT( idev != NULL, return -1;);
self = idev->irlap;
- ASSERT( self != NULL, return -1;);
- ASSERT( self->magic == LAP_MAGIC, return -1;);
- ASSERT( skb->len > 1, return -1;);
+ ASSERT(skb->len > 1, return -1;);
- frame = skb->data;
-
- command = frame[0] & CMD_FRAME;
- info.caddr = frame[0] & CBROADCAST;
+ command = skb->data[0] & CMD_FRAME;
+ info.caddr = skb->data[0] & CBROADCAST;
- info.pf = frame[1] & PF_BIT;
- info.control = frame[1] & ~PF_BIT; /* Mask away poll/final bit */
+ info.pf = skb->data[1] & PF_BIT;
+ info.control = skb->data[1] & ~PF_BIT; /* Mask away poll/final bit */
control = info.control;
- /*
- * First check if this frame addressed to us
- */
+ /* First check if this frame addressed to us */
if ((info.caddr != self->caddr) && (info.caddr != CBROADCAST)) {
DEBUG(2, __FUNCTION__ "(), Received frame is not for us!\n");
@@ -1243,11 +1245,11 @@
*/
switch (control & 0x0f) {
case RR:
- irlap_recv_rr_frame( self, skb, &info, command);
+ irlap_recv_rr_frame(self, skb, &info, command);
self->stats.rx_packets++;
break;
case RNR:
- irlap_recv_rnr_frame( self, skb, &info);
+ irlap_recv_rnr_frame(self, skb, &info);
self->stats.rx_packets++;
break;
case REJ:
@@ -1257,8 +1259,8 @@
DEBUG( 0, "*** SREJ frame received! ***\n");
break;
default:
- DEBUG( 0, "Unknown S frame %02x received!\n",
- info.control);
+ WARNING(__FUNCTION__ "() Unknown S frame %02x received!\n",
+ info.control);
break;
}
return 0;
@@ -1284,22 +1286,21 @@
irlap_do_event(self, RECV_DISC_FRAME, skb, &info);
break;
case TEST_CMD:
- DEBUG(0,__FUNCTION__ "(), TEST_FRAME\n");
irlap_recv_test_frame(self, skb, &info, command);
break;
case UA_RSP:
- DEBUG( 4, "UA rsp frame received!\n");
- irlap_recv_ua_frame( self, skb, &info);
+ irlap_recv_ua_frame(self, skb, &info);
break;
case FRMR_RSP:
- irlap_recv_frmr_frame( self, skb, &info);
+ irlap_recv_frmr_frame(self, skb, &info);
break;
case UI_FRAME:
- DEBUG( 4, "UI-frame received!\n");
- irlap_recv_ui_frame( self, skb, &info);
+ DEBUG(4, "UI-frame received!\n");
+ irlap_recv_ui_frame(self, skb, &info);
break;
default:
- DEBUG( 0, "Unknown frame %02x received!\n", info.control);
+ WARNING(__FUNCTION__ "(), Unknown frame %02x received!\n",
+ info.control);
dev_kfree_skb( skb);
break;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)