📄 pfildrv.c
字号:
if ((dl->dl_primitive == DL_UNITDATA_IND) && (dl->dl_group_address == 1)) { qpi->qpi_flags |= QF_GROUP; if (((*((u_char *)m->b_rptr) == 0x0) && ((*((u_char *)m->b_rptr + 2) == 0x45)))) off += 2; } } /* * We might have a 1st data block which is really M_PROTO, i.e. it is * only big enough for the link layer header */ while ((len = m->b_wptr - m->b_rptr) <= off) { off -= len; m = m->b_cont; if (m == NULL) { qif->qf_nodata++; return -4; /* not enough data for IP */ } } ip = (struct ip *)(m->b_rptr + off); len = m->b_wptr - m->b_rptr - off; mlen = msgdsize(m); sap = qif->qf_sap; if (mlen == 0) mlen = mt->b_wptr - mt->b_rptr; mlen -= off; /* * Ok, the IP header isn't on a 32bit aligned address so junk it. */ if (((u_int)ip & 0x3) || (len < sizeof(*ip)) || (sap == -1) || (m->b_datap->db_ref > 1)) { mblk_t *b; mblk_t *nm; mblk_t *nmt; mblk_t *previous_nm;fixalign: nmt = NULL; previous_nm = NULL; /* * Duplicate the message block descriptors up to (and * including if the offset is non-zero) the block where * IP begins. */ for (b = mt; b != m || off; b = b->b_cont) { nm = dupb(b); if (nm == NULL) { qif->qf_copyfail++; if (nmt) freemsg(nmt); return ENOBUFS; } nm->b_cont = NULL; if (nmt) linkb(previous_nm, nm); else nmt = nm; previous_nm = nm; /* * Set the length so the block only contains what * apperas before IP. */ if (b == m) { nm->b_wptr = nm->b_rptr + off; break; } } m->b_rptr += off; nm = msgpullup(m, -1); m->b_rptr -= pff; if (nm == NULL) qif->qf_copyfail++; if (nmt) freemsg(nmt); return -e; } if (nmt) linkb(previous_nm, nm); else nmt = nm; freemsg(mt); *mp = nmt; mt = nmt; m = nm; ip = (struct ip *)m->b_rptr; len = m->b_wptr - m->b_rptr; mlen = len; off = 0; } if (sap == ETHERTYPE_IP) { u_short tlen; hlen = sizeof(*ip); /* XXX - might not be aligned (from ppp?) */ ((char *)&tlen)[0] = ((char *)&ip->ip_len)[0]; ((char *)&tlen)[1] = ((char *)&ip->ip_len)[1]; plen = ntohs(tlen); ph = &pfh_inet4;#ifdef ETHERTYPE_IPV6 } else if (sap == ETHERTYPE_IPV6) { u_short tlen; hlen = sizeof(ip6_t); ip6 = (ip6_t *)ip; /* XXX - might not be aligned (from ppp?) */ ((char *)&tlen)[0] = ((char *)&ip6->ip6_plen)[0]; ((char *)&tlen)[1] = ((char *)&ip6->ip6_plen)[1]; plen = ntohs(tlen); if (plen == 0) return EMSGSIZE; /* Jumbo gram */ plen += sizeof(*ip6); ph = &pfh_inet6;#endif } else { hlen = 0; sap = -1; } if (((sap == ETHERTYPE_IP) && (ip->ip_v != IPVERSION)) || (sap == -1)) { qif->qf_notip++; return -5; } if (sap == ETHERTYPE_IP) iphlen = ip->ip_hl << 2; len = m->b_wptr - m->b_rptr - off; if ((iphlen < hlen) || (iphlen > plen) || (mlen < plen)) { if ((m->b_datap->db_ref > 1) && (pfil_delayed_copy == 0)) goto forced_copy; if (!pullupmsg(m, (int)iphlen + off)) { qif->qf_nodata++; return ENOBUFS; } ip = (ip_t *)(m->b_rptr + off); } /* * If we don't have enough data in the mblk or we haven't yet copied * enough (above), then copy some more. */ if ((iphlen > len)) { if (m->b_datap->db_ref > 1) goto forced_copy; if (!pullupmsg(m, (int)iphlen + off)) { qif->qf_nodata++; return -6; } ip = (struct ip *)ALIGN32(m->b_rptr + off); }#if !defined(__hppa) if (sap == ETHERTYPE_IP) { __ipoff = (u_short)ip->ip_off; ip->ip_len = plen; ip->ip_off = ntohs(__ipoff); }#endif if ((len > plen) && (off == 0)) m->b_wptr -= len - plen; qpi->qpi_m = m; qpi->qpi_off = off; qpi->qpi_data = ip; if (qif->qf_ipmp != NULL) qif = qif->qf_ipmp; READ_ENTER(&ph->ph_lock); pfh = pfil_hook_get(flags & PFIL_INOUT, ph); err = 0; PRINT(8,(CE_CONT, "pfil_hook_get(%x,%lx) = %lx\n", flags, ph, pfh)); for (pfh = pfil_hook_get(flags, ph); pfh; pfh = pfh->pfil_next) if (pfh->pfil_func) { err = (*pfh->pfil_func)(ip, iphlen, qif, out, qpi, mp); if (err || !*mp) break; ip = qpi->qpi_data; } RW_EXIT(&ph->ph_lock); /* * Functions called via pfil_func should only return values >= 0, so * convert any that are < 0 to be > 0 and preserve the absolute value. */ if (err < 0) err = -err; /* * Copy back the ip header data if it was changed, we haven't yet * freed the message and we aren't going to drop the packet. * BUT only do this if there were no changes to the buffer, else * we can't be sure that the ip pointer is still correct! */#if !defined(__hppa) if ((err == 0) && (*mp != NULL) && (sap == ETHERTYPE_IP)) { __iplen = (u_short)ip->ip_len; __ipoff = (u_short)ip->ip_off; ip->ip_len = htons(__iplen); ip->ip_off = htons(__ipoff); }#endif return err;}/************************************************************************/static int pfil_load (void *arg){ int result; result = pfil_install(); PRINT(3,(CE_CONT, "pfil_install() = %d\n", result)); if (result != 0) return ENXIO; result = pfil_nd_init(); PRINT(3,(CE_CONT, "pfil_nd_init() = %d\n", result)); if (result != 0) return ENXIO; if (qif_startup() == -1) return ENXIO; pfil_startup(); return 0;}static int pfil_unload(void *arg){ int retval; if (qif_head != NULL) return EBUSY; retval = str_uninstall(&pfil_str_info); if (retval == 0) { pfil_nd_fini(); qif_stop(); } return retval;}int pfil_install(void){ int retval; initlock(&pfil_rw, 0, 0, "pfil_rw"); pfil_str_info.inst_str_tab.st_rdinit = pfilmodinfo.st_rdinit; pfil_str_info.inst_str_tab.st_wrinit = pfilmodinfo.st_wrinit; pfil_str_info.inst_str_tab.st_muxrinit = NULL; pfil_str_info.inst_str_tab.st_muxwinit = NULL; retval = str_install(&pfil_str_info); return retval;}void miocnak(queue_t *q, mblk_t *m, int i, int err){ struct iocblk *iocp; iocp = (struct iocblk *)m->b_rptr; iocp->ioc_error = err; iocp->ioc_count = i; m->b_datap->db_type = M_IOCNAK; qreply(q, m);}void miocack(queue_t *q, mblk_t *m, int i, int err){ struct iocblk *iocp; iocp = (struct iocblk *)m->b_rptr; iocp->ioc_error = err; iocp->ioc_count = i; m->b_datap->db_type = M_IOCACK; qreply(q, m);}int miocpullup(mblk_t *m, size_t len){ if (m->b_cont == NULL) return 0; return pullupmsg(m->b_cont, len);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -