ddp_input.c revision 127289
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 127289 2004-03-22 03:48:31Z rwatson $ 6 */ 7 8#include "opt_mac.h" 9 10#include <sys/param.h> 11#include <sys/kernel.h> 12#include <sys/lock.h> 13#include <sys/mac.h> 14#include <sys/mbuf.h> 15#include <sys/signalvar.h> 16#include <sys/socket.h> 17#include <sys/socketvar.h> 18#include <sys/sx.h> 19#include <sys/systm.h> 20#include <net/if.h> 21#include <net/route.h> 22 23#include <netatalk/at.h> 24#include <netatalk/at_var.h> 25#include <netatalk/ddp.h> 26#include <netatalk/ddp_var.h> 27#include <netatalk/at_extern.h> 28 29static volatile int ddp_forward = 1; 30static volatile int ddp_firewall = 0; 31static struct ddpstat ddpstat; 32static struct route forwro; 33 34static void ddp_input(struct mbuf *, struct ifnet *, struct elaphdr *, int); 35 36/* 37 * Could probably merge these two code segments a little better... 38 */ 39void 40at2intr(struct mbuf *m) 41{ 42 GIANT_REQUIRED; 43 44 /* 45 * Phase 2 packet handling 46 */ 47 ddp_input(m, m->m_pkthdr.rcvif, NULL, 2); 48 return; 49} 50 51void 52at1intr(struct mbuf *m) 53{ 54 struct elaphdr *elhp, elh; 55 56 /* 57 * Phase 1 packet handling 58 */ 59 if (m->m_len < SZ_ELAPHDR && ((m = m_pullup(m, SZ_ELAPHDR)) == NULL)) { 60 ddpstat.ddps_tooshort++; 61 return; 62 } 63 64 /* 65 * This seems a little dubious, but I don't know phase 1 so leave it. 66 */ 67 elhp = mtod(m, struct elaphdr *); 68 m_adj(m, SZ_ELAPHDR); 69 70 GIANT_REQUIRED; 71 72 if (elhp->el_type == ELAP_DDPEXTEND) { 73 ddp_input(m, m->m_pkthdr.rcvif, NULL, 1); 74 } else { 75 bcopy((caddr_t)elhp, (caddr_t)&elh, SZ_ELAPHDR); 76 ddp_input(m, m->m_pkthdr.rcvif, &elh, 1); 77 } 78 return; 79} 80 81static void 82ddp_input(m, ifp, elh, phase) 83 struct mbuf *m; 84 struct ifnet *ifp; 85 struct elaphdr *elh; 86 int phase; 87{ 88 struct sockaddr_at from, to; 89 struct ddpshdr *dsh, ddps; 90 struct at_ifaddr *aa; 91 struct ddpehdr *deh = NULL, ddpe; 92 struct ddpcb *ddp; 93 int dlen, mlen; 94 u_short cksum = 0; 95 96 bzero((caddr_t)&from, sizeof(struct sockaddr_at)); 97 bzero((caddr_t)&to, sizeof(struct sockaddr_at)); 98 if (elh) { 99 /* 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. 104 */ 105 ddpstat.ddps_short++; 106 107 if (m->m_len < sizeof(struct ddpshdr) && 108 ((m = m_pullup(m, sizeof(struct ddpshdr))) == NULL)) { 109 ddpstat.ddps_tooshort++; 110 return; 111 } 112 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); 116 dlen = ddps.dsh_len; 117 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; 124 125 /* 126 * Make sure that we point to the phase1 ifaddr info 127 * and that it's valid for this packet. 128 */ 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))) { 134 break; 135 } 136 } 137 /* 138 * maybe we got a broadcast not meant for us.. ditch it. 139 */ 140 if (aa == NULL) { 141 m_freem(m); 142 return; 143 } 144 } else { 145 /* 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. 150 */ 151 ddpstat.ddps_long++; 152 153 if (m->m_len < sizeof(struct ddpehdr) && 154 ((m = m_pullup(m, sizeof(struct ddpehdr))) == NULL)) { 155 ddpstat.ddps_tooshort++; 156 return; 157 } 158 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); 162 dlen = ddpe.deh_len; 163 164 if ((cksum = ddpe.deh_sum) == 0) { 165 ddpstat.ddps_nosum++; 166 } 167 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; 174 175 if (to.sat_addr.s_net == ATADDR_ANYNET) { 176 /* 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 182 * cases). 183 * 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. 187 */ 188 for (aa = at_ifaddr; aa; aa = aa->aa_next) { 189 if (phase == 1 && (aa->aa_flags & AFA_PHASE2)) { 190 continue; 191 } 192 if (phase == 2 && (aa->aa_flags & AFA_PHASE2) == 0) { 193 continue; 194 } 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))) { 199 break; 200 } 201 } 202 } else { 203 /* 204 * A destination network was given. We just try to find 205 * which ifaddr info matches it. 206 */ 207 for (aa = at_ifaddr; aa; aa = aa->aa_next) { 208 /* 209 * This is a kludge. Accept packets that are 210 * for any router on a local netrange. 211 */ 212 if (to.sat_addr.s_net == aa->aa_firstnet && 213 to.sat_addr.s_node == 0) { 214 break; 215 } 216 /* 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 220 * the next test. 221 */ 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))) { 226 continue; 227 } 228 229 /* 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. 233 */ 234 if ((to.sat_addr.s_node != AA_SAT(aa)->sat_addr.s_node) 235 && (to.sat_addr.s_node != ATADDR_BCAST)) { 236 continue; 237 } 238 break; 239 } 240 } 241 } 242 243 /* 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. 247 */ 248 mlen = m->m_pkthdr.len; 249 if (mlen < dlen) { 250 ddpstat.ddps_toosmall++; 251 m_freem(m); 252 return; 253 } 254 if (mlen > dlen) { 255 m_adj(m, dlen - mlen); 256 } 257 258 /* 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 263 * useful some day. 264 */ 265 if ((aa == NULL) 266 || ((to.sat_addr.s_node == ATADDR_BCAST) 267 && (aa->aa_ifp != ifp) 268 && ((ifp->if_flags & IFF_LOOPBACK) == 0))) { 269 /* 270 * If we've explicitly disabled it, don't route anything 271 */ 272 if (ddp_forward == 0) { 273 m_freem(m); 274 return; 275 } 276 /* 277 * If the cached forwarding route is still valid, use it. 278 */ 279 if (forwro.ro_rt 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 = NULL; 284 } 285 286 /* 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! 290 */ 291 if (forwro.ro_rt == NULL || forwro.ro_rt->rt_ifp == NULL) { 292 forwro.ro_dst.sa_len = sizeof(struct sockaddr_at); 293 forwro.ro_dst.sa_family = AF_APPLETALK; 294 satosat(&forwro.ro_dst)->sat_addr.s_net = to.sat_addr.s_net; 295 satosat(&forwro.ro_dst)->sat_addr.s_node = to.sat_addr.s_node; 296 rtalloc(&forwro); 297 } 298 299 /* 300 * If it's not going to get there on this hop, and it's 301 * already done too many hops, then throw it away. 302 */ 303 if ((to.sat_addr.s_net != satosat(&forwro.ro_dst)->sat_addr.s_net) 304 && (ddpe.deh_hops == DDP_MAXHOPS)) { 305 m_freem(m); 306 return; 307 } 308 309 /* 310 * A ddp router might use the same interface 311 * to forward the packet, which this would not effect. 312 * Don't allow packets to cross from one interface to another however. 313 */ 314 if (ddp_firewall 315 && ((forwro.ro_rt == NULL) 316 || (forwro.ro_rt->rt_ifp != ifp))) { 317 m_freem(m); 318 return; 319 } 320 321 /* 322 * Adjust the header. 323 * If it was a short header then it would have not gotten here, 324 * so we can assume there is room to drop the header in. 325 * XXX what about promiscuous mode, etc... 326 */ 327 ddpe.deh_hops++; 328 ddpe.deh_bytes = htonl(ddpe.deh_bytes); 329 bcopy((caddr_t)&ddpe, (caddr_t)deh, sizeof(u_short)); /* XXX deh? */ 330 if (ddp_route(m, &forwro)) { 331 ddpstat.ddps_cantforward++; 332 } else { 333 ddpstat.ddps_forward++; 334 } 335 return; 336 } 337 338 /* 339 * It was for us, and we have an ifaddr to use with it. 340 */ 341 from.sat_len = sizeof(struct sockaddr_at); 342 from.sat_family = AF_APPLETALK; 343 344 /* 345 * We are no longer interested in the link layer. 346 * so cut it off. 347 */ 348 if (elh) { 349 m_adj(m, sizeof(struct ddpshdr)); 350 } else { 351 if (ddp_cksum && cksum && cksum != at_cksum(m, sizeof(int))) { 352 ddpstat.ddps_badsum++; 353 m_freem(m); 354 return; 355 } 356 m_adj(m, sizeof(struct ddpehdr)); 357 } 358 359 /* 360 * Search for ddp protocol control blocks that match these 361 * addresses. 362 */ 363 if ((ddp = ddp_search(&from, &to, aa)) == NULL) { 364 m_freem(m); 365 return; 366 } 367 368#ifdef MAC 369 if (mac_check_socket_deliver(ddp->ddp_socket, m) != 0) { 370 m_freem(m); 371 return; 372 } 373#endif 374 375 /* 376 * If we found one, deliver th epacket to the socket 377 */ 378 if (sbappendaddr(&ddp->ddp_socket->so_rcv, (struct sockaddr *)&from, 379 m, NULL) == 0) { 380 /* 381 * If the socket is full (or similar error) dump the packet. 382 */ 383 ddpstat.ddps_nosockspace++; 384 m_freem(m); 385 return; 386 } 387 /* 388 * And wake up whatever might be waiting for it 389 */ 390 sorwakeup(ddp->ddp_socket); 391} 392 393#if 0 394/* As if we haven't got enough of this sort of think floating 395around the kernel :) */ 396 397#define BPXLEN 48 398#define BPALEN 16 399#include <ctype.h> 400char hexdig[] = "0123456789ABCDEF"; 401 402static void 403bprint(char *data, int len) 404{ 405 char xout[ BPXLEN ], aout[ BPALEN ]; 406 int i = 0; 407 408 bzero(xout, BPXLEN); 409 bzero(aout, BPALEN); 410 411 for (;;) { 412 if (len < 1) { 413 if (i != 0) { 414 printf("%s\t%s\n", xout, aout); 415 } 416 printf("%s\n", "(end)"); 417 break; 418 } 419 420 xout[ (i*3) ] = hexdig[ (*data & 0xf0) >> 4 ]; 421 xout[ (i*3) + 1 ] = hexdig[ *data & 0x0f ]; 422 423 if ((u_char)*data < 0x7f && (u_char)*data > 0x20) { 424 aout[ i ] = *data; 425 } else { 426 aout[ i ] = '.'; 427 } 428 429 xout[ (i*3) + 2 ] = ' '; 430 431 i++; 432 len--; 433 data++; 434 435 if (i > BPALEN - 2) { 436 printf("%s\t%s\n", xout, aout); 437 bzero(xout, BPXLEN); 438 bzero(aout, BPALEN); 439 i = 0; 440 continue; 441 } 442 } 443} 444 445static void 446m_printm(struct mbuf *m) 447{ 448 for (; m; m = m->m_next) { 449 bprint(mtod(m, char *), m->m_len); 450 } 451} 452#endif 453