* Receive data from session hook and do something with it. */
| 1409 | * Receive data from session hook and do something with it. |
| 1410 | */ |
| 1411 | static int |
| 1412 | ng_pppoe_rcvdata(hook_p hook, item_p item) |
| 1413 | { |
| 1414 | node_p node = NG_HOOK_NODE(hook); |
| 1415 | const priv_p privp = NG_NODE_PRIVATE(node); |
| 1416 | sessp sp = NG_HOOK_PRIVATE(hook); |
| 1417 | struct pppoe_full_hdr *wh; |
| 1418 | struct mbuf *m; |
| 1419 | int error; |
| 1420 | |
| 1421 | CTR6(KTR_NET, "%20s: node [%x] (%p) received %p on \"%s\" (%p)", |
| 1422 | __func__, node->nd_ID, node, item, hook->hk_name, hook); |
| 1423 | |
| 1424 | NGI_GET_M(item, m); |
| 1425 | switch (sp->state) { |
| 1426 | case PPPOE_NEWCONNECTED: |
| 1427 | case PPPOE_CONNECTED: { |
| 1428 | /* |
| 1429 | * Remove PPP address and control fields, if any. |
| 1430 | * For example, ng_ppp(4) always sends LCP packets |
| 1431 | * with address and control fields as required by |
| 1432 | * generic PPP. PPPoE is an exception to the rule. |
| 1433 | */ |
| 1434 | if (m->m_pkthdr.len >= 2) { |
| 1435 | if (m->m_len < 2 && !(m = m_pullup(m, 2))) |
| 1436 | LEAVE(ENOBUFS); |
| 1437 | if (mtod(m, u_char *)[0] == 0xff && |
| 1438 | mtod(m, u_char *)[1] == 0x03) |
| 1439 | m_adj(m, 2); |
| 1440 | } |
| 1441 | /* |
| 1442 | * Bang in a pre-made header, and set the length up |
| 1443 | * to be correct. Then send it to the ethernet driver. |
| 1444 | */ |
| 1445 | M_PREPEND(m, sizeof(*wh), M_NOWAIT); |
| 1446 | if (m == NULL) |
| 1447 | LEAVE(ENOBUFS); |
| 1448 | |
| 1449 | wh = mtod(m, struct pppoe_full_hdr *); |
| 1450 | bcopy(&sp->pkt_hdr, wh, sizeof(*wh)); |
| 1451 | wh->ph.length = htons(m->m_pkthdr.len - sizeof(*wh)); |
| 1452 | NG_FWD_NEW_DATA(error, item, privp->ethernet_hook, m); |
| 1453 | privp->packets_out++; |
| 1454 | break; |
| 1455 | } |
| 1456 | case PPPOE_PRIMED: { |
| 1457 | struct { |
| 1458 | struct pppoe_tag hdr; |
| 1459 | union uniq data; |
| 1460 | } __packed uniqtag; |
| 1461 | const struct pppoe_tag *tag; |
| 1462 | struct mbuf *m0; |
| 1463 | const struct pppoe_hdr *ph; |
| 1464 | negp neg = sp->neg; |
| 1465 | uint16_t session; |
| 1466 | uint16_t length; |
| 1467 | uint8_t code; |
| 1468 |
nothing calls this directly
no test coverage detected