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