ddp_input.c revision 89416
1/* 2 * Copyright (c) 1990,1994 Regents of The University of Michigan. 3 * All Rights Reserved. See COPYRIGHT. 4 * 5 * $FreeBSD: head/sys/netatalk/ddp_input.c 89416 2002-01-16 11:26:50Z iedowse $ 6 */ 7 8#include <sys/param.h> 9#include <sys/systm.h> 10#include <sys/kernel.h> 11#include <net/netisr.h> 12#include <sys/mbuf.h> 13#include <sys/socket.h> 14#include <sys/socketvar.h> 15#include <net/if.h> 16#include <net/route.h> 17#include <net/intrq.h> 18 19#include <netatalk/at.h> 20#include <netatalk/at_var.h> 21#include <netatalk/ddp.h> 22#include <netatalk/ddp_var.h> 23#include <netatalk/at_extern.h> 24 25static volatile int ddp_forward = 1; 26static volatile int ddp_firewall = 0; 27static struct ddpstat ddpstat; 28static struct route forwro; 29 30static void ddp_input(struct mbuf *, struct ifnet *, struct elaphdr *, int); 31 32/* 33 * Could probably merge these two code segments a little better... 34 */ 35static void 36atintr( void ) 37{ 38 struct elaphdr *elhp, elh; 39 struct ifnet *ifp; 40 struct mbuf *m; 41 int s; 42 43 /* 44 * First pull off all the phase 2 packets. 45 */ 46 for (;;) { 47 s = splimp(); 48 49 IF_DEQUEUE( &atintrq2, m ); 50 51 splx( s ); 52 53 if ( m == 0 ) { /* no more queued packets */ 54 break; 55 } 56 57 ifp = m->m_pkthdr.rcvif; 58 ddp_input( m, ifp, (struct elaphdr *)NULL, 2 ); 59 } 60 61 /* 62 * Then pull off all the phase 1 packets. 63 */ 64 for (;;) { 65 s = splimp(); 66 67 IF_DEQUEUE( &atintrq1, m ); 68 69 splx( s ); 70 71 if ( m == 0 ) { /* no more queued packets */ 72 break; 73 } 74 75 ifp = m->m_pkthdr.rcvif; 76 77 if ( m->m_len < SZ_ELAPHDR && 78 (( m = m_pullup( m, SZ_ELAPHDR )) == 0 )) { 79 ddpstat.ddps_tooshort++; 80 continue; 81 } 82 83 /* 84 * this seems a little dubios, but I don't know phase 1 so leave it. 85 */ 86 elhp = mtod( m, struct elaphdr *); 87 m_adj( m, SZ_ELAPHDR ); 88 89 if ( elhp->el_type == ELAP_DDPEXTEND ) { 90 ddp_input( m, ifp, (struct elaphdr *)NULL, 1 ); 91 } else { 92 bcopy((caddr_t)elhp, (caddr_t)&elh, SZ_ELAPHDR ); 93 ddp_input( m, ifp, &elh, 1 ); 94 } 95 } 96 return; 97} 98 99static void 100netisr_atalk_setup(void *dummy __unused) 101{ 102 103 register_netisr(NETISR_ATALK, atintr); 104} 105SYSINIT(atalk_setup, SI_SUB_CPU, SI_ORDER_ANY, netisr_atalk_setup, NULL); 106 107static void 108ddp_input( m, ifp, elh, phase ) 109 struct mbuf *m; 110 struct ifnet *ifp; 111 struct elaphdr *elh; 112 int phase; 113{ 114 struct sockaddr_at from, to; 115 struct ddpshdr *dsh, ddps; 116 struct at_ifaddr *aa; 117 struct ddpehdr *deh = NULL, ddpe; 118 struct ddpcb *ddp; 119 int dlen, mlen; 120 u_short cksum = 0; 121 122 bzero( (caddr_t)&from, sizeof( struct sockaddr_at )); 123 bzero( (caddr_t)&to, sizeof( struct sockaddr_at )); 124 if ( elh ) { 125 /* 126 * Extract the information in the short header. 127 * netowrk information is defaulted to ATADDR_ANYNET 128 * and node information comes from the elh info. 129 * We must be phase 1. 130 */ 131 ddpstat.ddps_short++; 132 133 if ( m->m_len < sizeof( struct ddpshdr ) && 134 (( m = m_pullup( m, sizeof( struct ddpshdr ))) == 0 )) { 135 ddpstat.ddps_tooshort++; 136 return; 137 } 138 139 dsh = mtod( m, struct ddpshdr *); 140 bcopy( (caddr_t)dsh, (caddr_t)&ddps, sizeof( struct ddpshdr )); 141 ddps.dsh_bytes = ntohl( ddps.dsh_bytes ); 142 dlen = ddps.dsh_len; 143 144 to.sat_addr.s_net = ATADDR_ANYNET; 145 to.sat_addr.s_node = elh->el_dnode; 146 to.sat_port = ddps.dsh_dport; 147 from.sat_addr.s_net = ATADDR_ANYNET; 148 from.sat_addr.s_node = elh->el_snode; 149 from.sat_port = ddps.dsh_sport; 150 151 /* 152 * Make sure that we point to the phase1 ifaddr info 153 * and that it's valid for this packet. 154 */ 155 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 156 if ( (aa->aa_ifp == ifp) 157 && ( (aa->aa_flags & AFA_PHASE2) == 0) 158 && ( (to.sat_addr.s_node == AA_SAT( aa )->sat_addr.s_node) 159 || (to.sat_addr.s_node == ATADDR_BCAST))) { 160 break; 161 } 162 } 163 /* 164 * maybe we got a broadcast not meant for us.. ditch it. 165 */ 166 if ( aa == NULL ) { 167 m_freem( m ); 168 return; 169 } 170 } else { 171 /* 172 * There was no 'elh' passed on. This could still be 173 * either phase1 or phase2. 174 * We have a long header, but we may be running on a phase 1 net. 175 * Extract out all the info regarding this packet's src & dst. 176 */ 177 ddpstat.ddps_long++; 178 179 if ( m->m_len < sizeof( struct ddpehdr ) && 180 (( m = m_pullup( m, sizeof( struct ddpehdr ))) == 0 )) { 181 ddpstat.ddps_tooshort++; 182 return; 183 } 184 185 deh = mtod( m, struct ddpehdr *); 186 bcopy( (caddr_t)deh, (caddr_t)&ddpe, sizeof( struct ddpehdr )); 187 ddpe.deh_bytes = ntohl( ddpe.deh_bytes ); 188 dlen = ddpe.deh_len; 189 190 if (( cksum = ddpe.deh_sum ) == 0 ) { 191 ddpstat.ddps_nosum++; 192 } 193 194 from.sat_addr.s_net = ddpe.deh_snet; 195 from.sat_addr.s_node = ddpe.deh_snode; 196 from.sat_port = ddpe.deh_sport; 197 to.sat_addr.s_net = ddpe.deh_dnet; 198 to.sat_addr.s_node = ddpe.deh_dnode; 199 to.sat_port = ddpe.deh_dport; 200 201 if ( to.sat_addr.s_net == ATADDR_ANYNET ) { 202 /* 203 * The TO address doesn't specify a net, 204 * So by definition it's for this net. 205 * Try find ifaddr info with the right phase, 206 * the right interface, and either to our node, a broadcast, 207 * or looped back (though that SHOULD be covered in the other 208 * cases). 209 * 210 * XXX If we have multiple interfaces, then the first with 211 * this node number will match (which may NOT be what we want, 212 * but it's probably safe in 99.999% of cases. 213 */ 214 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 215 if ( phase == 1 && ( aa->aa_flags & AFA_PHASE2 )) { 216 continue; 217 } 218 if ( phase == 2 && ( aa->aa_flags & AFA_PHASE2 ) == 0 ) { 219 continue; 220 } 221 if ( (aa->aa_ifp == ifp) 222 && ( (to.sat_addr.s_node == AA_SAT( aa )->sat_addr.s_node) 223 || (to.sat_addr.s_node == ATADDR_BCAST) 224 || (ifp->if_flags & IFF_LOOPBACK))) { 225 break; 226 } 227 } 228 } else { 229 /* 230 * A destination network was given. We just try to find 231 * which ifaddr info matches it. 232 */ 233 for ( aa = at_ifaddr; aa; aa = aa->aa_next ) { 234 /* 235 * This is a kludge. Accept packets that are 236 * for any router on a local netrange. 237 */ 238 if ( to.sat_addr.s_net == aa->aa_firstnet && 239 to.sat_addr.s_node == 0 ) { 240 break; 241 } 242 /* 243 * Don't use ifaddr info for which we are totally outside the 244 * netrange, and it's not a startup packet. 245 * Startup packets are always implicitly allowed on to 246 * the next test. 247 */ 248 if ((( ntohs( to.sat_addr.s_net ) < ntohs( aa->aa_firstnet )) 249 || (ntohs( to.sat_addr.s_net ) > ntohs( aa->aa_lastnet ))) 250 && (( ntohs( to.sat_addr.s_net ) < 0xff00) 251 || (ntohs( to.sat_addr.s_net ) > 0xfffe ))) { 252 continue; 253 } 254 255 /* 256 * Don't record a match either if we just don't have a match 257 * in the node address. This can have if the interface 258 * is in promiscuous mode for example. 259 */ 260 if (( to.sat_addr.s_node != AA_SAT( aa )->sat_addr.s_node) 261 && (to.sat_addr.s_node != ATADDR_BCAST) ) { 262 continue; 263 } 264 break; 265 } 266 } 267 } 268 269 /* 270 * Adjust the length, removing any padding that may have been added 271 * at a link layer. We do this before we attempt to forward a packet, 272 * possibly on a different media. 273 */ 274 mlen = m->m_pkthdr.len; 275 if ( mlen < dlen ) { 276 ddpstat.ddps_toosmall++; 277 m_freem( m ); 278 return; 279 } 280 if ( mlen > dlen ) { 281 m_adj( m, dlen - mlen ); 282 } 283 284 /* 285 * If it aint for a net on any of our interfaces, 286 * or it IS for a net on a different interface than it came in on, 287 * (and it is not looped back) then consider if we should forward it. 288 * As we are not really a router this is a bit cheeky, but it may be 289 * useful some day. 290 */ 291 if ( (aa == NULL) 292 || ( (to.sat_addr.s_node == ATADDR_BCAST) 293 && (aa->aa_ifp != ifp) 294 && (( ifp->if_flags & IFF_LOOPBACK ) == 0 ))) { 295 /* 296 * If we've explicitly disabled it, don't route anything 297 */ 298 if ( ddp_forward == 0 ) { 299 m_freem( m ); 300 return; 301 } 302 /* 303 * If the cached forwarding route is still valid, use it. 304 */ 305 if ( forwro.ro_rt 306 && ( satosat(&forwro.ro_dst)->sat_addr.s_net != to.sat_addr.s_net 307 || satosat(&forwro.ro_dst)->sat_addr.s_node != to.sat_addr.s_node )) { 308 RTFREE( forwro.ro_rt ); 309 forwro.ro_rt = (struct rtentry *)0; 310 } 311 312 /* 313 * If we don't have a cached one (any more) or it's useless, 314 * Then get a new route. 315 * XXX this could cause a 'route leak'. check this! 316 */ 317 if ( forwro.ro_rt == (struct rtentry *)0 318 || forwro.ro_rt->rt_ifp == (struct ifnet *)0 ) { 319 forwro.ro_dst.sa_len = sizeof( struct sockaddr_at ); 320 forwro.ro_dst.sa_family = AF_APPLETALK; 321 satosat(&forwro.ro_dst)->sat_addr.s_net = to.sat_addr.s_net; 322 satosat(&forwro.ro_dst)->sat_addr.s_node = to.sat_addr.s_node; 323 rtalloc(&forwro); 324 } 325 326 /* 327 * If it's not going to get there on this hop, and it's 328 * already done too many hops, then throw it away. 329 */ 330 if ( (to.sat_addr.s_net != satosat( &forwro.ro_dst )->sat_addr.s_net) 331 && (ddpe.deh_hops == DDP_MAXHOPS) ) { 332 m_freem( m ); 333 return; 334 } 335 336 /* 337 * A ddp router might use the same interface 338 * to forward the packet, which this would not effect. 339 * Don't allow packets to cross from one interface to another however. 340 */ 341 if ( ddp_firewall 342 && ( (forwro.ro_rt == NULL) 343 || (forwro.ro_rt->rt_ifp != ifp))) { 344 m_freem( m ); 345 return; 346 } 347 348 /* 349 * Adjust the header. 350 * If it was a short header then it would have not gotten here, 351 * so we can assume there is room to drop the header in. 352 * XXX what about promiscuous mode, etc... 353 */ 354 ddpe.deh_hops++; 355 ddpe.deh_bytes = htonl( ddpe.deh_bytes ); 356 bcopy( (caddr_t)&ddpe, (caddr_t)deh, sizeof( u_short )); /* XXX deh? */ 357 if ( ddp_route( m, &forwro )) { 358 ddpstat.ddps_cantforward++; 359 } else { 360 ddpstat.ddps_forward++; 361 } 362 return; 363 } 364 365 /* 366 * It was for us, and we have an ifaddr to use with it. 367 */ 368 from.sat_len = sizeof( struct sockaddr_at ); 369 from.sat_family = AF_APPLETALK; 370 371 /* 372 * We are no longer interested in the link layer. 373 * so cut it off. 374 */ 375 if ( elh ) { 376 m_adj( m, sizeof( struct ddpshdr )); 377 } else { 378 if ( ddp_cksum && cksum && cksum != at_cksum( m, sizeof( int ))) { 379 ddpstat.ddps_badsum++; 380 m_freem( m ); 381 return; 382 } 383 m_adj( m, sizeof( struct ddpehdr )); 384 } 385 386 /* 387 * Search for ddp protocol control blocks that match these 388 * addresses. 389 */ 390 if (( ddp = ddp_search( &from, &to, aa )) == NULL ) { 391 m_freem( m ); 392 return; 393 } 394 395 /* 396 * If we found one, deliver th epacket to the socket 397 */ 398 if ( sbappendaddr( &ddp->ddp_socket->so_rcv, (struct sockaddr *)&from, 399 m, (struct mbuf *)0 ) == 0 ) { 400 /* 401 * If the socket is full (or similar error) dump the packet. 402 */ 403 ddpstat.ddps_nosockspace++; 404 m_freem( m ); 405 return; 406 } 407 /* 408 * And wake up whatever might be waiting for it 409 */ 410 sorwakeup( ddp->ddp_socket ); 411} 412 413#if 0 414/* As if we haven't got enough of this sort of think floating 415around the kernel :) */ 416 417#define BPXLEN 48 418#define BPALEN 16 419#include <ctype.h> 420char hexdig[] = "0123456789ABCDEF"; 421 422static void 423bprint( char *data, int len ) 424{ 425 char xout[ BPXLEN ], aout[ BPALEN ]; 426 int i = 0; 427 428 bzero( xout, BPXLEN ); 429 bzero( aout, BPALEN ); 430 431 for ( ;; ) { 432 if ( len < 1 ) { 433 if ( i != 0 ) { 434 printf( "%s\t%s\n", xout, aout ); 435 } 436 printf( "%s\n", "(end)" ); 437 break; 438 } 439 440 xout[ (i*3) ] = hexdig[ ( *data & 0xf0 ) >> 4 ]; 441 xout[ (i*3) + 1 ] = hexdig[ *data & 0x0f ]; 442 443 if ( (u_char)*data < 0x7f && (u_char)*data > 0x20 ) { 444 aout[ i ] = *data; 445 } else { 446 aout[ i ] = '.'; 447 } 448 449 xout[ (i*3) + 2 ] = ' '; 450 451 i++; 452 len--; 453 data++; 454 455 if ( i > BPALEN - 2 ) { 456 printf( "%s\t%s\n", xout, aout ); 457 bzero( xout, BPXLEN ); 458 bzero( aout, BPALEN ); 459 i = 0; 460 continue; 461 } 462 } 463} 464 465static void 466m_printm( struct mbuf *m ) 467{ 468 for (; m; m = m->m_next ) { 469 bprint( mtod( m, char * ), m->m_len ); 470 } 471} 472#endif 473