|
|
1.1 root 1: /* raw_pup.c 6.1 83/07/29 */
2:
3: #include "../h/param.h"
4: #include "../h/mbuf.h"
5: #include "../h/socket.h"
6: #include "../h/protosw.h"
7: #include "../h/socketvar.h"
8: #include "../h/errno.h"
9:
10: #include "../net/if.h"
11: #include "../net/route.h"
12: #include "../net/raw_cb.h"
13:
14: #include "../netpup/pup.h"
15:
16: /*
17: * Raw PUP protocol interface.
18: */
19:
20: struct sockaddr_pup pupsrc = { AF_PUP };
21: struct sockaddr_pup pupdst = { AF_PUP };
22: struct sockproto pupproto = { PF_PUP };
23: /*
24: * Raw PUP input.
25: */
26: rpup_input(m)
27: struct mbuf *m;
28: {
29: register struct pup_header *pup = mtod(m, struct pup_header *);
30:
31: pupproto.sp_protocol = pup->pup_type;
32: bcopy((caddr_t)&pup->pup_dnet, (caddr_t)&pupdst.spup_net,
33: sizeof (struct pupport));
34: bcopy((caddr_t)&pup->pup_snet, (caddr_t)&pupsrc.spup_net,
35: sizeof (struct pupport));
36: raw_input(m, &pupproto, (struct sockaddr *)&pupsrc,
37: (struct sockaddr *)&pupdst);
38: }
39:
40: /*
41: * Encapsulate packet in PUP header which is supplied by the
42: * user. This is done to allow user to specify PUP identifier.
43: */
44: rpup_output(m, so)
45: register struct mbuf *m;
46: struct socket *so;
47: {
48: register struct rawcb *rp = sotorawcb(so);
49: register struct pup_header *pup;
50: int len, error = 0;
51: register struct mbuf *n, *last;
52: struct sockaddr_pup *dst;
53: struct ifnet *ifp;
54: u_short *pc;
55:
56: /*
57: * Verify user has supplied necessary space
58: * for the header and check parameters in it.
59: */
60: if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct pup_header)) &&
61: (m = m_pullup(m, sizeof(struct pup_header))) == 0) {
62: error = EINVAL;
63: goto bad;
64: }
65: pup = mtod(m, struct pup_header *);
66: if (pup->pup_type == 0 || (pup->pup_tcontrol &~ PUP_TRACE)) {
67: error = EINVAL;
68: goto bad;
69: }
70: for (len = 0, n = last = m; n; last = n, n = n->m_next)
71: len += n->m_len;
72: /* assume user leaves space for checksum */
73: if ((len & 1) || len < MINPUPSIZ || len > MAXPUPSIZ) {
74: error = EMSGSIZE;
75: goto bad;
76: }
77: pup->pup_length = htons((u_short)len);
78: dst = (struct sockaddr_pup *)&rp->rcb_faddr;
79: bcopy((caddr_t)&dst->spup_net, (caddr_t)&pup->pup_dnet,
80: sizeof (struct pupport));
81: if (rp->rcb_route.ro_rt == 0)
82: ifp = if_ifonnetof(dst->spup_net);
83: else {
84: rp->rcb_route.ro_rt->rt_use++;
85: ifp = rp->rcb_route.ro_rt->rt_ifp;
86: }
87: if (ifp == 0) {
88: error = ENETUNREACH;
89: goto bad;
90: }
91: if (rp->rcb_flags & RAW_LADDR) {
92: register struct sockaddr_pup *src;
93:
94: src = (struct sockaddr_pup *)&rp->rcb_laddr;
95: bcopy((caddr_t)&src->spup_net, (caddr_t)&pup->pup_snet,
96: sizeof (struct pupport));
97: } else {
98: pup->pup_snet = ifp->if_net;
99: pup->pup_shost = ifp->if_host[0];
100: /* socket is specified by user */
101: }
102: /*
103: * Fill in checksum unless user indicates none should be specified.
104: */
105: pc = (u_short *)(mtod(last, caddr_t) + last->m_len - sizeof (short));
106: if (*pc != PUP_NOCKSUM)
107: *pc = htons((u_short)pup_cksum(m, len - sizeof (short)));
108: return ((*ifp->if_output)(ifp, m, (struct sockaddr *)dst));
109: bad:
110: m_freem(m);
111: return (error);
112: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.