0001
0002
0003
0004
0005
0006 #include <linux/errno.h>
0007 #include <linux/types.h>
0008 #include <linux/socket.h>
0009 #include <linux/in.h>
0010 #include <linux/kernel.h>
0011 #include <linux/jiffies.h>
0012 #include <linux/timer.h>
0013 #include <linux/string.h>
0014 #include <linux/sockios.h>
0015 #include <linux/net.h>
0016 #include <linux/slab.h>
0017 #include <net/ax25.h>
0018 #include <linux/inet.h>
0019 #include <linux/netdevice.h>
0020 #include <linux/skbuff.h>
0021 #include <net/sock.h>
0022 #include <linux/fcntl.h>
0023 #include <linux/mm.h>
0024 #include <linux/interrupt.h>
0025 #include <net/rose.h>
0026
0027 static void rose_ftimer_expiry(struct timer_list *);
0028 static void rose_t0timer_expiry(struct timer_list *);
0029
0030 static void rose_transmit_restart_confirmation(struct rose_neigh *neigh);
0031 static void rose_transmit_restart_request(struct rose_neigh *neigh);
0032
0033 void rose_start_ftimer(struct rose_neigh *neigh)
0034 {
0035 del_timer(&neigh->ftimer);
0036
0037 neigh->ftimer.function = rose_ftimer_expiry;
0038 neigh->ftimer.expires =
0039 jiffies + msecs_to_jiffies(sysctl_rose_link_fail_timeout);
0040
0041 add_timer(&neigh->ftimer);
0042 }
0043
0044 static void rose_start_t0timer(struct rose_neigh *neigh)
0045 {
0046 del_timer(&neigh->t0timer);
0047
0048 neigh->t0timer.function = rose_t0timer_expiry;
0049 neigh->t0timer.expires =
0050 jiffies + msecs_to_jiffies(sysctl_rose_restart_request_timeout);
0051
0052 add_timer(&neigh->t0timer);
0053 }
0054
0055 void rose_stop_ftimer(struct rose_neigh *neigh)
0056 {
0057 del_timer(&neigh->ftimer);
0058 }
0059
0060 void rose_stop_t0timer(struct rose_neigh *neigh)
0061 {
0062 del_timer(&neigh->t0timer);
0063 }
0064
0065 int rose_ftimer_running(struct rose_neigh *neigh)
0066 {
0067 return timer_pending(&neigh->ftimer);
0068 }
0069
0070 static int rose_t0timer_running(struct rose_neigh *neigh)
0071 {
0072 return timer_pending(&neigh->t0timer);
0073 }
0074
0075 static void rose_ftimer_expiry(struct timer_list *t)
0076 {
0077 }
0078
0079 static void rose_t0timer_expiry(struct timer_list *t)
0080 {
0081 struct rose_neigh *neigh = from_timer(neigh, t, t0timer);
0082
0083 rose_transmit_restart_request(neigh);
0084
0085 neigh->dce_mode = 0;
0086
0087 rose_start_t0timer(neigh);
0088 }
0089
0090
0091
0092
0093
0094
0095 static int rose_send_frame(struct sk_buff *skb, struct rose_neigh *neigh)
0096 {
0097 const ax25_address *rose_call;
0098 ax25_cb *ax25s;
0099
0100 if (ax25cmp(&rose_callsign, &null_ax25_address) == 0)
0101 rose_call = (const ax25_address *)neigh->dev->dev_addr;
0102 else
0103 rose_call = &rose_callsign;
0104
0105 ax25s = neigh->ax25;
0106 neigh->ax25 = ax25_send_frame(skb, 260, rose_call, &neigh->callsign, neigh->digipeat, neigh->dev);
0107 if (ax25s)
0108 ax25_cb_put(ax25s);
0109
0110 return neigh->ax25 != NULL;
0111 }
0112
0113
0114
0115
0116
0117
0118 static int rose_link_up(struct rose_neigh *neigh)
0119 {
0120 const ax25_address *rose_call;
0121 ax25_cb *ax25s;
0122
0123 if (ax25cmp(&rose_callsign, &null_ax25_address) == 0)
0124 rose_call = (const ax25_address *)neigh->dev->dev_addr;
0125 else
0126 rose_call = &rose_callsign;
0127
0128 ax25s = neigh->ax25;
0129 neigh->ax25 = ax25_find_cb(rose_call, &neigh->callsign, neigh->digipeat, neigh->dev);
0130 if (ax25s)
0131 ax25_cb_put(ax25s);
0132
0133 return neigh->ax25 != NULL;
0134 }
0135
0136
0137
0138
0139 void rose_link_rx_restart(struct sk_buff *skb, struct rose_neigh *neigh, unsigned short frametype)
0140 {
0141 struct sk_buff *skbn;
0142
0143 switch (frametype) {
0144 case ROSE_RESTART_REQUEST:
0145 rose_stop_t0timer(neigh);
0146 neigh->restarted = 1;
0147 neigh->dce_mode = (skb->data[3] == ROSE_DTE_ORIGINATED);
0148 rose_transmit_restart_confirmation(neigh);
0149 break;
0150
0151 case ROSE_RESTART_CONFIRMATION:
0152 rose_stop_t0timer(neigh);
0153 neigh->restarted = 1;
0154 break;
0155
0156 case ROSE_DIAGNOSTIC:
0157 pr_warn("ROSE: received diagnostic #%d - %3ph\n", skb->data[3],
0158 skb->data + 4);
0159 break;
0160
0161 default:
0162 printk(KERN_WARNING "ROSE: received unknown %02X with LCI 000\n", frametype);
0163 break;
0164 }
0165
0166 if (neigh->restarted) {
0167 while ((skbn = skb_dequeue(&neigh->queue)) != NULL)
0168 if (!rose_send_frame(skbn, neigh))
0169 kfree_skb(skbn);
0170 }
0171 }
0172
0173
0174
0175
0176 static void rose_transmit_restart_request(struct rose_neigh *neigh)
0177 {
0178 struct sk_buff *skb;
0179 unsigned char *dptr;
0180 int len;
0181
0182 len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN + 3;
0183
0184 if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
0185 return;
0186
0187 skb_reserve(skb, AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN);
0188
0189 dptr = skb_put(skb, ROSE_MIN_LEN + 3);
0190
0191 *dptr++ = AX25_P_ROSE;
0192 *dptr++ = ROSE_GFI;
0193 *dptr++ = 0x00;
0194 *dptr++ = ROSE_RESTART_REQUEST;
0195 *dptr++ = ROSE_DTE_ORIGINATED;
0196 *dptr++ = 0;
0197
0198 if (!rose_send_frame(skb, neigh))
0199 kfree_skb(skb);
0200 }
0201
0202
0203
0204
0205 static void rose_transmit_restart_confirmation(struct rose_neigh *neigh)
0206 {
0207 struct sk_buff *skb;
0208 unsigned char *dptr;
0209 int len;
0210
0211 len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN + 1;
0212
0213 if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
0214 return;
0215
0216 skb_reserve(skb, AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN);
0217
0218 dptr = skb_put(skb, ROSE_MIN_LEN + 1);
0219
0220 *dptr++ = AX25_P_ROSE;
0221 *dptr++ = ROSE_GFI;
0222 *dptr++ = 0x00;
0223 *dptr++ = ROSE_RESTART_CONFIRMATION;
0224
0225 if (!rose_send_frame(skb, neigh))
0226 kfree_skb(skb);
0227 }
0228
0229
0230
0231
0232
0233 void rose_transmit_clear_request(struct rose_neigh *neigh, unsigned int lci, unsigned char cause, unsigned char diagnostic)
0234 {
0235 struct sk_buff *skb;
0236 unsigned char *dptr;
0237 int len;
0238
0239 len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN + 3;
0240
0241 if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
0242 return;
0243
0244 skb_reserve(skb, AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN);
0245
0246 dptr = skb_put(skb, ROSE_MIN_LEN + 3);
0247
0248 *dptr++ = AX25_P_ROSE;
0249 *dptr++ = ((lci >> 8) & 0x0F) | ROSE_GFI;
0250 *dptr++ = ((lci >> 0) & 0xFF);
0251 *dptr++ = ROSE_CLEAR_REQUEST;
0252 *dptr++ = cause;
0253 *dptr++ = diagnostic;
0254
0255 if (!rose_send_frame(skb, neigh))
0256 kfree_skb(skb);
0257 }
0258
0259 void rose_transmit_link(struct sk_buff *skb, struct rose_neigh *neigh)
0260 {
0261 unsigned char *dptr;
0262
0263 if (neigh->loopback) {
0264 rose_loopback_queue(skb, neigh);
0265 return;
0266 }
0267
0268 if (!rose_link_up(neigh))
0269 neigh->restarted = 0;
0270
0271 dptr = skb_push(skb, 1);
0272 *dptr++ = AX25_P_ROSE;
0273
0274 if (neigh->restarted) {
0275 if (!rose_send_frame(skb, neigh))
0276 kfree_skb(skb);
0277 } else {
0278 skb_queue_tail(&neigh->queue, skb);
0279
0280 if (!rose_t0timer_running(neigh)) {
0281 rose_transmit_restart_request(neigh);
0282 neigh->dce_mode = 0;
0283 rose_start_t0timer(neigh);
0284 }
0285 }
0286 }