home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / s0ftpj / eth_out_ex.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  6.3 KB  |  263 lines

  1. /*
  2.  * This kld gives you an example of how you can modify 
  3.  * the output function of an Ethernet Interface....
  4.  * 
  5.  * 
  6.  * Note: Don't use it for loopback, ppp or other no eth interfaces !
  7.  *
  8.  * pigpen [pigpen@s0ftpj.org, deadhead@sikurezza.org]
  9.  * 
  10.  * SoftProject NoProfit 
  11.  * Italian Security Organization
  12.  * www.s0ftpj.org
  13.  *
  14.  * Sikurezza.org
  15.  * Italian Security MailingList
  16.  * www.sikurezza.org
  17.  *
  18.  */
  19.  
  20. /* 
  21.  * pay attention... this kld can change in future...
  22.  * 
  23.  * uname -a
  24.  *
  25.  * FreeBSD storpio.cameretta.pig 4.0-19990705-CURRENT FreeBSD 4.0-19990705-
  26.  * CURRENT #4 ..... i386
  27.  *
  28.  * If you wanna a porting of this code and you have no time to do that 
  29.  * write me at: deadhead@sikurezza.org with subject "PORTING A KLD"
  30.  * 
  31.  */
  32.  
  33. #define INTERFACE        "ed"
  34. #define INTERFACE_NUM        0
  35.  
  36.  
  37. #include <sys/param.h>
  38. #include <sys/systm.h>
  39. #include <sys/malloc.h>
  40. #include <sys/mbuf.h>
  41. #include <sys/kernel.h>
  42. #include <sys/proc.h>
  43. #include <sys/socket.h>
  44. #include <sys/socketvar.h>
  45. #include <net/if.h>
  46. #include <netinet/in.h>
  47. #include <netinet/in_systm.h>
  48. #include <netinet/ip.h>
  49. #include <netinet/ip_var.h>
  50.  
  51. #include <net/netisr.h>
  52. #include <net/route.h>
  53. #include <net/if_types.h>
  54.  
  55. #include <netinet/in_var.h>
  56. #include <netinet/if_ether.h>
  57.  
  58.  
  59.  
  60.  
  61. #define        IFP2AC(IFP)    ((struct arpcom *) IFP)
  62. #define        senderr(e)    do { error = (e); goto bad;} while (0)
  63.  
  64. int    my_eth_output            __P((register struct ifnet *,
  65.                          struct mbuf *, struct sockaddr *,
  66.                          struct rtentry *));
  67.  
  68. static int    module_handler        __P((struct module *, int, void *));
  69.  
  70. /*
  71.  * Ethernet output routine.
  72.  * Encapsulate a packet of type family for the local net.
  73.  * Use trailer local net encapsulation if enough data in first
  74.  * packet leaves a multiple of 512 bytes of data in remainder.
  75.  * Assumes that ifp is actually pointer to arpcom structure.
  76.  */
  77. int
  78. my_eth_output(ifp, m0, dst, rt0)
  79.     register struct ifnet *ifp;
  80.     struct mbuf *m0;
  81.     struct sockaddr *dst;
  82.     struct rtentry *rt0;
  83. {
  84.     short type;
  85.     int s, error = 0;
  86.      u_char edst[6];
  87.     register struct mbuf *m = m0;
  88.     register struct rtentry *rt;
  89.     register struct ether_header *eh;
  90.     int off, len = m->m_pkthdr.len, loop_copy = 0;
  91.     int hlen;    /* link layer header lenght */
  92.     struct arpcom *ac = IFP2AC(ifp);
  93.  
  94.     
  95.     if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
  96.         senderr(ENETDOWN);
  97.     rt = rt0;
  98.     if (rt) {
  99.         if ((rt->rt_flags & RTF_UP) == 0) {
  100.             rt0 = rt = rtalloc1(dst, 1, 0UL);
  101.             if (rt0)
  102.                 rt->rt_refcnt--;
  103.             else
  104.                 senderr(EHOSTUNREACH);
  105.         }
  106.         if (rt->rt_flags & RTF_GATEWAY) {
  107.             if (rt->rt_gwroute == 0)
  108.                 goto lookup;
  109.             if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
  110.                 rtfree(rt); rt = rt0;
  111.             lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1,
  112.                               0UL);
  113.                 if ((rt = rt->rt_gwroute) == 0)
  114.                     senderr(EHOSTUNREACH);
  115.             }
  116.         }
  117.         if (rt->rt_flags & RTF_REJECT)
  118.             if (rt->rt_rmx.rmx_expire == 0 ||
  119.                 time_second < rt->rt_rmx.rmx_expire)
  120.                 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
  121.     }
  122.     hlen = ETHER_HDR_LEN;
  123.     switch (dst->sa_family) {
  124.     case AF_INET:
  125.         if (!arpresolve(ac, rt, m, dst, edst, rt0))
  126.             return (0);    /* if not yet resolved */
  127.         off = m->m_pkthdr.len - m->m_len;
  128.         type = htons(ETHERTYPE_IP);
  129.         break;
  130.     case AF_UNSPEC:
  131.         loop_copy = -1; /* if this is for us, don't do it */
  132.         eh = (struct ether_header *)dst->sa_data;
  133.          (void)memcpy(edst, eh->ether_dhost, sizeof (edst));
  134.         type = eh->ether_type;
  135.         break;
  136.  
  137.     default:
  138.         printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
  139.             dst->sa_family);
  140.         senderr(EAFNOSUPPORT);
  141.     }
  142.  
  143.     /*
  144.      * Add local net header.  If no space in first mbuf,
  145.      * allocate another.
  146.      */
  147.     M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
  148.     if (m == 0)
  149.         senderr(ENOBUFS);
  150.     eh = mtod(m, struct ether_header *);
  151.     (void)memcpy(&eh->ether_type, &type,
  152.         sizeof(eh->ether_type));
  153.      (void)memcpy(eh->ether_dhost, edst, sizeof (edst));
  154.      (void)memcpy(eh->ether_shost, ac->ac_enaddr,
  155.         sizeof(eh->ether_shost));
  156.  
  157.     /*
  158.      * If a simplex interface, and the packet is being sent to our
  159.      * Ethernet address or a broadcast address, loopback a copy.
  160.      * XXX To make a simplex device behave exactly like a duplex
  161.      * device, we should copy in the case of sending to our own
  162.      * ethernet address (thus letting the original actually appear
  163.      * on the wire). However, we don't do that here for security
  164.      * reasons and compatibility with the original behavior.
  165.      */
  166.     if ((ifp->if_flags & IFF_SIMPLEX) && (loop_copy != -1)) {
  167.         if ((m->m_flags & M_BCAST) || (loop_copy > 0)) {
  168.             struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
  169.  
  170.             (void) if_simloop(ifp, n, dst, hlen);
  171.         } else if (bcmp(eh->ether_dhost,
  172.             eh->ether_shost, ETHER_ADDR_LEN) == 0) {
  173.             (void) if_simloop(ifp, m, dst, hlen);
  174.             return (0);    /* XXX */
  175.         }
  176.     }
  177. /*#ifdef BRIDGE
  178.     if (do_bridge) {
  179.         struct mbuf *m0 = m ;
  180.  
  181.         if (m->m_pkthdr.rcvif)
  182.             m->m_pkthdr.rcvif = NULL ;
  183.         ifp = bridge_dst_lookup(m);
  184.         bdg_forward(&m0, ifp);
  185.         if (m0)
  186.             m_freem(m0);
  187.         return (0);
  188.     }
  189. #endif*/
  190.     s = splimp();
  191.     /*
  192.      * Queue message on interface, and start output if interface
  193.      * not yet active.
  194.      */
  195.     if (IF_QFULL(&ifp->if_snd)) {
  196.         IF_DROP(&ifp->if_snd);
  197.         splx(s);
  198.         senderr(ENOBUFS);
  199.     }
  200.     IF_ENQUEUE(&ifp->if_snd, m);
  201.     if ((ifp->if_flags & IFF_OACTIVE) == 0)
  202.         (*ifp->if_start)(ifp);
  203.     splx(s);
  204.     ifp->if_obytes += len + sizeof (struct ether_header);
  205.     if (m->m_flags & M_MCAST)
  206.         ifp->if_omcasts++;
  207.     return (error);
  208.  
  209. bad:
  210.     if (m)
  211.         m_freem(m);
  212.     return (error);
  213. }
  214.  
  215.  
  216.  
  217. static int
  218. module_handler(struct module *module, int cmd, void *arg) {
  219.     int s;
  220.     struct ifnet *ifp;
  221.     
  222.     switch(cmd) {
  223.         case MOD_LOAD:
  224.          s = splimp();
  225.          for(ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) {
  226.           /* pig: sys/queue.h-> TAILQ_FOREACH(ifp, &ifnet, if_link) */
  227.             printf("%s%d -> ", ifp->if_name, ifp->if_unit);
  228.             if(!strcmp(ifp->if_name,INTERFACE) &&
  229.                     ifp->if_unit == INTERFACE_NUM) {
  230.                 ifp->if_output = my_eth_output;
  231.                 printf("MODIFIED");
  232.             } else
  233.                 printf("no");
  234.             printf("\n");
  235.          }
  236.          splx(s);
  237.          break;
  238.          
  239.         case MOD_UNLOAD:
  240.          s = splimp();
  241.          for(ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) {
  242.           if( !strcmp(ifp->if_name,INTERFACE) &&
  243.                  ifp->if_unit == INTERFACE_NUM) {
  244.            ifp->if_output = ether_output;
  245.            printf("%s%d output funct: Updated\n",ifp->if_name, 
  246.                                     ifp->if_unit);
  247.           }
  248.          }
  249.          splx(s);
  250.          break;
  251.     }
  252.  
  253.     return 0;
  254. }
  255.  
  256. static moduledata_t mymod = {
  257.     "eth_out",
  258.     module_handler,
  259.     0
  260. };
  261.  
  262. DECLARE_MODULE(eth_out, mymod, SI_SUB_PSEUDO, SI_ORDER_ANY);
  263.