home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / src / traceroute / raw_ip.c < prev    next >
C/C++ Source or Header  |  1989-10-13  |  4KB  |  166 lines

  1. /*
  2.  * Copyright (c) 1982, 1986 Regents of the University of California.
  3.  * All rights reserved.  The Berkeley software License Agreement
  4.  * specifies the terms and conditions for redistribution.
  5.  *
  6.  *    @(#)raw_ip.c 1.11 89/01/16 SMI; from UCB 7.2 6/21/87
  7.  */
  8.  
  9. #include <sys/param.h>
  10. #include <sys/mbuf.h>
  11. #include <sys/socket.h>
  12. #include <sys/protosw.h>
  13. #include <sys/socketvar.h>
  14. #include <sys/errno.h>
  15.  
  16. #include <net/if.h>
  17. #include <net/route.h>
  18. #include <net/raw_cb.h>
  19.  
  20. #include <netinet/in.h>
  21. #include <netinet/in_systm.h>
  22. #include <netinet/ip.h>
  23. #include <netinet/ip_var.h>
  24.  
  25. /*
  26.  * Raw interface to IP protocol.
  27.  */
  28.  
  29. struct    sockaddr_in ripdst = { AF_INET };
  30. struct    sockaddr_in ripsrc = { AF_INET };
  31. struct    sockproto ripproto = { PF_INET };
  32.  
  33. /*
  34.  * Setup generic address and protocol structures
  35.  * for raw_input routine, then pass them along with
  36.  * mbuf chain.
  37.  */
  38. rip_input(m)
  39.     struct mbuf *m;
  40. {
  41.     register struct ip *ip = mtod(m, struct ip *);
  42.  
  43.     ripproto.sp_protocol = ip->ip_p;
  44.     ripdst.sin_addr = ip->ip_dst;
  45.     ripsrc.sin_addr = ip->ip_src;
  46.     raw_input(m, &ripproto, (struct sockaddr *)&ripsrc,
  47.       (struct sockaddr *)&ripdst);
  48. }
  49.  
  50. /*
  51.  * Generate IP header and pass packet to ip_output.
  52.  * Tack on options user may have setup with control call.
  53.  */
  54. rip_output(m, so)
  55.     register struct mbuf *m;
  56.     struct socket *so;
  57. {
  58.     register struct ip *ip;
  59.     int error;
  60.     struct rawcb *rp = sotorawcb(so);
  61.     struct sockaddr_in *sin;
  62.  
  63.     /*
  64.      * if the protocol is IPPROTO_RAW, the user handed us a 
  65.      * complete IP packet.  Otherwise, allocate an mbuf for a
  66.      * header and fill it in as needed.
  67.      */
  68.     if (so->so_proto->pr_protocol != IPPROTO_RAW) {
  69.         /*
  70.          * Calculate data length and get an mbuf
  71.          * for IP header.
  72.          */
  73.         int len = 0;
  74.         struct mbuf *m0;
  75.  
  76.         for (m0 = m; m; m = m->m_next)
  77.             len += m->m_len;
  78.  
  79.         m = m_get(M_DONTWAIT, MT_HEADER);
  80.         if (m == 0) {
  81.             m = m0;
  82.             error = ENOBUFS;
  83.             goto bad;
  84.         }
  85.         m->m_off = MMAXOFF - sizeof(struct ip);
  86.         m->m_len = sizeof(struct ip);
  87.         m->m_next = m0;
  88.  
  89.         ip = mtod(m, struct ip *);
  90.         ip->ip_off = 0;
  91.         ip->ip_tos = 0;
  92.         ip->ip_p = rp->rcb_proto.sp_protocol;
  93.         ip->ip_len = sizeof(struct ip) + len;
  94.         ip->ip_ttl = MAXTTL;
  95.     } else
  96.         ip = mtod(m, struct ip *);
  97.  
  98.     if (rp->rcb_flags & RAW_LADDR) {
  99.         sin = (struct sockaddr_in *)&rp->rcb_laddr;
  100.         if (sin->sin_family != AF_INET) {
  101.             error = EAFNOSUPPORT;
  102.             goto bad;
  103.         }
  104.         ip->ip_src.s_addr = sin->sin_addr.s_addr;
  105.     } else
  106.         ip->ip_src.s_addr = 0;
  107.  
  108.     ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr;
  109.  
  110.     return (ip_output(m, rp->rcb_options, &rp->rcb_route, 
  111.        (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST));
  112. bad:
  113.     m_freem(m);
  114.     return (error);
  115. }
  116.  
  117. /*
  118.  * Raw IP socket option processing.
  119.  */
  120. rip_ctloutput(op, so, level, optname, m)
  121.     int op;
  122.     struct socket *so;
  123.     int level, optname;
  124.     struct mbuf **m;
  125. {
  126.     int error = 0;
  127.     register struct rawcb *rp = sotorawcb(so);
  128.  
  129.     if (level != IPPROTO_IP)
  130.         error = EINVAL;
  131.     else switch (op) {
  132.  
  133.     case PRCO_SETOPT:
  134.         switch (optname) {
  135.         case IP_OPTIONS:
  136.             return (ip_pcbopts(&rp->rcb_options, *m));
  137.  
  138.         default:
  139.             error = EINVAL;
  140.             break;
  141.         }
  142.         break;
  143.  
  144.     case PRCO_GETOPT:
  145.         switch (optname) {
  146.         case IP_OPTIONS:
  147.             *m = m_get(M_WAIT, MT_SOOPTS);
  148.             if (rp->rcb_options) {
  149.                 (*m)->m_off = rp->rcb_options->m_off;
  150.                 (*m)->m_len = rp->rcb_options->m_len;
  151.                 bcopy(mtod(rp->rcb_options, caddr_t),
  152.                     mtod(*m, caddr_t), (unsigned)(*m)->m_len);
  153.             } else
  154.                 (*m)->m_len = 0;
  155.             break;
  156.         default:
  157.             error = EINVAL;
  158.             break;
  159.         }
  160.         break;
  161.     }
  162.     if (op == PRCO_SETOPT && *m)
  163.         (void)m_free(*m);
  164.     return (error);
  165. }
  166.