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->tail; 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 unsigned short cisco_type_trans(struct sk_buff *skb, 95 struct net_device *dev) 96 { 97 hdlc_header *data = (hdlc_header*)skb->data; 98 99 if (skb->len < sizeof(hdlc_header)) 100 return __constant_htons(ETH_P_HDLC); 101 102 if (data->address != CISCO_MULTICAST && 103 data->address != CISCO_UNICAST) 104 return __constant_htons(ETH_P_HDLC); 105 106 switch(data->protocol) { 107 case __constant_htons(ETH_P_IP): 108 case __constant_htons(ETH_P_IPX): 109 case __constant_htons(ETH_P_IPV6): 110 skb_pull(skb, sizeof(hdlc_header)); 111 return data->protocol; 112 default: 113 return __constant_htons(ETH_P_HDLC); 114 } 115 } 116 117 118 static int cisco_rx(struct sk_buff *skb) 119 { 120 struct net_device *dev = skb->dev; 121 hdlc_device *hdlc = dev_to_hdlc(dev); 122 hdlc_header *data = (hdlc_header*)skb->data; 123 cisco_packet *cisco_data; 124 struct in_device *in_dev; 125 u32 addr, mask; 126 127 if (skb->len < sizeof(hdlc_header)) 128 goto rx_error; 129 130 if (data->address != CISCO_MULTICAST && 131 data->address != CISCO_UNICAST) 132 goto rx_error; 133 134 switch(ntohs(data->protocol)) { 135 case CISCO_SYS_INFO: 136 /* Packet is not needed, drop it. */ 137 dev_kfree_skb_any(skb); 138 return NET_RX_SUCCESS; 139 140 case CISCO_KEEPALIVE: 141 if (skb->len != sizeof(hdlc_header) + CISCO_PACKET_LEN && 142 skb->len != sizeof(hdlc_header) + CISCO_BIG_PACKET_LEN) { 143 printk(KERN_INFO "%s: Invalid length of Cisco " 144 "control packet (%d bytes)\n", 145 dev->name, skb->len); 146 goto rx_error; 147 } 148 149 cisco_data = (cisco_packet*)(skb->data + sizeof(hdlc_header)); 150 151 switch(ntohl (cisco_data->type)) { 152 case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */ 153 in_dev = dev->ip_ptr; 154 addr = 0; 155 mask = ~0; /* is the mask correct? */ 156 157 if (in_dev != NULL) { 158 struct in_ifaddr **ifap = &in_dev->ifa_list; 159 160 while (*ifap != NULL) { 161 if (strcmp(dev->name, 162 (*ifap)->ifa_label) == 0) { 163 addr = (*ifap)->ifa_local; 164 mask = (*ifap)->ifa_mask; 165 break; 166 } 167 ifap = &(*ifap)->ifa_next; 168 } 169 170 cisco_keepalive_send(dev, CISCO_ADDR_REPLY, 171 addr, mask); 172 } 173 dev_kfree_skb_any(skb); 174 return NET_RX_SUCCESS; 175 176 case CISCO_ADDR_REPLY: 177 printk(KERN_INFO "%s: Unexpected Cisco IP address " 178 "reply\n", dev->name); 179 goto rx_error; 180 181 case CISCO_KEEPALIVE_REQ: 182 hdlc->state.cisco.rxseq = ntohl(cisco_data->par1); 183 if (hdlc->state.cisco.request_sent && 184 ntohl(cisco_data->par2)==hdlc->state.cisco.txseq) { 185 hdlc->state.cisco.last_poll = jiffies; 186 if (!hdlc->state.cisco.up) { 187 u32 sec, min, hrs, days; 188 sec = ntohl(cisco_data->time) / 1000; 189 min = sec / 60; sec -= min * 60; 190 hrs = min / 60; min -= hrs * 60; 191 days = hrs / 24; hrs -= days * 24; 192 printk(KERN_INFO "%s: Link up (peer " 193 "uptime %ud%uh%um%us)\n", 194 dev->name, days, hrs, 195 min, sec); 196 netif_carrier_on(dev); 197 hdlc->state.cisco.up = 1; 198 } 199 } 200 201 dev_kfree_skb_any(skb); 202 return NET_RX_SUCCESS; 203 } /* switch(keepalive type) */ 204 } /* switch(protocol) */ 205 206 printk(KERN_INFO "%s: Unsupported protocol %x\n", dev->name, 207 data->protocol); 208 dev_kfree_skb_any(skb); 209 return NET_RX_DROP; 210 211 rx_error: 212 hdlc->stats.rx_errors++; /* Mark error */ 213 dev_kfree_skb_any(skb); 214 return NET_RX_DROP; 215 } 216 217 218 219 static void cisco_timer(unsigned long arg) 220 { 221 struct net_device *dev = (struct net_device *)arg; 222 hdlc_device *hdlc = dev_to_hdlc(dev); 223 224 if (hdlc->state.cisco.up && 225 time_after(jiffies, hdlc->state.cisco.last_poll + 226 hdlc->state.cisco.settings.timeout * HZ)) { 227 hdlc->state.cisco.up = 0; 228 printk(KERN_INFO "%s: Link down\n", dev->name); 229 netif_carrier_off(dev); 230 } 231 232 cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, 233 ++hdlc->state.cisco.txseq, 234 hdlc->state.cisco.rxseq); 235 hdlc->state.cisco.request_sent = 1; 236 hdlc->state.cisco.timer.expires = jiffies + 237 hdlc->state.cisco.settings.interval * HZ; 238 hdlc->state.cisco.timer.function = cisco_timer; 239 hdlc->state.cisco.timer.data = arg; 240 add_timer(&hdlc->state.cisco.timer); 241 } 242 243 244 245 static void cisco_start(struct net_device *dev) 246 { 247 hdlc_device *hdlc = dev_to_hdlc(dev); 248 hdlc->state.cisco.up = 0; 249 hdlc->state.cisco.request_sent = 0; 250 hdlc->state.cisco.txseq = hdlc->state.cisco.rxseq = 0; 251 252 init_timer(&hdlc->state.cisco.timer); 253 hdlc->state.cisco.timer.expires = jiffies + HZ; /*First poll after 1s*/ 254 hdlc->state.cisco.timer.function = cisco_timer; 255 hdlc->state.cisco.timer.data = (unsigned long)dev; 256 add_timer(&hdlc->state.cisco.timer); 257 } 258 259 260 261 static void cisco_stop(struct net_device *dev) 262 { 263 hdlc_device *hdlc = dev_to_hdlc(dev); 264 del_timer_sync(&hdlc->state.cisco.timer); 265 if (netif_carrier_ok(dev)) 266 netif_carrier_off(dev); 267 hdlc->state.cisco.up = 0; 268 hdlc->state.cisco.request_sent = 0; 269 } 270 271 272 273 int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr) 274 { 275 cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco; 276 const size_t size = sizeof(cisco_proto); 277 cisco_proto new_settings; 278 hdlc_device *hdlc = dev_to_hdlc(dev); 279 int result; 280 281 switch (ifr->ifr_settings.type) { 282 case IF_GET_PROTO: 283 ifr->ifr_settings.type = IF_PROTO_CISCO; 284 if (ifr->ifr_settings.size < size) { 285 ifr->ifr_settings.size = size; /* data size wanted */ 286 return -ENOBUFS; 287 } 288 if (copy_to_user(cisco_s, &hdlc->state.cisco.settings, size)) 289 return -EFAULT; 290 return 0; 291 292 case IF_PROTO_CISCO: 293 if(!capable(CAP_NET_ADMIN)) 294 return -EPERM; 295 296 if(dev->flags & IFF_UP) 297 return -EBUSY; 298 299 if (copy_from_user(&new_settings, cisco_s, size)) 300 return -EFAULT; 301 302 if (new_settings.interval < 1 || 303 new_settings.timeout < 2) 304 return -EINVAL; 305 306 result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT); 307 308 if (result) 309 return result; 310 311 hdlc_proto_detach(hdlc); 312 memcpy(&hdlc->state.cisco.settings, &new_settings, size); 313 memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 314 315 hdlc->proto.start = cisco_start; 316 hdlc->proto.stop = cisco_stop; 317 hdlc->proto.netif_rx = cisco_rx; 318 hdlc->proto.type_trans = cisco_type_trans; 319 hdlc->proto.id = IF_PROTO_CISCO; 320 dev->hard_start_xmit = hdlc->xmit; 321 dev->hard_header = cisco_hard_header; 322 dev->hard_header_cache = NULL; 323 dev->type = ARPHRD_CISCO; 324 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 325 dev->addr_len = 0; 326 return 0; 327 } 328 329 return -EINVAL; 330 } 331