ax25_ip.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * AX.25 release 037
  3.  *
  4.  * This code REQUIRES 2.1.15 or higher/ NET3.038
  5.  *
  6.  * This module:
  7.  * This module is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU General Public License
  9.  * as published by the Free Software Foundation; either version
  10.  * 2 of the License, or (at your option) any later version.
  11.  *
  12.  * History
  13.  * AX.25 036 Jonathan(G4KLX) Split from af_ax25.c.
  14.  */
  15. #include <linux/config.h>
  16. #include <linux/errno.h>
  17. #include <linux/types.h>
  18. #include <linux/socket.h>
  19. #include <linux/in.h>
  20. #include <linux/kernel.h>
  21. #include <linux/sched.h>
  22. #include <linux/timer.h>
  23. #include <linux/string.h>
  24. #include <linux/sockios.h>
  25. #include <linux/net.h>
  26. #include <net/ax25.h>
  27. #include <linux/inet.h>
  28. #include <linux/netdevice.h>
  29. #include <linux/if_arp.h>
  30. #include <linux/skbuff.h>
  31. #include <net/sock.h>
  32. #include <asm/uaccess.h>
  33. #include <asm/system.h>
  34. #include <linux/fcntl.h>
  35. #include <linux/termios.h> /* For TIOCINQ/OUTQ */
  36. #include <linux/mm.h>
  37. #include <linux/interrupt.h>
  38. #include <linux/notifier.h>
  39. #include <linux/proc_fs.h>
  40. #include <linux/stat.h>
  41. #include <linux/netfilter.h>
  42. #include <linux/sysctl.h>
  43. #include <net/ip.h>
  44. #include <net/arp.h>
  45. /*
  46.  * IP over AX.25 encapsulation.
  47.  */
  48. /*
  49.  * Shove an AX.25 UI header on an IP packet and handle ARP
  50.  */
  51. #ifdef CONFIG_INET
  52. int ax25_encapsulate(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len)
  53. {
  54. unsigned char *buff;
  55. /* they sometimes come back to us... */
  56. if (type == ETH_P_AX25)
  57. return 0;
  58.    /* header is an AX.25 UI frame from us to them */
  59.   buff = skb_push(skb, AX25_HEADER_LEN);
  60.    *buff++ = 0x00; /* KISS DATA */
  61. if (daddr != NULL)
  62. memcpy(buff, daddr, dev->addr_len); /* Address specified */
  63.    buff[6] &= ~AX25_CBIT;
  64.    buff[6] &= ~AX25_EBIT;
  65.    buff[6] |= AX25_SSSID_SPARE;
  66.    buff    += AX25_ADDR_LEN;
  67.    if (saddr != NULL)
  68.    memcpy(buff, saddr, dev->addr_len);
  69.    else
  70.    memcpy(buff, dev->dev_addr, dev->addr_len);
  71.    buff[6] &= ~AX25_CBIT;
  72.    buff[6] |= AX25_EBIT;
  73.    buff[6] |= AX25_SSSID_SPARE;
  74.    buff    += AX25_ADDR_LEN;
  75.    *buff++  = AX25_UI; /* UI */
  76.    /* Append a suitable AX.25 PID */
  77.    switch (type) {
  78.    case ETH_P_IP:
  79.    *buff++ = AX25_P_IP;
  80.   break;
  81.    case ETH_P_ARP:
  82.    *buff++ = AX25_P_ARP;
  83.    break;
  84.    default:
  85.    printk(KERN_ERR "AX.25: ax25_encapsulate - wrong protocol type 0x%2.2xn", type);
  86.    *buff++ = 0;
  87.    break;
  88.   }
  89. if (daddr != NULL)
  90.    return AX25_HEADER_LEN;
  91. return -AX25_HEADER_LEN; /* Unfinished header */
  92. }
  93. int ax25_rebuild_header(struct sk_buff *skb)
  94. {
  95. struct sk_buff *ourskb;
  96. unsigned char *bp  = skb->data;
  97. struct net_device *dev;
  98. ax25_address *src, *dst;
  99. ax25_route *route;
  100. ax25_dev *ax25_dev;
  101. dst = (ax25_address *)(bp + 1);
  102. src = (ax25_address *)(bp + 8);
  103.    if (arp_find(bp + 1, skb))
  104.    return 1;
  105. route    = ax25_rt_find_route(dst, NULL);
  106. dev      = route->dev;
  107. if (dev == NULL)
  108. dev = skb->dev;
  109.         if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
  110.                 return 1;
  111. if (bp[16] == AX25_P_IP) {
  112. if (route->ip_mode == 'V' || (route->ip_mode == ' ' && ax25_dev->values[AX25_VALUES_IPDEFMODE])) {
  113. /*
  114.  * We copy the buffer and release the original thereby
  115.  * keeping it straight
  116.  *
  117.  * Note: we report 1 back so the caller will
  118.  * not feed the frame direct to the physical device
  119.  * We don't want that to happen. (It won't be upset
  120.  * as we have pulled the frame from the queue by
  121.  * freeing it).
  122.  *
  123.  * NB: TCP modifies buffers that are still
  124.  * on a device queue, thus we use skb_copy()
  125.  *      instead of using skb_clone() unless this
  126.  * gets fixed.
  127.  */
  128. ax25_address src_c;
  129. ax25_address dst_c;
  130. if ((ourskb = skb_copy(skb, GFP_ATOMIC)) == NULL) {
  131. kfree_skb(skb);
  132. return 1;
  133. }
  134. if (skb->sk != NULL)
  135. skb_set_owner_w(ourskb, skb->sk);
  136. kfree_skb(skb);
  137. src_c = *src;
  138. dst_c = *dst;
  139. skb_pull(ourskb, AX25_HEADER_LEN - 1); /* Keep PID */
  140. ourskb->nh.raw = ourskb->data;
  141. ax25_send_frame(ourskb, ax25_dev->values[AX25_VALUES_PACLEN], &src_c, 
  142. &dst_c, route->digipeat, dev);
  143. return 1;
  144. }
  145. }
  146.    bp[7]  &= ~AX25_CBIT;
  147.    bp[7]  &= ~AX25_EBIT;
  148.    bp[7]  |= AX25_SSSID_SPARE;
  149.    bp[14] &= ~AX25_CBIT;
  150.    bp[14] |= AX25_EBIT;
  151.    bp[14] |= AX25_SSSID_SPARE;
  152. skb_pull(skb, AX25_KISS_HEADER_LEN);
  153. if (route->digipeat != NULL) {
  154. if ((ourskb = ax25_rt_build_path(skb, src, dst, route->digipeat)) == NULL) {
  155. kfree_skb(skb);
  156. return 1;
  157. }
  158. skb = ourskb;
  159. }
  160. skb->dev      = dev;
  161. ax25_queue_xmit(skb);
  162.    return 1;
  163. }
  164. #else /* INET */
  165. int ax25_encapsulate(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len)
  166. {
  167. return -AX25_HEADER_LEN;
  168. }
  169. int ax25_rebuild_header(struct sk_buff *skb)
  170. {
  171. return 1;
  172. }
  173. #endif