This source file includes following definitions.
- ddp_output
- at_cksum
- ddp_route
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 #include <sys/types.h>
73 #include <sys/param.h>
74 #include <sys/systm.h>
75 #include <sys/mbuf.h>
76 #include <sys/socket.h>
77 #include <sys/errno.h>
78 #include <sys/syslog.h>
79
80 #include <net/if.h>
81 #include <net/route.h>
82
83 #include <netinet/in.h>
84 #undef s_net
85 #include <netinet/if_ether.h>
86
87 #include <machine/endian.h>
88
89 #include <netatalk/at.h>
90 #include <netatalk/at_var.h>
91 #include <netatalk/ddp.h>
92 #include <netatalk/ddp_var.h>
93 #include <netatalk/at_extern.h>
94
95 int ddp_output( struct mbuf *, ... );
96 u_int16_t at_cksum( struct mbuf *, int );
97 int ddp_route(struct mbuf *, struct route * );
98
99 int ddp_cksum = 1;
100
101 int
102 ddp_output(struct mbuf *m, ...)
103 {
104 struct ddpcb *ddp;
105 struct ddpehdr *deh;
106 va_list ap;
107
108 va_start(ap, m);
109 ddp = va_arg(ap, struct ddpcb *);
110 va_end(ap);
111
112 M_PREPEND( m, sizeof( struct ddpehdr ), M_DONTWAIT );
113 if (!m)
114 return (ENOBUFS);
115
116 deh = mtod( m, struct ddpehdr *);
117 deh->deh_pad = 0;
118 deh->deh_hops = 0;
119
120 deh->deh_len = m->m_pkthdr.len;
121
122 deh->deh_dnet = ddp->ddp_fsat.sat_addr.s_net;
123 deh->deh_dnode = ddp->ddp_fsat.sat_addr.s_node;
124 deh->deh_dport = ddp->ddp_fsat.sat_port;
125 deh->deh_snet = ddp->ddp_lsat.sat_addr.s_net;
126 deh->deh_snode = ddp->ddp_lsat.sat_addr.s_node;
127 deh->deh_sport = ddp->ddp_lsat.sat_port;
128
129
130
131
132
133 if ( ddp_cksum ) {
134 deh->deh_sum = at_cksum( m, sizeof( int ));
135 } else {
136 deh->deh_sum = 0;
137 }
138 deh->deh_bytes = htonl( deh->deh_bytes );
139
140 return( ddp_route( m, &ddp->ddp_route ));
141 }
142
143 u_int16_t
144 at_cksum( m, skip )
145 struct mbuf *m;
146 int skip;
147 {
148 u_int8_t *data, *end;
149 u_long cksum = 0;
150
151 for (; m; m = m->m_next ) {
152 for ( data = mtod( m, u_int8_t * ), end = data + m->m_len; data < end;
153 data++ ) {
154 if ( skip ) {
155 skip--;
156 continue;
157 }
158 cksum = ( cksum + *data ) << 1;
159 if ( cksum & 0x00010000 ) {
160 cksum++;
161 }
162 cksum &= 0x0000ffff;
163 }
164 }
165
166 if ( cksum == 0 ) {
167 cksum = 0x0000ffff;
168 }
169 return( (u_int16_t)cksum );
170 }
171
172 int
173 ddp_route( m, ro )
174 struct mbuf *m;
175 struct route *ro;
176 {
177 struct sockaddr_at gate;
178 struct elaphdr *elh;
179 struct at_ifaddr *aa = NULL;
180 struct ifnet *ifp;
181 u_int16_t net;
182
183 if ( ro->ro_rt && ( ifp = ro->ro_rt->rt_ifp )) {
184 net = satosat( ro->ro_rt->rt_gateway )->sat_addr.s_net;
185 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
186 if ( aa->aa_ifp == ifp &&
187 ntohs( net ) >= ntohs( aa->aa_firstnet ) &&
188 ntohs( net ) <= ntohs( aa->aa_lastnet )) {
189 break;
190 }
191 }
192 }
193 if ( aa == NULL ) {
194 m_freem( m );
195 return( EINVAL );
196 }
197
198
199
200
201
202
203
204 if ( aa->aa_flags & AFA_PHASE2 ) {
205 if (( m = m_pullup( m, MIN( MHLEN, m->m_pkthdr.len ))) == 0 ) {
206 return( ENOBUFS );
207 }
208 } else {
209 M_PREPEND(m, SZ_ELAPHDR, M_DONTWAIT);
210 if (!m)
211 return (ENOBUFS);
212
213 elh = mtod( m, struct elaphdr *);
214 elh->el_snode = satosat( &aa->aa_addr )->sat_addr.s_node;
215 elh->el_type = ELAP_DDPEXTEND;
216 if ( ntohs( satosat( &ro->ro_dst )->sat_addr.s_net ) >=
217 ntohs( aa->aa_firstnet ) &&
218 ntohs( satosat( &ro->ro_dst )->sat_addr.s_net ) <=
219 ntohs( aa->aa_lastnet )) {
220 elh->el_dnode = satosat( &ro->ro_dst )->sat_addr.s_node;
221 } else {
222 elh->el_dnode = satosat( ro->ro_rt->rt_gateway )->sat_addr.s_node;
223 }
224 }
225
226 if ( ntohs( satosat( &ro->ro_dst )->sat_addr.s_net ) >=
227 ntohs( aa->aa_firstnet ) &&
228 ntohs( satosat( &ro->ro_dst )->sat_addr.s_net ) <=
229 ntohs( aa->aa_lastnet )) {
230 gate = *satosat( &ro->ro_dst );
231 } else {
232 gate = *satosat( ro->ro_rt->rt_gateway );
233 }
234 ro->ro_rt->rt_use++;
235
236
237 return((*ifp->if_output)( ifp, m, (struct sockaddr *) &gate, NULL ));
238 }