* Receive data */
| 337 | * Receive data |
| 338 | */ |
| 339 | static int |
| 340 | cisco_rcvdata(hook_p hook, item_p item) |
| 341 | { |
| 342 | const sc_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); |
| 343 | struct protoent *pep; |
| 344 | struct cisco_header *h; |
| 345 | struct mbuf *m; |
| 346 | int error = 0; |
| 347 | |
| 348 | if ((pep = NG_HOOK_PRIVATE(hook)) == NULL) |
| 349 | goto out; |
| 350 | |
| 351 | /* If it came from our downlink, deal with it separately */ |
| 352 | if (pep->af == 0xffff) |
| 353 | return (cisco_input(sc, item)); |
| 354 | |
| 355 | /* OK so it came from a protocol, heading out. Prepend general data |
| 356 | packet header. For now, IP,IPX only */ |
| 357 | NGI_GET_M(item, m); |
| 358 | M_PREPEND(m, CISCO_HEADER_LEN, M_NOWAIT); |
| 359 | if (!m) { |
| 360 | error = ENOBUFS; |
| 361 | goto out; |
| 362 | } |
| 363 | NGI_M(item) = m; |
| 364 | h = mtod(m, struct cisco_header *); |
| 365 | h->address = CISCO_UNICAST; |
| 366 | h->control = 0; |
| 367 | |
| 368 | switch (pep->af) { |
| 369 | case AF_INET: /* Internet Protocol */ |
| 370 | h->protocol = htons(ETHERTYPE_IP); |
| 371 | break; |
| 372 | case AF_INET6: |
| 373 | h->protocol = htons(ETHERTYPE_IPV6); |
| 374 | break; |
| 375 | case AF_APPLETALK: /* AppleTalk Protocol */ |
| 376 | h->protocol = htons(ETHERTYPE_AT); |
| 377 | break; |
| 378 | case AF_IPX: /* Novell IPX Protocol */ |
| 379 | h->protocol = htons(ETHERTYPE_IPX); |
| 380 | break; |
| 381 | default: |
| 382 | error = EAFNOSUPPORT; |
| 383 | goto out; |
| 384 | } |
| 385 | |
| 386 | /* Send it */ |
| 387 | NG_FWD_NEW_DATA(error, item, sc->downstream.hook, m); |
| 388 | return (error); |
| 389 | |
| 390 | out: |
| 391 | NG_FREE_ITEM(item); |
| 392 | return (error); |
| 393 | } |
| 394 | |
| 395 | /* |
| 396 | * Shutdown node |
nothing calls this directly
no test coverage detected