Advertisement
vpenkoff

smmod

Apr 18th, 2013
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.27 KB | None | 0 0
  1. #include <sys/param.h>
  2. #include <sys/systm.h>
  3. #include <sys/kernel.h>
  4. #include <sys/mbuf.h>
  5. #include <sys/module.h>
  6. #include <machine/bus.h>
  7. #include <sys/rman.h>
  8. #include <sys/socket.h>
  9. #include <sys/sockio.h>
  10. #include <sys/sysctl.h>
  11.  
  12. #include <net/if.h>
  13. #include <net/if_clone.h>
  14. #include <net/if_types.h>
  15. #include <net/netisr.h>
  16. #include <net/route.h>
  17. #include <net/bpf.h>
  18. #include <net/vnet.h>
  19. #include <net/ethernet.h>
  20.  
  21. #ifdef INET
  22. #include <netinet/in.h>
  23. #include <netinet/in_var.h>
  24. #endif
  25.  
  26. #define SMMTU   (1024 + 512)
  27.  
  28. #define SM_CSUM_FEATURES    (CSUM_IP | CSUM_TCP | CSUM_UDP | CSUM_SCTP)
  29. #define SM_CSUM_SET     (CSUM_IP_CHECKED | CSUM_IP_VALID | CSUM_DATA_VALID | \
  30.                 CSUM_PSEUDO_HDR | CSUM_SCTP_VALID)
  31.  
  32. int     smioctl(struct ifnet *, u_long, caddr_t);
  33. static void smrtrequest(int, struct rtentry *, struct rt_addrinfo *);
  34. int     smoutput(struct ifnet *, struct mbuf *, struct sockaddr *, struct route *);
  35. void        loopatach(struct ifnet *, int);
  36.  
  37.  
  38. void
  39. loopatach(struct ifnet *ifp, int unit)
  40. {
  41.     ifp = if_alloc(IFT_LOOP);
  42.     if (ifp == NULL)
  43.         return;
  44.     if_initname(ifp, "sm", unit);
  45.     ifp->if_mtu = SMMTU;
  46.     ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
  47.     ifp->if_ioctl = smioctl;
  48.     ifp->if_output = smoutput;
  49.     ifp->if_snd.ifq_maxlen = ifqmaxlen;
  50.     ifp->if_capabilities = ifp->if_capenable = IFCAP_HWCSUM;
  51.     ifp->if_hwassist = SM_CSUM_FEATURES;
  52.     if_attach(ifp);
  53.     bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
  54. }
  55.  
  56. static void
  57. smrtrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info)
  58. {
  59.     RT_LOCK_ASSERT(rt);
  60.     rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu;
  61. }
  62.  
  63. int
  64. smioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  65. {
  66.     struct ifaddr *ifa;
  67.     struct ifreq *ifr = (struct ifreq *)data;
  68.     int error = 0, mask;
  69.  
  70.     switch (cmd) {
  71.     case SIOCSIFADDR:
  72.         ifp->if_flags |= IFF_UP;
  73.         ifp->if_drv_flags |= IFF_DRV_RUNNING;
  74.         ifa = (struct ifaddr *)data;
  75.         ifa->ifa_rtrequest = smrtrequest;
  76.         break;
  77.    
  78.  
  79.     case SIOCADDMULTI:
  80.     case SIOCDELMULTI:
  81.         if (ifr == 0) {
  82.             error = EAFNOSUPPORT;
  83.             break;
  84.         }
  85.        
  86.         if (ifr->ifr_addr.sa_family == AF_INET)
  87.             break;
  88.         else {
  89.             error = EAFNOSUPPORT;
  90.             break;
  91.         }
  92.  
  93.     case SIOCSIFMTU:
  94.         ifp->if_mtu = ifr->ifr_mtu;
  95.         break;
  96.    
  97.     case SIOCSIFFLAGS:
  98.         break;
  99.  
  100.     case SIOCSIFCAP:
  101.         mask = ifp->if_capenable ^ ifr->ifr_reqcap;
  102.         if ((mask & IFCAP_RXCSUM) != 0)
  103.             ifp->if_capenable ^= IFCAP_RXCSUM;
  104.         if ((mask & IFCAP_TXCSUM) != 0)
  105.             ifp->if_capenable ^= IFCAP_TXCSUM;
  106.        
  107.  
  108.         ifp->if_hwassist = 0;
  109.         if (ifp->if_capenable & IFCAP_TXCSUM)
  110.             ifp->if_hwassist = SM_CSUM_FEATURES;
  111.         break;
  112.    
  113.     default:
  114.         error = EINVAL;
  115.     }
  116.    
  117.     return (error);
  118. }
  119.  
  120. int
  121. smoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
  122.     struct route *ro)
  123. {
  124.     u_int32_t af;
  125.     struct rtentry *rt = NULL;
  126.  
  127. #ifdef MAC
  128.     int error = 0;
  129. #endif
  130.  
  131.     M_ASSERTPKTHDR(m);
  132.  
  133.     if (ro != NULL)
  134.         rt = ro->ro_rt;
  135.  
  136. #ifdef MAC
  137.     error = mac_ifnet_check_transmit(ifp, m);
  138.     if (error) {
  139.         m_freem(m);
  140.         return (error);
  141.     }
  142. #endif
  143.  
  144.     if (rt && rt->rt_flags & (RTF_REJECT | RTF_BLACKHOLE)) {
  145.         m_freem(m);
  146.         return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
  147.             rt->rt_flags & RTF_HOST ? EHOSTUNREACH :
  148.             ENETUNREACH);
  149.     }
  150.  
  151.     ifp->if_opackets++;
  152.     ifp->if_obytes += m->m_pkthdr.len;
  153.  
  154.     if (dst->sa_family == AF_UNSPEC) {
  155.         bcopy(dst->sa_data, &af, sizeof(af));
  156.         dst->sa_family = af;
  157.     }
  158.  
  159.     if (dst->sa_family == AF_INET) {
  160.             if (ifp->if_capenable & IFCAP_RXCSUM) {
  161.                 m->m_pkthdr.csum_data = 0xffff;
  162.                 m->m_pkthdr.csum_flags = SM_CSUM_SET;
  163.             }
  164.             m->m_pkthdr.csum_flags &= ~ SM_CSUM_FEATURES;
  165.     } else {
  166.         printf("smoutput: af=%d unexpected\n", dst->sa_family);
  167.         m_freem(m);
  168.         return (EAFNOSUPPORT);
  169.     }
  170.  
  171.     return (if_simloop(ifp, m, dst->sa_family, 0));
  172. }
  173.  
  174. int
  175. if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen)
  176. {
  177.     int isr, i;
  178.     struct ether_header *eh;
  179.     M_ASSERTPKTHDR(m);
  180.     m_tag_delete_nonpersistent(m);
  181.     m->m_pkthdr.rcvif = ifp;
  182.  
  183.     if (hlen > 0) {
  184.         if (bpf_peers_present(ifp->if_bpf)){
  185.             bpf_mtap(ifp->if_bpf, m);
  186.         }
  187.     } else {
  188.         m = m_pullup(m, sizeof(*eh));
  189.         if (m == NULL) {
  190.             return (EINVAL);
  191.         }
  192.     }
  193.    
  194.  
  195.  
  196.     if (hlen > 0) {
  197.         m_adj(m, hlen);
  198. #ifndef __NO_STRICT_ALIGNMENT
  199.         if (mtod(m, vm_offset_t) & 3) {
  200.             KASSERT(hlen >= 3, ("if_simloop: hlen too small"));
  201.             bcopy(m->m_data, (char*)(mtod(m, vm_offset_t)
  202.                 - (mtod(m,vm_offset_t) & 3)),
  203.                 m->m_len);
  204.             m->m_data -= (mtod(m, vm_offset_t) & 3);
  205.         }
  206. #endif
  207.     }
  208.  
  209.     if (af == AF_INET) {
  210.         isr = NETISR_IP;
  211.     } else {
  212.         printf("if_simloop: can't handle af=%d\n", af);
  213.         m_freem(m);
  214.         return (EAFNOSUPPORT);
  215.     }
  216.  
  217.     ifp->if_ipackets++;
  218.     ifp->if_ibytes += m->m_pkthdr.len;
  219.     netisr_queue(isr, m);
  220.  
  221.     BPF_MTAP(ifp, m);
  222.     eh = mtod(m, struct ether_header *);
  223.    
  224.     for (i = 0; i < ETHER_ADDR_LEN; i++){
  225.         printf("%2x", eh->ether_dhost[i]);
  226.         printf("\t");
  227.         printf("%2x", eh->ether_shost[i]);
  228.     }
  229.  
  230.     return (0);
  231. }
  232.  
  233. static int
  234. sm_modevent(module_t mod, int type, void *data)
  235. {
  236.     switch (type) {
  237.         case MOD_LOAD:
  238.             printf("module sm loaded\n");
  239.             break;
  240.  
  241.         case MOD_UNLOAD:
  242.             printf("module not possible to unload\n");
  243.             return (EINVAL);
  244.  
  245.         default:
  246.             return (EOPNOTSUPP);
  247.     }
  248.     return (0);
  249. }
  250.  
  251. static moduledata_t sm_mod = {
  252.     "if_sm",
  253.     sm_modevent,
  254.     0
  255. };
  256.  
  257. DECLARE_MODULE(if_sm, sm_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement