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

Defined functions

rip_ctloutput defined in line 131; never used
rip_input defined in line 44; never used
rip_output defined in line 56; never used

Defined variables

ripdst defined in line 36; used 2 times
ripproto defined in line 38; used 2 times
ripsrc defined in line 37; used 2 times
Last modified: 1989-07-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3656
Valid CSS Valid XHTML 1.0 Strict