📄 sdla_ppp.c
字号:
/* It's an IPX packet */ if (!enable_IPX) { /* Return 1 so we don't pass it up the stack. */ return 1; } } else { /* It's not IPX so pass it up the stack. */ return 0; } if (sendpacket[16] == 0x90 && sendpacket[17] == 0x04) { /* It's IPXWAN */ if (sendpacket[2] == 0x02 && sendpacket[34] == 0x00) { /* It's a timer request packet */ printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n", devname); /* Go through the routing options and answer no to every */ /* option except Unnumbered RIP/SAP */ for (i = 41; sendpacket[i] == 0x00; i += 5) { /* 0x02 is the option for Unnumbered RIP/SAP */ if (sendpacket[i + 4] != 0x02) { sendpacket[i + 1] = 0; } } /* Skip over the extended Node ID option */ if (sendpacket[i] == 0x04) { i += 8; } /* We also want to turn off all header compression opt. */ for (; sendpacket[i] == 0x80;) { sendpacket[i + 1] = 0; i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4; } /* Set the packet type to timer response */ sendpacket[34] = 0x01; printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n", devname); } else if (sendpacket[34] == 0x02) { /* This is an information request packet */ printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n", devname); /* Set the packet type to information response */ sendpacket[34] = 0x03; /* Set the router name */ sendpacket[51] = 'P'; sendpacket[52] = 'T'; sendpacket[53] = 'P'; sendpacket[54] = 'I'; sendpacket[55] = 'P'; sendpacket[56] = 'E'; sendpacket[57] = '-'; sendpacket[58] = CVHexToAscii(network_number >> 28); sendpacket[59] = CVHexToAscii((network_number & 0x0F000000) >> 24); sendpacket[60] = CVHexToAscii((network_number & 0x00F00000) >> 20); sendpacket[61] = CVHexToAscii((network_number & 0x000F0000) >> 16); sendpacket[62] = CVHexToAscii((network_number & 0x0000F000) >> 12); sendpacket[63] = CVHexToAscii((network_number & 0x00000F00) >> 8); sendpacket[64] = CVHexToAscii((network_number & 0x000000F0) >> 4); sendpacket[65] = CVHexToAscii(network_number & 0x0000000F); for (i = 66; i < 99; i += 1) sendpacket[i] = 0; printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n", devname); } else { printk(KERN_INFO "%s: Unknown IPXWAN packet!\n", devname); return 0; } /* Set the WNodeID to our network address */ sendpacket[35] = (unsigned char) (network_number >> 24); sendpacket[36] = (unsigned char) ((network_number & 0x00FF0000) >> 16); sendpacket[37] = (unsigned char) ((network_number & 0x0000FF00) >> 8); sendpacket[38] = (unsigned char) (network_number & 0x000000FF); return 1; } else { /* If we get here's its an IPX-data packet, so it'll get passed up the stack. */ /* switch the network numbers */ switch_net_numbers(sendpacket, network_number, 1); return 0; }}/****** Background Polling Routines ****************************************//*============================================================================ * Main polling routine. * This routine is repeatedly called by the WANPIPE 'thread' to allow for * time-dependent housekeeping work. * * Notes: * 1. This routine may be called on interrupt context with all interrupts * enabled. Beware! */static void wpp_poll(sdla_t * card){ struct device *dev = card->wandev.dev; ppp_flags_t *adptr_flags = card->flags; unsigned long host_cpu_flags; ++card->statistics.poll_entry; /* The wpp_poll is called continously by the WANPIPE thread to allow * for line state housekeeping. However if we are in a connected state * then we do not need to go through all the checks everytime. When in * connected state execute wpp_poll once every second. */ if (card->wandev.state == WAN_CONNECTED) { if ((jiffies - card->state_tick) < HZ) return; } disable_irq(card->hw.irq); ++card->irq_dis_poll_count; if (test_and_set_bit(0, (void *) &card->wandev.critical)) { ++card->statistics.poll_already_critical; printk(KERN_INFO "%s: critical inside wpp_poll\n", card->devname); save_flags(host_cpu_flags); cli(); if ((!card->irq_dis_if_send_count) && (!(--card->irq_dis_poll_count))) enable_irq(card->hw.irq); restore_flags(host_cpu_flags); return; } ++card->statistics.poll_processed; if (dev && dev->tbusy && !(adptr_flags->imask & 0x02)) { ++card->statistics.poll_tbusy_bad_status; printk(KERN_INFO "%s: Wpp_Poll: tbusy = 0x01, imask = 0x%02X\n" ,card->devname, adptr_flags->imask); } switch (card->wandev.state) { case WAN_CONNECTED: card->state_tick = jiffies; poll_active(card); break; case WAN_CONNECTING: poll_connecting(card); break; case WAN_DISCONNECTED: poll_disconnected(card); break; default: printk(KERN_INFO "%s: Unknown Poll State 0x%02X\n", card->devname, card->wandev.state); break; } card->wandev.critical = 0; save_flags(host_cpu_flags); cli(); if ((!card->irq_dis_if_send_count) && (!(--card->irq_dis_poll_count))) enable_irq(card->hw.irq); restore_flags(host_cpu_flags);}/*============================================================================ * Monitor active link phase. */static void poll_active(sdla_t * card){ ppp_flags_t *flags = card->flags; /* We check the lcp_state to see if we are in DISCONNECTED state. * We are considered to be connected for lcp states 0x06, 0x07, 0x08 * and 0x09. */ if ((flags->lcp_state <= 0x05) || (flags->disc_cause & 0x03)) { wanpipe_set_state(card, WAN_DISCONNECTED); show_disc_cause(card, flags->disc_cause); }}/*============================================================================ * Monitor link establishment phase. * o if connection timed out, disconnect the link. */static void poll_connecting(sdla_t * card){ ppp_flags_t *flags = card->flags; if (flags->lcp_state == 0x09) { wanpipe_set_state(card, WAN_CONNECTED); } else if (flags->disc_cause & 0x03) { wanpipe_set_state(card, WAN_DISCONNECTED); show_disc_cause(card, flags->disc_cause); }}/*============================================================================ * Monitor physical link disconnected phase. * o if interface is up and the hold-down timeout has expired, then retry * connection. */static void poll_disconnected(sdla_t * card){ struct device *dev = card->wandev.dev; if (dev && dev->start && ((jiffies - card->state_tick) > HOLD_DOWN_TIME)) { wanpipe_set_state(card, WAN_CONNECTING); if (ppp_comm_enable(card) == CMD_OK) init_ppp_tx_rx_buff(card); }}/****** Miscellaneous Functions *********************************************//*============================================================================ * Configure S502 adapter. */static int config502(sdla_t * card){ ppp502_conf_t cfg; /* Prepare PPP configuration structure */ memset(&cfg, 0, sizeof(ppp502_conf_t)); if (card->wandev.clocking) cfg.line_speed = bps_to_speed_code(card->wandev.bps); cfg.txbuf_num = 4; cfg.mtu_local = card->wandev.mtu; cfg.mtu_remote = card->wandev.mtu; cfg.restart_tmr = 30; cfg.auth_rsrt_tmr = 30; cfg.auth_wait_tmr = 300; cfg.mdm_fail_tmr = 5; cfg.dtr_drop_tmr = 1; cfg.connect_tmout = 0; /* changed it from 900 */ cfg.conf_retry = 10; cfg.term_retry = 2; cfg.fail_retry = 5; cfg.auth_retry = 10; cfg.ip_options = 0x80; cfg.ipx_options = 0xA0; cfg.conf_flags |= 0x0E;/* cfg.ip_local = dev->pa_addr; cfg.ip_remote = dev->pa_dstaddr; */ return ppp_configure(card, &cfg);}/*============================================================================ * Configure S508 adapter. */static int config508(sdla_t * card){ ppp508_conf_t cfg; /* Prepare PPP configuration structure */ memset(&cfg, 0, sizeof(ppp508_conf_t)); if (card->wandev.clocking) cfg.line_speed = card->wandev.bps; if (card->wandev.interface == WANOPT_RS232) cfg.conf_flags |= 0x0020; cfg.conf_flags |= 0x300; /*send Configure-Request packets forever */ cfg.txbuf_percent = 60; /* % of Tx bufs */ cfg.mtu_local = card->wandev.mtu; cfg.mtu_remote = card->wandev.mtu; cfg.restart_tmr = 30; cfg.auth_rsrt_tmr = 30; cfg.auth_wait_tmr = 300; cfg.mdm_fail_tmr = 100; cfg.dtr_drop_tmr = 1; cfg.connect_tmout = 0; /* changed it from 900 */ cfg.conf_retry = 10; cfg.term_retry = 2; cfg.fail_retry = 5; cfg.auth_retry = 10; cfg.ip_options = 0x80; cfg.ipx_options = 0xA0;/* cfg.ip_local = dev->pa_addr; cfg.ip_remote = dev->pa_dstaddr; */ return ppp_configure(card, &cfg);}/*============================================================================ * Show disconnection cause. */static void show_disc_cause(sdla_t * card, unsigned cause){ if (cause & 0x0002) printk(KERN_INFO "%s: link terminated by peer\n", card->devname); else if (cause & 0x0004) printk(KERN_INFO "%s: link terminated by user\n", card->devname); else if (cause & 0x0008) printk(KERN_INFO "%s: authentication failed\n", card->devname); else if (cause & 0x0010) printk(KERN_INFO "%s: authentication protocol negotiation failed\n", card->devname); else if (cause & 0x0020) printk(KERN_INFO "%s: peer's request for authentication rejected\n", card->devname); else if (cause & 0x0040) printk(KERN_INFO "%s: MRU option rejected by peer\n", card->devname); else if (cause & 0x0080) printk(KERN_INFO "%s: peer's MRU was too small\n", card->devname); else if (cause & 0x0100) printk(KERN_INFO "%s: failed to negotiate peer's LCP options\n", card->devname); else if (cause & 0x0200) printk(KERN_INFO "%s: failed to negotiate peer's IPCP options\n" ,card->devname); else if (cause & 0x0400) printk(KERN_INFO "%s: failed to negotiate peer's IPXCP options\n", card->devname);}/*============================================================================ * Convert line speed in bps to a number used by S502 code. */static unsigned char bps_to_speed_code(unsigned long bps){ unsigned char number; if (bps <= 1200) number = 0x01; else if (bps <= 2400) number = 0x02; else if (bps <= 4800) number = 0x03; else if (bps <= 9600) number = 0x04; else if (bps <= 19200) number = 0x05; else if (bps <= 38400) number = 0x06; else if (bps <= 45000) number = 0x07; else if (bps <= 56000) number = 0x08; else if (bps <= 64000) number = 0x09; else if (bps <= 74000) number = 0x0A; else if (bps <= 112000) number = 0x0B; else if (bps <= 128000) number = 0x0C; else number = 0x0D; return number;}/*============================================================================ * Process UDP call of type DRVSTATS. */static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, ppp_private_area_t * ppp_priv_area){ unsigned char *sendpacket; unsigned char buf2[5]; unsigned char *data; unsigned char *buf; unsigned int len; ppp_mbox_t *mbox = card->mbox; struct sk_buff *new_skb; int err; sendpacket = skb->data; memcpy(&buf2, &card->wandev.udp_port, 2); if ((data = kmalloc(2000, GFP_ATOMIC)) == NULL) { printk(KERN_INFO "%s: Error allocating memory for UDP DRIVER STATS cmnd0x%02X" ,card->devname, data[45]); ++ppp_priv_area->UDP_DRVSTATS_mgmt_kmalloc_err; return 1; } memcpy(data, sendpacket, skb->len); switch (data[45]) { /* PPIPE_DRIVER_STATISTICS */ case 0x26: *(unsigned long *) &data[60] = ppp_priv_area->if_send_entry; *(unsigned long *) &data[64] = ppp_priv_area->if_send_skb_null; *(unsigned long *) &data[68] = ppp_priv_area->if_send_broadcast; *(unsigned long *) &data[72] = ppp_priv_area->if_send_multicast; *(unsigned long *) &data[76] = ppp_priv_area->if_send_critical_ISR; *(unsigned long *) &data[80] = ppp_priv_area->if_send_critical_non_ISR; *(unsigned long *) &data[84] = ppp_priv_area->if_send_busy; *(unsigned long *) &data[88] = ppp_priv_area->if_send_busy_timeout; *(unsigned long *) &data[92] = ppp_priv_area->if_send_DRVSTATS_request; *(unsigned long *) &data[96] = ppp_priv_area->if_send_PTPIPE_request; *(unsigned long *) &data[100] = ppp_priv_area->if_send_wan_disconnected; *(unsigned long *) &data[104] = ppp_priv_area->if_send_adptr_bfrs_full; *(unsigned long *) &data[108] = ppp_priv_area->if_send_protocol_error; *(unsigned long *) &data[112] = ppp_priv_area->if_send_tx_int_enabled; *(unsigned long *) &data[116] = ppp_priv_area->if_send_bfr_passed_to_adptr; *(unsigned long *) &data[118] = card->irq_dis_if_send_count; mbox->cmd.length = 62; break; case 0x27: *(unsigned long *) &data[60] = card->statistics.isr_entry; *(unsigned long *) &data[64] = card->statistics.isr_already_critical; *(unsigned long *) &data[68] = card->statistics.isr_rx; *(unsigned long *) &data[72] = card->statistics.isr_tx;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -