|
|
1.1 ! root 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 the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: * ! 17: * @(#)raw_ip.c 7.4 (Berkeley) 6/29/88 ! 18: */ ! 19: ! 20: #include "param.h" ! 21: #include "mbuf.h" ! 22: #include "socket.h" ! 23: #include "protosw.h" ! 24: #include "socketvar.h" ! 25: #include "errno.h" ! 26: ! 27: #include "../net/if.h" ! 28: #include "../net/route.h" ! 29: #include "../net/raw_cb.h" ! 30: ! 31: #include "in.h" ! 32: #include "in_systm.h" ! 33: #include "ip.h" ! 34: #include "ip_var.h" ! 35: ! 36: /* ! 37: * Raw interface to IP protocol. ! 38: */ ! 39: ! 40: struct sockaddr_in ripdst = { AF_INET }; ! 41: struct sockaddr_in ripsrc = { AF_INET }; ! 42: struct sockproto ripproto = { PF_INET }; ! 43: /* ! 44: * Setup generic address and protocol structures ! 45: * for raw_input routine, then pass them along with ! 46: * mbuf chain. ! 47: */ ! 48: rip_input(m) ! 49: struct mbuf *m; ! 50: { ! 51: register struct ip *ip = mtod(m, struct ip *); ! 52: ! 53: ripproto.sp_protocol = ip->ip_p; ! 54: ripdst.sin_addr = ip->ip_dst; ! 55: ripsrc.sin_addr = ip->ip_src; ! 56: raw_input(m, &ripproto, (struct sockaddr *)&ripsrc, ! 57: (struct sockaddr *)&ripdst); ! 58: } ! 59: ! 60: /* ! 61: * Generate IP header and pass packet to ip_output. ! 62: * Tack on options user may have setup with control call. ! 63: */ ! 64: rip_output(m0, so) ! 65: struct mbuf *m0; ! 66: struct socket *so; ! 67: { ! 68: register struct mbuf *m; ! 69: register struct ip *ip; ! 70: int len = 0, error; ! 71: struct rawcb *rp = sotorawcb(so); ! 72: struct sockaddr_in *sin; ! 73: ! 74: /* ! 75: * Calculate data length and get an mbuf ! 76: * for IP header. ! 77: */ ! 78: for (m = m0; m; m = m->m_next) ! 79: len += m->m_len; ! 80: m = m_get(M_DONTWAIT, MT_HEADER); ! 81: if (m == 0) { ! 82: error = ENOBUFS; ! 83: goto bad; ! 84: } ! 85: ! 86: /* ! 87: * Fill in IP header as needed. ! 88: */ ! 89: m->m_off = MMAXOFF - sizeof(struct ip); ! 90: m->m_len = sizeof(struct ip); ! 91: m->m_next = m0; ! 92: ip = mtod(m, struct ip *); ! 93: ip->ip_tos = 0; ! 94: ip->ip_off = 0; ! 95: ip->ip_p = rp->rcb_proto.sp_protocol; ! 96: ip->ip_len = sizeof(struct ip) + len; ! 97: if (rp->rcb_flags & RAW_LADDR) { ! 98: sin = (struct sockaddr_in *)&rp->rcb_laddr; ! 99: if (sin->sin_family != AF_INET) { ! 100: error = EAFNOSUPPORT; ! 101: goto bad; ! 102: } ! 103: ip->ip_src.s_addr = sin->sin_addr.s_addr; ! 104: } else ! 105: ip->ip_src.s_addr = 0; ! 106: ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr; ! 107: ip->ip_ttl = MAXTTL; ! 108: return (ip_output(m, rp->rcb_options, &rp->rcb_route, ! 109: (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST)); ! 110: bad: ! 111: m_freem(m); ! 112: return (error); ! 113: } ! 114: ! 115: /* ! 116: * Raw IP socket option processing. ! 117: */ ! 118: rip_ctloutput(op, so, level, optname, m) ! 119: int op; ! 120: struct socket *so; ! 121: int level, optname; ! 122: struct mbuf **m; ! 123: { ! 124: int error = 0; ! 125: register struct rawcb *rp = sotorawcb(so); ! 126: ! 127: if (level != IPPROTO_IP) ! 128: error = EINVAL; ! 129: else switch (op) { ! 130: ! 131: case PRCO_SETOPT: ! 132: switch (optname) { ! 133: case IP_OPTIONS: ! 134: return (ip_pcbopts(&rp->rcb_options, *m)); ! 135: ! 136: default: ! 137: error = EINVAL; ! 138: break; ! 139: } ! 140: break; ! 141: ! 142: case PRCO_GETOPT: ! 143: switch (optname) { ! 144: case IP_OPTIONS: ! 145: *m = m_get(M_WAIT, MT_SOOPTS); ! 146: if (rp->rcb_options) { ! 147: (*m)->m_off = rp->rcb_options->m_off; ! 148: (*m)->m_len = rp->rcb_options->m_len; ! 149: bcopy(mtod(rp->rcb_options, caddr_t), ! 150: mtod(*m, caddr_t), (unsigned)(*m)->m_len); ! 151: } else ! 152: (*m)->m_len = 0; ! 153: break; ! 154: default: ! 155: error = EINVAL; ! 156: break; ! 157: } ! 158: break; ! 159: } ! 160: if (op == PRCO_SETOPT && *m) ! 161: (void)m_free(*m); ! 162: return (error); ! 163: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.