Commit | Line | Data |
---|---|---|
8ae0e4b4 | 1 | /* |
616d42db | 2 | * Copyright (c) 1982, 1986, 1988 Regents of the University of California. |
b0c21e3a | 3 | * All rights reserved. |
8ae0e4b4 | 4 | * |
dbf0c423 | 5 | * %sccs.include.redist.c% |
b0c21e3a | 6 | * |
5548a02f | 7 | * @(#)raw_imp.c 7.7 (Berkeley) %G% |
8ae0e4b4 | 8 | */ |
718d1f9e | 9 | |
5548a02f KB |
10 | #include <sys/param.h> |
11 | #include <sys/mbuf.h> | |
12 | #include <sys/socket.h> | |
13 | #include <sys/protosw.h> | |
14 | #include <sys/socketvar.h> | |
15 | #include <sys/errno.h> | |
f4d55810 | 16 | |
5548a02f KB |
17 | #include <net/if.h> |
18 | #include <net/route.h> | |
19 | #include <net/raw_cb.h> | |
f4d55810 | 20 | |
5548a02f KB |
21 | #include <netinet/in.h> |
22 | #include <netinet/in_systm.h> | |
23 | #include <netinet/in_var.h> | |
24 | #include <netinet/in_pcb.h> | |
25 | #include <netimp/if_imp.h> | |
718d1f9e BJ |
26 | |
27 | /* | |
28 | * Raw interface to IMP. | |
29 | */ | |
30 | ||
718d1f9e BJ |
31 | /* |
32 | * Generate IMP leader and pass packet to impoutput. | |
33 | * The user must create a skeletal leader in order to | |
34 | * communicate message type, message subtype, etc. | |
35 | * We fill in holes where needed and verify parameters | |
36 | * supplied by user. | |
37 | */ | |
8e999b50 | 38 | rimp_output(m, so) |
718d1f9e BJ |
39 | register struct mbuf *m; |
40 | struct socket *so; | |
41 | { | |
42 | struct mbuf *n; | |
126472ab | 43 | int len, error = 0; |
a0b7c7fb | 44 | register struct imp_leader *ip; |
718d1f9e | 45 | register struct sockaddr_in *sin; |
dce64e24 | 46 | register struct raw_inpcb *rp = sotorawinpcb(so); |
91b2c865 | 47 | struct in_ifaddr *ia; |
a2cd4df7 | 48 | struct control_leader *cp; |
718d1f9e | 49 | |
718d1f9e BJ |
50 | /* |
51 | * Verify user has supplied necessary space | |
52 | * for the leader and check parameters in it. | |
53 | */ | |
dce64e24 | 54 | if ((m->m_len < sizeof(struct control_leader)) && |
126472ab SL |
55 | (m = m_pullup(m, sizeof(struct control_leader))) == 0) { |
56 | error = EMSGSIZE; /* XXX */ | |
57 | goto bad; | |
58 | } | |
a2cd4df7 BJ |
59 | cp = mtod(m, struct control_leader *); |
60 | if (cp->dl_mtype == IMPTYPE_DATA) | |
61 | if (m->m_len < sizeof(struct imp_leader) && | |
126472ab SL |
62 | (m = m_pullup(m, sizeof(struct imp_leader))) == 0) { |
63 | error = EMSGSIZE; /* XXX */ | |
64 | goto bad; | |
65 | } | |
a0b7c7fb | 66 | ip = mtod(m, struct imp_leader *); |
126472ab SL |
67 | if (ip->il_format != IMP_NFF) { |
68 | error = EMSGSIZE; /* XXX */ | |
718d1f9e | 69 | goto bad; |
126472ab | 70 | } |
27cadab0 | 71 | #ifdef notdef |
a0b7c7fb | 72 | if (ip->il_link != IMPLINK_IP && |
126472ab SL |
73 | (ip->il_link<IMPLINK_LOWEXPER || ip->il_link>IMPLINK_HIGHEXPER)) { |
74 | error = EPERM; | |
718d1f9e | 75 | goto bad; |
126472ab | 76 | } |
27cadab0 | 77 | #endif |
718d1f9e BJ |
78 | |
79 | /* | |
80 | * Fill in IMP leader -- impoutput refrains from rebuilding | |
81 | * the leader when it sees the protocol family PF_IMPLINK. | |
82 | * (message size calculated by walking through mbuf's) | |
83 | */ | |
84 | for (len = 0, n = m; n; n = n->m_next) | |
85 | len += n->m_len; | |
668cc26d | 86 | ip->il_length = htons((u_short)(len << 3)); |
dce64e24 | 87 | sin = (struct sockaddr_in *)rp->rinp_rcb.rcb_faddr; |
357f1ef5 | 88 | imp_addr_to_leader((struct control_leader *)ip, sin->sin_addr.s_addr); |
ee787340 | 89 | /* no routing here */ |
91b2c865 MK |
90 | ia = in_iaonnetof(in_netof(sin->sin_addr)); |
91 | if (ia) | |
92 | return (impoutput(ia->ia_ifp, m, (struct sockaddr *)sin)); | |
126472ab | 93 | error = ENETUNREACH; |
718d1f9e BJ |
94 | bad: |
95 | m_freem(m); | |
126472ab | 96 | return (error); |
718d1f9e | 97 | } |