* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Tromsø admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
{
/* Some common init stuff */
skb->dev = self->netdev;
- skb->h.raw = skb->nh.raw = skb->mac.raw = skb->data;
+ skb_reset_mac_header(skb);
+ skb_reset_network_header(skb);
+ skb_reset_transport_header(skb);
skb->protocol = htons(ETH_P_IRDA);
skb->priority = TC_PRIO_BESTEFFORT;
irlap_insert_info(self, skb);
+ if (unlikely(self->mode & IRDA_MODE_MONITOR)) {
+ IRDA_DEBUG(3, "%s(): %s is in monitor mode\n", __FUNCTION__,
+ self->netdev->name);
+ dev_kfree_skb(skb);
+ return;
+ }
+
dev_queue_xmit(skb);
}
IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
/* Allocate frame */
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(sizeof(struct snrm_frame) +
+ IRLAP_NEGOCIATION_PARAMS_LEN,
+ GFP_ATOMIC);
if (!tx_skb)
return;
* If we are establishing a connection then insert QoS paramerters
*/
if (qos) {
- skb_put(tx_skb, 9); /* 21 left */
+ skb_put(tx_skb, 9); /* 25 left */
frame->saddr = cpu_to_le32(self->saddr);
frame->daddr = cpu_to_le32(self->daddr);
IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
/* Allocate frame */
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(sizeof(struct ua_frame) +
+ IRLAP_NEGOCIATION_PARAMS_LEN,
+ GFP_ATOMIC);
if (!tx_skb)
return;
void irlap_send_dm_frame( struct irlap_cb *self)
{
struct sk_buff *tx_skb = NULL;
- __u8 *frame;
+ struct dm_frame *frame;
IRDA_ASSERT(self != NULL, return;);
IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
- tx_skb = alloc_skb(32, GFP_ATOMIC);
+ tx_skb = alloc_skb(sizeof(struct dm_frame), GFP_ATOMIC);
if (!tx_skb)
return;
- frame = skb_put(tx_skb, 2);
+ frame = (struct dm_frame *)skb_put(tx_skb, 2);
if (self->state == LAP_NDM)
- frame[0] = CBROADCAST;
+ frame->caddr = CBROADCAST;
else
- frame[0] = self->caddr;
+ frame->caddr = self->caddr;
- frame[1] = DM_RSP | PF_BIT;
+ frame->control = DM_RSP | PF_BIT;
irlap_queue_xmit(self, tx_skb);
}
void irlap_send_disc_frame(struct irlap_cb *self)
{
struct sk_buff *tx_skb = NULL;
- __u8 *frame;
+ struct disc_frame *frame;
IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
IRDA_ASSERT(self != NULL, return;);
IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
- tx_skb = alloc_skb(16, GFP_ATOMIC);
+ tx_skb = alloc_skb(sizeof(struct disc_frame), GFP_ATOMIC);
if (!tx_skb)
return;
- frame = skb_put(tx_skb, 2);
+ frame = (struct disc_frame *)skb_put(tx_skb, 2);
- frame[0] = self->caddr | CMD_FRAME;
- frame[1] = DISC_CMD | PF_BIT;
+ frame->caddr = self->caddr | CMD_FRAME;
+ frame->control = DISC_CMD | PF_BIT;
irlap_queue_xmit(self, tx_skb);
}
IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
IRDA_ASSERT(discovery != NULL, return;);
- tx_skb = alloc_skb(64, GFP_ATOMIC);
+ tx_skb = alloc_skb(sizeof(struct xid_frame) + IRLAP_DISCOVERY_INFO_LEN,
+ GFP_ATOMIC);
if (!tx_skb)
return;
IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
if (!pskb_may_pull(skb, sizeof(struct xid_frame))) {
- IRDA_ERROR("%s: frame to short!\n", __FUNCTION__);
+ IRDA_ERROR("%s: frame too short!\n", __FUNCTION__);
return;
}
-
+
xid = (struct xid_frame *) skb->data;
info->daddr = le32_to_cpu(xid->saddr);
char *text;
if (!pskb_may_pull(skb, sizeof(struct xid_frame))) {
- IRDA_ERROR("%s: frame to short!\n", __FUNCTION__);
+ IRDA_ERROR("%s: frame too short!\n", __FUNCTION__);
return;
}
-
+
xid = (struct xid_frame *) skb->data;
info->daddr = le32_to_cpu(xid->saddr);
*/
if (info->s == 0xff) {
/* Check if things are sane at this point... */
- if((discovery_info == NULL) ||
+ if((discovery_info == NULL) ||
!pskb_may_pull(skb, 3)) {
- IRDA_ERROR("%s: discovery frame to short!\n",
+ IRDA_ERROR("%s: discovery frame too short!\n",
__FUNCTION__);
return;
}
void irlap_send_rr_frame(struct irlap_cb *self, int command)
{
struct sk_buff *tx_skb;
- __u8 *frame;
+ struct rr_frame *frame;
- tx_skb = alloc_skb(16, GFP_ATOMIC);
+ tx_skb = alloc_skb(sizeof(struct rr_frame), GFP_ATOMIC);
if (!tx_skb)
return;
- frame = skb_put(tx_skb, 2);
+ frame = (struct rr_frame *)skb_put(tx_skb, 2);
- frame[0] = self->caddr;
- frame[0] |= (command) ? CMD_FRAME : 0;
+ frame->caddr = self->caddr;
+ frame->caddr |= (command) ? CMD_FRAME : 0;
- frame[1] = RR | PF_BIT | (self->vr << 5);
+ frame->control = RR | PF_BIT | (self->vr << 5);
irlap_queue_xmit(self, tx_skb);
}
void irlap_send_rd_frame(struct irlap_cb *self)
{
struct sk_buff *tx_skb;
- __u8 *frame;
+ struct rd_frame *frame;
- tx_skb = alloc_skb(16, GFP_ATOMIC);
+ tx_skb = alloc_skb(sizeof(struct rd_frame), GFP_ATOMIC);
if (!tx_skb)
return;
- frame = skb_put(tx_skb, 2);
+ frame = (struct rd_frame *)skb_put(tx_skb, 2);
- frame[0] = self->caddr;
- frame[1] = RD_RSP | PF_BIT;
+ frame->caddr = self->caddr;
+ frame->caddr = RD_RSP | PF_BIT;
irlap_queue_xmit(self, tx_skb);
}
self->vs = (self->vs + 1) % 8;
self->ack_required = FALSE;
+ irlap_next_state(self, LAP_NRM_P);
irlap_send_i_frame(self, tx_skb, CMD_FRAME);
} else {
IRDA_DEBUG(4, "%s(), sending unreliable frame\n", __FUNCTION__);
if (self->ack_required) {
irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
+ irlap_next_state(self, LAP_NRM_P);
irlap_send_rr_frame(self, CMD_FRAME);
self->ack_required = FALSE;
} else {
skb->data[1] |= PF_BIT;
+ irlap_next_state(self, LAP_NRM_P);
irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
}
}
IRDA_ASSERT(info != NULL, return;);
if (!pskb_may_pull(skb, 4)) {
- IRDA_ERROR("%s: frame to short!\n", __FUNCTION__);
+ IRDA_ERROR("%s: frame too short!\n", __FUNCTION__);
return;
}
struct test_frame *frame;
__u8 *info;
- tx_skb = alloc_skb(cmd->len+sizeof(struct test_frame), GFP_ATOMIC);
+ tx_skb = alloc_skb(cmd->len + sizeof(struct test_frame), GFP_ATOMIC);
if (!tx_skb)
return;
IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
if (!pskb_may_pull(skb, sizeof(*frame))) {
- IRDA_ERROR("%s: frame to short!\n", __FUNCTION__);
+ IRDA_ERROR("%s: frame too short!\n", __FUNCTION__);
return;
}
frame = (struct test_frame *) skb->data;
/* Broadcast frames must carry saddr and daddr fields */
if (info->caddr == CBROADCAST) {
if (skb->len < sizeof(struct test_frame)) {
- IRDA_DEBUG(0, "%s() test frame to short!\n",
+ IRDA_DEBUG(0, "%s() test frame too short!\n",
__FUNCTION__);
return;
}
int command;
__u8 control;
+ if (dev->nd_net != &init_net)
+ goto out;
+
/* FIXME: should we get our own field? */
self = (struct irlap_cb *) dev->atalk_ptr;
/* Check if frame is large enough for parsing */
if (!pskb_may_pull(skb, 2)) {
- IRDA_ERROR("%s: frame to short!\n", __FUNCTION__);
+ IRDA_ERROR("%s: frame too short!\n", __FUNCTION__);
dev_kfree_skb(skb);
return -1;
}