1 /* 2 * Generic HDLC support routines for Linux 3 * Cisco HDLC support 4 * 5 * Copyright (C) 2000 - 2003 Krzysztof Halasa <khc@pm.waw.pl> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of version 2 of the GNU General Public License 9 * as published by the Free Software Foundation. 10 */ 11 12 #include <linux/module.h> 13 #include <linux/kernel.h> 14 #include <linux/slab.h> 15 #include <linux/poll.h> 16 #include <linux/errno.h> 17 #include <linux/if_arp.h> 18 #include <linux/init.h> 19 #include <linux/skbuff.h> 20 #include <linux/pkt_sched.h> 21 #include <linux/inetdevice.h> 22 #include <linux/lapb.h> 23 #include <linux/rtnetlink.h> 24 #include <linux/hdlc.h> 25 26 #undef DEBUG_HARD_HEADER 27 28 #define CISCO_MULTICAST 0x8F /* Cisco multicast address */ 29 #define CISCO_UNICAST 0x0F /* Cisco unicast address */ 30 #define CISCO_KEEPALIVE 0x8035 /* Cisco keepalive protocol */ 31 #define CISCO_SYS_INFO 0x2000 /* Cisco interface/system info */ 32 #define CISCO_ADDR_REQ 0 /* Cisco address request */ 33 #define CISCO_ADDR_REPLY 1 /* Cisco address reply */ 34 #define CISCO_KEEPALIVE_REQ 2 /* Cisco keepalive request */ 35 36 37 static int cisco_hard_header(struct sk_buff *skb, struct net_device *dev, 38 u16 type, void *daddr, void *saddr, 39 unsigned int len) 40 { 41 hdlc_header *data; 42 #ifdef DEBUG_HARD_HEADER 43 printk(KERN_DEBUG "%s: cisco_hard_header called\n", dev->name); 44 #endif 45 46 skb_push(skb, sizeof(hdlc_header)); 47 data = (hdlc_header*)skb->data; 48 if (type == CISCO_KEEPALIVE) 49 data->address = CISCO_MULTICAST; 50 else 51 data->address = CISCO_UNICAST; 52 data->control = 0; 53 data->protocol = htons(type); 54 55 return sizeof(hdlc_header); 56 } 57 58 59 60 static void cisco_keepalive_send(struct net_device *dev, u32 type, 61 u32 par1, u32 par2) 62 { 63 struct sk_buff *skb; 64 cisco_packet *data; 65 66 skb = dev_alloc_skb(sizeof(hdlc_header) + sizeof(cisco_packet)); 67 if (!skb) { 68 printk(KERN_WARNING 69 "%s: Memory squeeze on cisco_keepalive_send()\n", 70 dev->name); 71 return; 72 } 73 skb_reserve(skb, 4); 74 cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0); 75 data = (cisco_packet*)(skb->data + 4); 76 77 data->type = htonl(type); 78 data->par1 = htonl(par1); 79 data->par2 = htonl(par2); 80 data->rel = 0xFFFF; 81 /* we will need do_div here if 1000 % HZ != 0 */ 82 data->time = htonl((jiffies - INITIAL_JIFFIES) * (1000 / HZ)); 83 84 skb_put(skb, sizeof(cisco_packet)); 85 skb->priority = TC_PRIO_CONTROL; 86 skb->dev = dev; 87 skb->nh.raw = skb->data; 88 89 dev_queue_xmit(skb); 90 } 91 92 93 94 static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev) 95 { 96 hdlc_header *data = (hdlc_header*)skb->data; 97 98 if (skb->len < sizeof(hdlc_header)) 99 return __constant_htons(ETH_P_HDLC); 100 101 if (data->address != CISCO_MULTICAST && 102 data->address != CISCO_UNICAST) 103 return __constant_htons(ETH_P_HDLC); 104 105 switch(data->protocol) { 106 case __constant_htons(ETH_P_IP): 107 case __constant_htons(ETH_P_IPX): 108 case __constant_htons(ETH_P_IPV6): 109 skb_pull(skb, sizeof(hdlc_header)); 110 return data->protocol; 111 default: 112 return __constant_htons(ETH_P_HDLC); 113 } 114 } 115 116 117 static int cisco_rx(struct sk_buff *skb) 118 { 119 struct net_device *dev = skb->dev; 120 hdlc_device *hdlc = dev_to_hdlc(dev); 121 hdlc_header *data = (hdlc_header*)skb->data; 122 cisco_packet *cisco_data; 123 struct in_device *in_dev; 124 u32 addr, mask; 125 126 if (skb->len < sizeof(hdlc_header)) 127 goto rx_error; 128 129 if (data->address != CISCO_MULTICAST && 130 data->address != CISCO_UNICAST) 131 goto rx_error; 132 133 switch(ntohs(data->protocol)) { 134 case CISCO_SYS_INFO: 135 /* Packet is not needed, drop it. */ 136 dev_kfree_skb_any(skb); 137 return NET_RX_SUCCESS; 138 139 case CISCO_KEEPALIVE: 140 if (skb->len != sizeof(hdlc_header) + CISCO_PACKET_LEN && 141 skb->len != sizeof(hdlc_header) + CISCO_BIG_PACKET_LEN) { 142 printk(KERN_INFO "%s: Invalid length of Cisco " 143 "control packet (%d bytes)\n", 144 dev->name, skb->len); 145 goto rx_error; 146 } 147 148 cisco_data = (cisco_packet*)(skb->data + sizeof(hdlc_header)); 149 150 switch(ntohl (cisco_data->type)) { 151 case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */ 152 in_dev = dev->ip_ptr; 153 addr = 0; 154 mask = ~0; /* is the mask correct? */ 155 156 if (in_dev != NULL) { 157 struct in_ifaddr **ifap = &in_dev->ifa_list; 158 159 while (*ifap != NULL) { 160 if (strcmp(dev->name, 161 (*ifap)->ifa_label) == 0) { 162 addr = (*ifap)->ifa_local; 163 mask = (*ifap)->ifa_mask; 164 break; 165 } 166 ifap = &(*ifap)->ifa_next; 167 } 168 169 cisco_keepalive_send(dev, CISCO_ADDR_REPLY, 170 addr, mask); 171 } 172 dev_kfree_skb_any(skb); 173 return NET_RX_SUCCESS; 174 175 case CISCO_ADDR_REPLY: 176 printk(KERN_INFO "%s: Unexpected Cisco IP address " 177 "reply\n", dev->name); 178 goto rx_error; 179 180 case CISCO_KEEPALIVE_REQ: 181 hdlc->state.cisco.rxseq = ntohl(cisco_data->par1); 182 if (hdlc->state.cisco.request_sent && 183 ntohl(cisco_data->par2)==hdlc->state.cisco.txseq) { 184 hdlc->state.cisco.last_poll = jiffies; 185 if (!hdlc->state.cisco.up) { 186 u32 sec, min, hrs, days; 187 sec = ntohl(cisco_data->time) / 1000; 188 min = sec / 60; sec -= min * 60; 189 hrs = min / 60; min -= hrs * 60; 190 days = hrs / 24; hrs -= days * 24; 191 printk(KERN_INFO "%s: Link up (peer " 192 "uptime %ud%uh%um%us)\n", 193 dev->name, days, hrs, 194 min, sec); 195 #if 0 196 netif_carrier_on(dev); 197 #endif 198 hdlc->state.cisco.up = 1; 199 } 200 } 201 202 dev_kfree_skb_any(skb); 203 return NET_RX_SUCCESS; 204 } /* switch(keepalive type) */ 205 } /* switch(protocol) */ 206 207 printk(KERN_INFO "%s: Unsupported protocol %x\n", dev->name, 208 data->protocol); 209 dev_kfree_skb_any(skb); 210 return NET_RX_DROP; 211 212 rx_error: 213 hdlc->stats.rx_errors++; /* Mark error */ 214 dev_kfree_skb_any(skb); 215 return NET_RX_DROP; 216 } 217 218 219 220 static void cisco_timer(unsigned long arg) 221 { 222 struct net_device *dev = (struct net_device *)arg; 223 hdlc_device *hdlc = dev_to_hdlc(dev); 224 225 if (hdlc->state.cisco.up && 226 time_after(jiffies, hdlc->state.cisco.last_poll + 227 hdlc->state.cisco.settings.timeout * HZ)) { 228 hdlc->state.cisco.up = 0; 229 printk(KERN_INFO "%s: Link down\n", dev->name); 230 #if 0 231 netif_carrier_off(dev); 232 #endif 233 } 234 235 cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, 236 ++hdlc->state.cisco.txseq, 237 hdlc->state.cisco.rxseq); 238 hdlc->state.cisco.request_sent = 1; 239 hdlc->state.cisco.timer.expires = jiffies + 240 hdlc->state.cisco.settings.interval * HZ; 241 hdlc->state.cisco.timer.function = cisco_timer; 242 hdlc->state.cisco.timer.data = arg; 243 add_timer(&hdlc->state.cisco.timer); 244 } 245 246 247 248 static void cisco_start(struct net_device *dev) 249 { 250 hdlc_device *hdlc = dev_to_hdlc(dev); 251 hdlc->state.cisco.up = 0; 252 hdlc->state.cisco.request_sent = 0; 253 hdlc->state.cisco.txseq = hdlc->state.cisco.rxseq = 0; 254 255 init_timer(&hdlc->state.cisco.timer); 256 hdlc->state.cisco.timer.expires = jiffies + HZ; /*First poll after 1s*/ 257 hdlc->state.cisco.timer.function = cisco_timer; 258 hdlc->state.cisco.timer.data = (unsigned long)dev; 259 add_timer(&hdlc->state.cisco.timer); 260 } 261 262 263 264 static void cisco_stop(struct net_device *dev) 265 { 266 hdlc_device *hdlc = dev_to_hdlc(dev); 267 del_timer_sync(&hdlc->state.cisco.timer); 268 #if 0 269 if (netif_carrier_ok(dev)) 270 netif_carrier_off(dev); 271 #endif 272 hdlc->state.cisco.up = 0; 273 hdlc->state.cisco.request_sent = 0; 274 } 275 276 277 278 int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr) 279 { 280 cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco; 281 const size_t size = sizeof(cisco_proto); 282 cisco_proto new_settings; 283 hdlc_device *hdlc = dev_to_hdlc(dev); 284 int result; 285 286 switch (ifr->ifr_settings.type) { 287 case IF_GET_PROTO: 288 ifr->ifr_settings.type = IF_PROTO_CISCO; 289 if (ifr->ifr_settings.size < size) { 290 ifr->ifr_settings.size = size; /* data size wanted */ 291 return -ENOBUFS; 292 } 293 if (copy_to_user(cisco_s, &hdlc->state.cisco.settings, size)) 294 return -EFAULT; 295 return 0; 296 297 case IF_PROTO_CISCO: 298 if(!capable(CAP_NET_ADMIN)) 299 return -EPERM; 300 301 if(dev->flags & IFF_UP) 302 return -EBUSY; 303 304 if (copy_from_user(&new_settings, cisco_s, size)) 305 return -EFAULT; 306 307 if (new_settings.interval < 1 || 308 new_settings.timeout < 2) 309 return -EINVAL; 310 311 result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT); 312 313 if (result) 314 return result; 315 316 hdlc_proto_detach(hdlc); 317 memcpy(&hdlc->state.cisco.settings, &new_settings, size); 318 memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 319 320 hdlc->proto.start = cisco_start; 321 hdlc->proto.stop = cisco_stop; 322 hdlc->proto.netif_rx = cisco_rx; 323 hdlc->proto.type_trans = cisco_type_trans; 324 hdlc->proto.id = IF_PROTO_CISCO; 325 dev->hard_start_xmit = hdlc->xmit; 326 dev->hard_header = cisco_hard_header; 327 dev->hard_header_cache = NULL; 328 dev->type = ARPHRD_CISCO; 329 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 330 dev->addr_len = 0; 331 return 0; 332 } 333 334 return -EINVAL; 335 } 336