2 * Copyright (c) 1990,1994 Regents of The University of Michigan.
3 * All Rights Reserved. See COPYRIGHT.
5 * $FreeBSD: src/sys/netatalk/ddp_input.c,v 1.12 2000/02/13 03:31:58 peter Exp $
6 * $DragonFly: src/sys/netproto/atalk/ddp_input.c,v 1.14 2007/05/23 08:57:06 dillon Exp $
10 #include <sys/systm.h>
11 #include <sys/kernel.h>
13 #include <sys/socket.h>
14 #include <sys/socketvar.h>
16 #include <sys/thread2.h>
17 #include <sys/msgport2.h>
20 #include <net/netisr.h>
21 #include <net/route.h>
22 #include <net/intrq.h>
28 #include "at_extern.h"
30 static volatile int ddp_forward
= 1;
31 static volatile int ddp_firewall
= 0;
32 static struct ddpstat ddpstat
;
33 static struct route forwro
;
35 const int atintrq1_present
= 1, atintrq2_present
= 1;
37 static void ddp_input(struct mbuf
*, struct ifnet
*, struct elaphdr
*, int);
40 * Could probably merge these two code segments a little better...
43 at2intr(struct netmsg
*msg
)
45 struct mbuf
*m
= ((struct netmsg_packet
*)msg
)->nm_packet
;
48 * Phase 2 packet handling
50 ddp_input(m
, m
->m_pkthdr
.rcvif
, NULL
, 2);
51 /* msg was embedded in the mbuf, do not reply! */
55 at1intr(struct netmsg
*msg
)
57 struct mbuf
*m
= ((struct netmsg_packet
*)msg
)->nm_packet
;
58 struct elaphdr
*elhp
, elh
;
61 * Phase 1 packet handling
63 if (m
->m_len
< SZ_ELAPHDR
&& ((m
= m_pullup(m
, SZ_ELAPHDR
)) == 0)) {
64 ddpstat
.ddps_tooshort
++;
69 * This seems a little dubious, but I don't know phase 1 so leave it.
71 elhp
= mtod(m
, struct elaphdr
*);
74 if (elhp
->el_type
== ELAP_DDPEXTEND
) {
75 ddp_input(m
, m
->m_pkthdr
.rcvif
, NULL
, 1);
77 bcopy((caddr_t
)elhp
, (caddr_t
)&elh
, SZ_ELAPHDR
);
78 ddp_input(m
, m
->m_pkthdr
.rcvif
, &elh
, 1);
82 /* msg was embedded in the mbuf, do not reply! */
86 ddp_input(struct mbuf
*m
, struct ifnet
*ifp
, struct elaphdr
*elh
, int phase
)
88 struct sockaddr_at from
, to
;
89 struct ddpshdr
*dsh
, ddps
;
91 struct ddpehdr
*deh
= NULL
, ddpe
;
96 bzero( (caddr_t
)&from
, sizeof( struct sockaddr_at
));
97 bzero( (caddr_t
)&to
, sizeof( struct sockaddr_at
));
100 * Extract the information in the short header.
101 * netowrk information is defaulted to ATADDR_ANYNET
102 * and node information comes from the elh info.
103 * We must be phase 1.
105 ddpstat
.ddps_short
++;
107 if ( m
->m_len
< sizeof( struct ddpshdr
) &&
108 (( m
= m_pullup( m
, sizeof( struct ddpshdr
))) == 0 )) {
109 ddpstat
.ddps_tooshort
++;
113 dsh
= mtod( m
, struct ddpshdr
*);
114 bcopy( (caddr_t
)dsh
, (caddr_t
)&ddps
, sizeof( struct ddpshdr
));
115 ddps
.dsh_bytes
= ntohl( ddps
.dsh_bytes
);
118 to
.sat_addr
.s_net
= ATADDR_ANYNET
;
119 to
.sat_addr
.s_node
= elh
->el_dnode
;
120 to
.sat_port
= ddps
.dsh_dport
;
121 from
.sat_addr
.s_net
= ATADDR_ANYNET
;
122 from
.sat_addr
.s_node
= elh
->el_snode
;
123 from
.sat_port
= ddps
.dsh_sport
;
126 * Make sure that we point to the phase1 ifaddr info
127 * and that it's valid for this packet.
129 for ( aa
= at_ifaddr
; aa
; aa
= aa
->aa_next
) {
130 if ( (aa
->aa_ifp
== ifp
)
131 && ( (aa
->aa_flags
& AFA_PHASE2
) == 0)
132 && ( (to
.sat_addr
.s_node
== AA_SAT( aa
)->sat_addr
.s_node
)
133 || (to
.sat_addr
.s_node
== ATADDR_BCAST
))) {
138 * maybe we got a broadcast not meant for us.. ditch it.
146 * There was no 'elh' passed on. This could still be
147 * either phase1 or phase2.
148 * We have a long header, but we may be running on a phase 1 net.
149 * Extract out all the info regarding this packet's src & dst.
153 if ( m
->m_len
< sizeof( struct ddpehdr
) &&
154 (( m
= m_pullup( m
, sizeof( struct ddpehdr
))) == 0 )) {
155 ddpstat
.ddps_tooshort
++;
159 deh
= mtod( m
, struct ddpehdr
*);
160 bcopy( (caddr_t
)deh
, (caddr_t
)&ddpe
, sizeof( struct ddpehdr
));
161 ddpe
.deh_bytes
= ntohl( ddpe
.deh_bytes
);
164 if (( cksum
= ddpe
.deh_sum
) == 0 ) {
165 ddpstat
.ddps_nosum
++;
168 from
.sat_addr
.s_net
= ddpe
.deh_snet
;
169 from
.sat_addr
.s_node
= ddpe
.deh_snode
;
170 from
.sat_port
= ddpe
.deh_sport
;
171 to
.sat_addr
.s_net
= ddpe
.deh_dnet
;
172 to
.sat_addr
.s_node
= ddpe
.deh_dnode
;
173 to
.sat_port
= ddpe
.deh_dport
;
175 if ( to
.sat_addr
.s_net
== ATADDR_ANYNET
) {
177 * The TO address doesn't specify a net,
178 * So by definition it's for this net.
179 * Try find ifaddr info with the right phase,
180 * the right interface, and either to our node, a broadcast,
181 * or looped back (though that SHOULD be covered in the other
184 * XXX If we have multiple interfaces, then the first with
185 * this node number will match (which may NOT be what we want,
186 * but it's probably safe in 99.999% of cases.
188 for ( aa
= at_ifaddr
; aa
; aa
= aa
->aa_next
) {
189 if ( phase
== 1 && ( aa
->aa_flags
& AFA_PHASE2
)) {
192 if ( phase
== 2 && ( aa
->aa_flags
& AFA_PHASE2
) == 0 ) {
195 if ( (aa
->aa_ifp
== ifp
)
196 && ( (to
.sat_addr
.s_node
== AA_SAT( aa
)->sat_addr
.s_node
)
197 || (to
.sat_addr
.s_node
== ATADDR_BCAST
)
198 || (ifp
->if_flags
& IFF_LOOPBACK
))) {
204 * A destination network was given. We just try to find
205 * which ifaddr info matches it.
207 for ( aa
= at_ifaddr
; aa
; aa
= aa
->aa_next
) {
209 * This is a kludge. Accept packets that are
210 * for any router on a local netrange.
212 if ( to
.sat_addr
.s_net
== aa
->aa_firstnet
&&
213 to
.sat_addr
.s_node
== 0 ) {
217 * Don't use ifaddr info for which we are totally outside the
218 * netrange, and it's not a startup packet.
219 * Startup packets are always implicitly allowed on to
222 if ((( ntohs( to
.sat_addr
.s_net
) < ntohs( aa
->aa_firstnet
))
223 || (ntohs( to
.sat_addr
.s_net
) > ntohs( aa
->aa_lastnet
)))
224 && (( ntohs( to
.sat_addr
.s_net
) < 0xff00)
225 || (ntohs( to
.sat_addr
.s_net
) > 0xfffe ))) {
230 * Don't record a match either if we just don't have a match
231 * in the node address. This can have if the interface
232 * is in promiscuous mode for example.
234 if (( to
.sat_addr
.s_node
!= AA_SAT( aa
)->sat_addr
.s_node
)
235 && (to
.sat_addr
.s_node
!= ATADDR_BCAST
) ) {
244 * Adjust the length, removing any padding that may have been added
245 * at a link layer. We do this before we attempt to forward a packet,
246 * possibly on a different media.
248 mlen
= m
->m_pkthdr
.len
;
250 ddpstat
.ddps_toosmall
++;
255 m_adj( m
, dlen
- mlen
);
259 * If it aint for a net on any of our interfaces,
260 * or it IS for a net on a different interface than it came in on,
261 * (and it is not looped back) then consider if we should forward it.
262 * As we are not really a router this is a bit cheeky, but it may be
266 || ( (to
.sat_addr
.s_node
== ATADDR_BCAST
)
267 && (aa
->aa_ifp
!= ifp
)
268 && (( ifp
->if_flags
& IFF_LOOPBACK
) == 0 ))) {
270 * If we've explicitly disabled it, don't route anything
272 if ( ddp_forward
== 0 ) {
277 * If the cached forwarding route is still valid, use it.
280 && ( satosat(&forwro
.ro_dst
)->sat_addr
.s_net
!= to
.sat_addr
.s_net
281 || satosat(&forwro
.ro_dst
)->sat_addr
.s_node
!= to
.sat_addr
.s_node
)) {
282 RTFREE( forwro
.ro_rt
);
283 forwro
.ro_rt
= (struct rtentry
*)0;
287 * If we don't have a cached one (any more) or it's useless,
288 * Then get a new route.
289 * XXX this could cause a 'route leak'. check this!
291 if ( forwro
.ro_rt
== (struct rtentry
*)0
292 || forwro
.ro_rt
->rt_ifp
== (struct ifnet
*)0 ) {
293 forwro
.ro_dst
.sa_len
= sizeof( struct sockaddr_at
);
294 forwro
.ro_dst
.sa_family
= AF_APPLETALK
;
295 satosat(&forwro
.ro_dst
)->sat_addr
.s_net
= to
.sat_addr
.s_net
;
296 satosat(&forwro
.ro_dst
)->sat_addr
.s_node
= to
.sat_addr
.s_node
;
301 * If it's not going to get there on this hop, and it's
302 * already done too many hops, then throw it away.
304 if ( (to
.sat_addr
.s_net
!= satosat( &forwro
.ro_dst
)->sat_addr
.s_net
)
305 && (ddpe
.deh_hops
== DDP_MAXHOPS
) ) {
311 * A ddp router might use the same interface
312 * to forward the packet, which this would not effect.
313 * Don't allow packets to cross from one interface to another however.
316 && ( (forwro
.ro_rt
== NULL
)
317 || (forwro
.ro_rt
->rt_ifp
!= ifp
))) {
324 * If it was a short header then it would have not gotten here,
325 * so we can assume there is room to drop the header in.
326 * XXX what about promiscuous mode, etc...
329 ddpe
.deh_bytes
= htonl( ddpe
.deh_bytes
);
330 bcopy( (caddr_t
)&ddpe
, (caddr_t
)deh
, sizeof( u_short
)); /* XXX deh? */
331 if ( ddp_route( m
, &forwro
)) {
332 ddpstat
.ddps_cantforward
++;
334 ddpstat
.ddps_forward
++;
340 * It was for us, and we have an ifaddr to use with it.
342 from
.sat_len
= sizeof( struct sockaddr_at
);
343 from
.sat_family
= AF_APPLETALK
;
346 * We are no longer interested in the link layer.
350 m_adj( m
, sizeof( struct ddpshdr
));
352 if ( ddp_cksum
&& cksum
&& cksum
!= at_cksum( m
, sizeof( int ))) {
353 ddpstat
.ddps_badsum
++;
357 m_adj( m
, sizeof( struct ddpehdr
));
361 * Search for ddp protocol control blocks that match these
364 if (( ddp
= ddp_search( &from
, &to
, aa
)) == NULL
) {
370 * If we found one, deliver th epacket to the socket
372 if (ssb_appendaddr( &ddp
->ddp_socket
->so_rcv
, (struct sockaddr
*)&from
,
373 m
, (struct mbuf
*)0 ) == 0 ) {
375 * If the socket is full (or similar error) dump the packet.
377 ddpstat
.ddps_nosockspace
++;
382 * And wake up whatever might be waiting for it
384 sorwakeup( ddp
->ddp_socket
);
388 /* As if we haven't got enough of this sort of think floating
389 around the kernel :) */
394 char hexdig
[] = "0123456789ABCDEF";
397 bprint(char *data
, int len
)
399 char xout
[ BPXLEN
], aout
[ BPALEN
];
402 bzero( xout
, BPXLEN
);
403 bzero( aout
, BPALEN
);
408 kprintf( "%s\t%s\n", xout
, aout
);
410 kprintf( "%s\n", "(end)" );
414 xout
[ (i
*3) ] = hexdig
[ ( *data
& 0xf0 ) >> 4 ];
415 xout
[ (i
*3) + 1 ] = hexdig
[ *data
& 0x0f ];
417 if ( (u_char
)*data
< 0x7f && (u_char
)*data
> 0x20 ) {
423 xout
[ (i
*3) + 2 ] = ' ';
429 if ( i
> BPALEN
- 2 ) {
430 kprintf( "%s\t%s\n", xout
, aout
);
431 bzero( xout
, BPXLEN
);
432 bzero( aout
, BPALEN
);
440 m_printm(struct mbuf
*m
)
442 for (; m
; m
= m
->m_next
) {
443 bprint( mtod( m
, char * ), m
->m_len
);