|
|
1.1 ! root 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 7.1 (Berkeley) 6/5/86 ! 7: */ ! 8: ! 9: #include "param.h" ! 10: #include "mbuf.h" ! 11: #include "socket.h" ! 12: #include "protosw.h" ! 13: #include "socketvar.h" ! 14: #include "errno.h" ! 15: ! 16: #include "../net/if.h" ! 17: #include "../net/route.h" ! 18: #include "../net/raw_cb.h" ! 19: ! 20: #include "in.h" ! 21: #include "in_systm.h" ! 22: #include "ip.h" ! 23: #include "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: * Setup generic address and protocol structures ! 34: * for raw_input routine, then pass them along with ! 35: * mbuf chain. ! 36: */ ! 37: rip_input(m) ! 38: struct mbuf *m; ! 39: { ! 40: register struct ip *ip = mtod(m, struct ip *); ! 41: ! 42: ripproto.sp_protocol = ip->ip_p; ! 43: ripdst.sin_addr = ip->ip_dst; ! 44: ripsrc.sin_addr = ip->ip_src; ! 45: raw_input(m, &ripproto, (struct sockaddr *)&ripsrc, ! 46: (struct sockaddr *)&ripdst); ! 47: } ! 48: ! 49: /* ! 50: * Generate IP header and pass packet to ip_output. ! 51: * Tack on options user may have setup with control call. ! 52: */ ! 53: rip_output(m0, so) ! 54: struct mbuf *m0; ! 55: struct socket *so; ! 56: { ! 57: register struct mbuf *m; ! 58: register struct ip *ip; ! 59: int len = 0, error; ! 60: struct rawcb *rp = sotorawcb(so); ! 61: struct sockaddr_in *sin; ! 62: ! 63: /* ! 64: * Calculate data length and get an mbuf ! 65: * for IP header. ! 66: */ ! 67: for (m = m0; m; m = m->m_next) ! 68: len += m->m_len; ! 69: m = m_get(M_DONTWAIT, MT_HEADER); ! 70: if (m == 0) { ! 71: error = ENOBUFS; ! 72: goto bad; ! 73: } ! 74: ! 75: /* ! 76: * Fill in IP header as needed. ! 77: */ ! 78: m->m_off = MMAXOFF - sizeof(struct ip); ! 79: m->m_len = sizeof(struct ip); ! 80: m->m_next = m0; ! 81: ip = mtod(m, struct ip *); ! 82: ip->ip_tos = 0; ! 83: ip->ip_off = 0; ! 84: ip->ip_p = rp->rcb_proto.sp_protocol; ! 85: ip->ip_len = sizeof(struct ip) + len; ! 86: if (rp->rcb_flags & RAW_LADDR) { ! 87: sin = (struct sockaddr_in *)&rp->rcb_laddr; ! 88: if (sin->sin_family != AF_INET) { ! 89: error = EAFNOSUPPORT; ! 90: goto bad; ! 91: } ! 92: ip->ip_src.s_addr = sin->sin_addr.s_addr; ! 93: } else ! 94: ip->ip_src.s_addr = 0; ! 95: ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr; ! 96: ip->ip_ttl = MAXTTL; ! 97: return (ip_output(m, rp->rcb_options, &rp->rcb_route, ! 98: (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST)); ! 99: bad: ! 100: m_freem(m); ! 101: return (error); ! 102: } ! 103: ! 104: /* ! 105: * Raw IP socket option processing. ! 106: */ ! 107: rip_ctloutput(op, so, level, optname, m) ! 108: int op; ! 109: struct socket *so; ! 110: int level, optname; ! 111: struct mbuf **m; ! 112: { ! 113: int error = 0; ! 114: register struct rawcb *rp = sotorawcb(so); ! 115: ! 116: if (level != IPPROTO_IP) ! 117: error = EINVAL; ! 118: else switch (op) { ! 119: ! 120: case PRCO_SETOPT: ! 121: switch (optname) { ! 122: case IP_OPTIONS: ! 123: return (ip_pcbopts(&rp->rcb_options, *m)); ! 124: ! 125: default: ! 126: error = EINVAL; ! 127: break; ! 128: } ! 129: break; ! 130: ! 131: case PRCO_GETOPT: ! 132: switch (optname) { ! 133: case IP_OPTIONS: ! 134: *m = m_get(M_WAIT, MT_SOOPTS); ! 135: if (rp->rcb_options) { ! 136: (*m)->m_off = rp->rcb_options->m_off; ! 137: (*m)->m_len = rp->rcb_options->m_len; ! 138: bcopy(mtod(rp->rcb_options, caddr_t), ! 139: mtod(*m, caddr_t), (unsigned)(*m)->m_len); ! 140: } else ! 141: (*m)->m_len = 0; ! 142: break; ! 143: default: ! 144: error = EINVAL; ! 145: break; ! 146: } ! 147: break; ! 148: } ! 149: if (op == PRCO_SETOPT) ! 150: (void)m_free(*m); ! 151: return (error); ! 152: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.