0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0012
0013 #include <linux/errno.h>
0014 #include <linux/types.h>
0015 #include <linux/socket.h>
0016 #include <linux/in.h>
0017 #include <linux/kernel.h>
0018 #include <linux/timer.h>
0019 #include <linux/string.h>
0020 #include <linux/sockios.h>
0021 #include <linux/net.h>
0022 #include <linux/inet.h>
0023 #include <linux/skbuff.h>
0024 #include <linux/slab.h>
0025 #include <net/sock.h>
0026 #include <linux/uaccess.h>
0027 #include <linux/fcntl.h>
0028 #include <linux/mm.h>
0029 #include <linux/interrupt.h>
0030 #include <net/lapb.h>
0031
0032
0033
0034
0035 void lapb_clear_queues(struct lapb_cb *lapb)
0036 {
0037 skb_queue_purge(&lapb->write_queue);
0038 skb_queue_purge(&lapb->ack_queue);
0039 }
0040
0041
0042
0043
0044
0045
0046 void lapb_frames_acked(struct lapb_cb *lapb, unsigned short nr)
0047 {
0048 struct sk_buff *skb;
0049 int modulus;
0050
0051 modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS : LAPB_SMODULUS;
0052
0053
0054
0055
0056 if (lapb->va != nr)
0057 while (skb_peek(&lapb->ack_queue) && lapb->va != nr) {
0058 skb = skb_dequeue(&lapb->ack_queue);
0059 kfree_skb(skb);
0060 lapb->va = (lapb->va + 1) % modulus;
0061 }
0062 }
0063
0064 void lapb_requeue_frames(struct lapb_cb *lapb)
0065 {
0066 struct sk_buff *skb, *skb_prev = NULL;
0067
0068
0069
0070
0071
0072
0073 while ((skb = skb_dequeue(&lapb->ack_queue)) != NULL) {
0074 if (!skb_prev)
0075 skb_queue_head(&lapb->write_queue, skb);
0076 else
0077 skb_append(skb_prev, skb, &lapb->write_queue);
0078 skb_prev = skb;
0079 }
0080 }
0081
0082
0083
0084
0085
0086 int lapb_validate_nr(struct lapb_cb *lapb, unsigned short nr)
0087 {
0088 unsigned short vc = lapb->va;
0089 int modulus;
0090
0091 modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS : LAPB_SMODULUS;
0092
0093 while (vc != lapb->vs) {
0094 if (nr == vc)
0095 return 1;
0096 vc = (vc + 1) % modulus;
0097 }
0098
0099 return nr == lapb->vs;
0100 }
0101
0102
0103
0104
0105
0106 int lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
0107 struct lapb_frame *frame)
0108 {
0109 frame->type = LAPB_ILLEGAL;
0110
0111 lapb_dbg(2, "(%p) S%d RX %3ph\n", lapb->dev, lapb->state, skb->data);
0112
0113
0114
0115
0116 if (!pskb_may_pull(skb, 2))
0117 return -1;
0118
0119 if (lapb->mode & LAPB_MLP) {
0120 if (lapb->mode & LAPB_DCE) {
0121 if (skb->data[0] == LAPB_ADDR_D)
0122 frame->cr = LAPB_COMMAND;
0123 if (skb->data[0] == LAPB_ADDR_C)
0124 frame->cr = LAPB_RESPONSE;
0125 } else {
0126 if (skb->data[0] == LAPB_ADDR_C)
0127 frame->cr = LAPB_COMMAND;
0128 if (skb->data[0] == LAPB_ADDR_D)
0129 frame->cr = LAPB_RESPONSE;
0130 }
0131 } else {
0132 if (lapb->mode & LAPB_DCE) {
0133 if (skb->data[0] == LAPB_ADDR_B)
0134 frame->cr = LAPB_COMMAND;
0135 if (skb->data[0] == LAPB_ADDR_A)
0136 frame->cr = LAPB_RESPONSE;
0137 } else {
0138 if (skb->data[0] == LAPB_ADDR_A)
0139 frame->cr = LAPB_COMMAND;
0140 if (skb->data[0] == LAPB_ADDR_B)
0141 frame->cr = LAPB_RESPONSE;
0142 }
0143 }
0144
0145 skb_pull(skb, 1);
0146
0147 if (lapb->mode & LAPB_EXTENDED) {
0148 if (!(skb->data[0] & LAPB_S)) {
0149 if (!pskb_may_pull(skb, 2))
0150 return -1;
0151
0152
0153
0154 frame->type = LAPB_I;
0155 frame->ns = (skb->data[0] >> 1) & 0x7F;
0156 frame->nr = (skb->data[1] >> 1) & 0x7F;
0157 frame->pf = skb->data[1] & LAPB_EPF;
0158 frame->control[0] = skb->data[0];
0159 frame->control[1] = skb->data[1];
0160 skb_pull(skb, 2);
0161 } else if ((skb->data[0] & LAPB_U) == 1) {
0162 if (!pskb_may_pull(skb, 2))
0163 return -1;
0164
0165
0166
0167 frame->type = skb->data[0] & 0x0F;
0168 frame->nr = (skb->data[1] >> 1) & 0x7F;
0169 frame->pf = skb->data[1] & LAPB_EPF;
0170 frame->control[0] = skb->data[0];
0171 frame->control[1] = skb->data[1];
0172 skb_pull(skb, 2);
0173 } else if ((skb->data[0] & LAPB_U) == 3) {
0174
0175
0176
0177 frame->type = skb->data[0] & ~LAPB_SPF;
0178 frame->pf = skb->data[0] & LAPB_SPF;
0179 frame->control[0] = skb->data[0];
0180 frame->control[1] = 0x00;
0181 skb_pull(skb, 1);
0182 }
0183 } else {
0184 if (!(skb->data[0] & LAPB_S)) {
0185
0186
0187
0188 frame->type = LAPB_I;
0189 frame->ns = (skb->data[0] >> 1) & 0x07;
0190 frame->nr = (skb->data[0] >> 5) & 0x07;
0191 frame->pf = skb->data[0] & LAPB_SPF;
0192 } else if ((skb->data[0] & LAPB_U) == 1) {
0193
0194
0195
0196 frame->type = skb->data[0] & 0x0F;
0197 frame->nr = (skb->data[0] >> 5) & 0x07;
0198 frame->pf = skb->data[0] & LAPB_SPF;
0199 } else if ((skb->data[0] & LAPB_U) == 3) {
0200
0201
0202
0203 frame->type = skb->data[0] & ~LAPB_SPF;
0204 frame->pf = skb->data[0] & LAPB_SPF;
0205 }
0206
0207 frame->control[0] = skb->data[0];
0208
0209 skb_pull(skb, 1);
0210 }
0211
0212 return 0;
0213 }
0214
0215
0216
0217
0218
0219
0220
0221 void lapb_send_control(struct lapb_cb *lapb, int frametype,
0222 int poll_bit, int type)
0223 {
0224 struct sk_buff *skb;
0225 unsigned char *dptr;
0226
0227 if ((skb = alloc_skb(LAPB_HEADER_LEN + 3, GFP_ATOMIC)) == NULL)
0228 return;
0229
0230 skb_reserve(skb, LAPB_HEADER_LEN + 1);
0231
0232 if (lapb->mode & LAPB_EXTENDED) {
0233 if ((frametype & LAPB_U) == LAPB_U) {
0234 dptr = skb_put(skb, 1);
0235 *dptr = frametype;
0236 *dptr |= poll_bit ? LAPB_SPF : 0;
0237 } else {
0238 dptr = skb_put(skb, 2);
0239 dptr[0] = frametype;
0240 dptr[1] = (lapb->vr << 1);
0241 dptr[1] |= poll_bit ? LAPB_EPF : 0;
0242 }
0243 } else {
0244 dptr = skb_put(skb, 1);
0245 *dptr = frametype;
0246 *dptr |= poll_bit ? LAPB_SPF : 0;
0247 if ((frametype & LAPB_U) == LAPB_S)
0248 *dptr |= (lapb->vr << 5);
0249 }
0250
0251 lapb_transmit_buffer(lapb, skb, type);
0252 }
0253
0254
0255
0256
0257
0258 void lapb_transmit_frmr(struct lapb_cb *lapb)
0259 {
0260 struct sk_buff *skb;
0261 unsigned char *dptr;
0262
0263 if ((skb = alloc_skb(LAPB_HEADER_LEN + 7, GFP_ATOMIC)) == NULL)
0264 return;
0265
0266 skb_reserve(skb, LAPB_HEADER_LEN + 1);
0267
0268 if (lapb->mode & LAPB_EXTENDED) {
0269 dptr = skb_put(skb, 6);
0270 *dptr++ = LAPB_FRMR;
0271 *dptr++ = lapb->frmr_data.control[0];
0272 *dptr++ = lapb->frmr_data.control[1];
0273 *dptr++ = (lapb->vs << 1) & 0xFE;
0274 *dptr = (lapb->vr << 1) & 0xFE;
0275 if (lapb->frmr_data.cr == LAPB_RESPONSE)
0276 *dptr |= 0x01;
0277 dptr++;
0278 *dptr++ = lapb->frmr_type;
0279
0280 lapb_dbg(1, "(%p) S%d TX FRMR %5ph\n",
0281 lapb->dev, lapb->state,
0282 &skb->data[1]);
0283 } else {
0284 dptr = skb_put(skb, 4);
0285 *dptr++ = LAPB_FRMR;
0286 *dptr++ = lapb->frmr_data.control[0];
0287 *dptr = (lapb->vs << 1) & 0x0E;
0288 *dptr |= (lapb->vr << 5) & 0xE0;
0289 if (lapb->frmr_data.cr == LAPB_RESPONSE)
0290 *dptr |= 0x10;
0291 dptr++;
0292 *dptr++ = lapb->frmr_type;
0293
0294 lapb_dbg(1, "(%p) S%d TX FRMR %3ph\n",
0295 lapb->dev, lapb->state, &skb->data[1]);
0296 }
0297
0298 lapb_transmit_buffer(lapb, skb, LAPB_RESPONSE);
0299 }