📄 pfildrv.c
字号:
sap = -1; } if (((sap == ETHERTYPE_IP) && (ip->ip_v != IPVERSION))#if SOLARIS2 >= 8 || ((sap == IP6_DL_SAP) && (((ip6->ip6_vfc) & 0xf0) != 0x60))#endif || sap == -1 ) { atomic_add_long(&qif->qf_notip, 1);#ifdef PFILDEBUG pfil_donotip(out, qif, q, m, mt, ip, off);#endif return EINVAL; } if (sap == ETHERTYPE_IP) iphlen = ip->ip_hl << 2;#if SOLARIS2 >= 8 else if (sap == IP6_DL_SAP) iphlen = sizeof(ip6_t);#endif if ((#if SOLARIS2 >= 8 (sap == IP6_DL_SAP) && (mlen < plen)) || ((sap == ETHERTYPE_IP) &&#endif ((iphlen < hlen) || (iphlen > plen) || (mlen < plen)))) { /* * Bad IP packet or not enough data/data length mismatches */ atomic_add_long(&qif->qf_bad, 1); return EINVAL; } /* * 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)) { atomic_add_long(&qif->qf_nodata, 1); return ENOBUFS; } ip = (struct ip *)ALIGN32(m->b_rptr + off); } /* * Discard any excess data. */ if (len > plen) m->b_wptr = m->b_rptr + off + plen; /* * The code in IPFilter assumes that both the ip_off and ip_len * fields are in host byte order, so convert them here to fulfill * that expectation. * * If the target compile host is non-SPARC, assume it is a little * endian machine, requiring the conversion of offset/length fields * to both be host byte ordered. */#ifndef sparc if (sap == ETHERTYPE_IP) { __ipoff = (u_short)ip->ip_off; ip->ip_len = plen; ip->ip_off = ntohs(__ipoff); }#endif 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; /*LINTED: E_CONSTANT_CONDITION*/ PRINT(8,(CE_CONT, "!pfil_hook_get(%x,%p) = %p\n", flags, (void *)ph, (void *)pfh)); for (; pfh; pfh = pfh->pfil_next) if (pfh->pfil_func) { err = (*pfh->pfil_func)(ip, iphlen, qif, out, qpi, mp); if (err || !*mp) break; /* * fr_pullup may have allocated a new buffer. */ 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; /* * If we still have a STREAMS message after calling the filtering * hooks, return the byte order of the fields changed above on * platforms where this is required. They are refetched from the * packet headers because the callback (pfil_func) may have changed * them in some way. */#ifndef sparc if ((err == 0) && (*mp != NULL)) { if (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;}/************************************************************************ * kernel module initialization *//* ------------------------------------------------------------------------ *//* Function: _init *//* Returns: int - DDI_SUCCESS == success, else failure *//* Parameters: Nil. *//* *//* Initialise the kernel module and if that succeeds, call other init *//* routines, elsewhere, that handle initialisation of the more generic *//* components. *//* ------------------------------------------------------------------------ */int _init(void){ int result; result = pfil_nd_init(); /* LINTED: E_CONSTANT_CONDITION */ PRINT(2,(CE_CONT, "pfil_nd_init():%d\n", result)); if (result != 0) return DDI_FAILURE; if (qif_startup() == -1) return DDI_FAILURE; rw_init(&pfil_rw, "pfil_rw", RW_DRIVER, 0); pfil_startup(); result = mod_install(&modlinkage); /* LINTED: E_CONSTANT_CONDITION */ PRINT(1,(CE_CONT, "_init():%d\n", result)); return result;}/* ------------------------------------------------------------------------ *//* Function: _fini *//* Returns: int - DDI_SUCCESS == success, else failure *//* Parameters: Nil. *//* *//* Called when the OS attempts to unload the module, it should only be *//* allowed to succeed if pfil is not currently in the middle of any STREAMS *//* "connections". If it isn't then turn ourselves off and remove the module*//* ------------------------------------------------------------------------ */int _fini(void){ int result; if (qif_head != NULL) return EBUSY; result = mod_remove(&modlinkage); /* LINTED: E_CONSTANT_CONDITION */ PRINT(1,(CE_CONT, "_fini():%d\n", result)); if (result == DDI_SUCCESS) { pfil_nd_fini(); qif_stop(); } return result;}/* ------------------------------------------------------------------------ *//* Function: _info *//* Returns: int - DDI_SUCCESS == success, else failure *//* Parameters: modinfop(I) - pointer to module informatio buffer *//* *//* Standard _info() implementation that just calls mod_info on its linkage *//* structure so information can be copied back into the modinfop struct. *//* ------------------------------------------------------------------------ */int _info(struct modinfo *modinfop){ int result; result = mod_info(&modlinkage, modinfop); /* LINTED: E_CONSTANT_CONDITION */ PRINT(3,(CE_CONT, "_info(%p):%x\n", (void *)modinfop, result)); return result;}/************************************************************************ * */#ifdef PFILDEBUG/* ------------------------------------------------------------------------ *//* Function: pfil_donotip *//* Returns: Nil *//* Parameters: out(I) - in(0)/out(1) flag for direction of message *//* qif(I) - pointer to per-queue interface information *//* q(I) - pointer to STREAMS queue *//* m(I) - pointer to STREAMS message block where IP starts *//* mt(I) - pointer to the start of the STREAMS message *//* ip(I) - pointer to the start of the IP header *//* off(I) - offset from start of message to start of IP header *//* *//* This function is here solely for dumping out the contents of an mblk and *//* showing what related information is known about it, to aid in debugging *//* processing of messages going by that fail to be recognised properly. *//* ------------------------------------------------------------------------ */void pfil_donotip(int out, qif_t *qif, queue_t *q, mblk_t *m, mblk_t *mt, struct ip *ip, size_t off){ u_char *s, outb[256], *t; int i; outb[0] = '\0'; outb[1] = '\0'; outb[2] = '\0'; outb[3] = '\0'; s = ip ? (u_char *)ip : outb; if (!ip && (m == mt) && m->b_cont && (MTYPE(m) != M_DATA)) m = m->b_cont; /*LINTED: E_CONSTANT_CONDITION*/ PRINT(9,(CE_CONT, "!IP %s:%d %ld %p %p %p ip %p b_rptr %p off %ld m %p/%d/%ld/%p mt %p/%d/%ld/%p\n", qif ? qif->qf_name : "?", out, qif ? qif->qf_hl : -1, (void *)q, q ? q->q_ptr : NULL, q ? (void *)q->q_qinfo : NULL, (void *)ip, (void *)m->b_rptr, off, (void *)m, MTYPE(m), MLEN(m), (void *)m->b_cont, (void *)mt, MTYPE(mt), MLEN(mt), (void *)mt->b_cont)); /*LINTED: E_CONSTANT_CONDITION*/ PRINT(9,(CE_CONT, "%02x%02x%02x%02x\n", *s, *(s+1), *(s+2), *(s+3))); while (m != mt) { i = 0; t = outb; s = mt->b_rptr; (void)sprintf((char *)t, "%d:", MTYPE(mt)); t += strlen((char *)t); for (; (i < 100) && (s < mt->b_wptr); i++) { (void)sprintf((char *)t, "%02x%s", *s++, ((i & 3) == 3) ? " " : ""); t += ((i & 3) == 3) ? 3 : 2; } *t++ = '\n'; *t = '\0'; /*LINTED: E_CONSTANT_CONDITION*/ PRINT(50,(CE_CONT, "%s", outb)); mt = mt->b_cont; } i = 0; t = outb; s = m->b_rptr; (void)sprintf((char *)t, "%d:", MTYPE(m)); t += strlen((char *)t); for (; (i < 100) && (s < m->b_wptr); i++) { (void)sprintf((char *)t, "%02x%s", *s++, ((i & 3) == 3) ? " " : ""); t += ((i & 3) == 3) ? 3 : 2; } *t++ = '\n'; *t = '\0'; /*LINTED: E_CONSTANT_CONDITION*/ PRINT(50,(CE_CONT, "%s", outb));}#endif/* ------------------------------------------------------------------------ *//* Function: pfil_property_update *//* Returns: int - DDI_SUCCESS == success, else failure *//* Parameters: modinfop(I) - pointer to module informatio buffer *//* *//* Fetch configuration file values that have been entered into the *//* pfil.conf driver file. *//* ------------------------------------------------------------------------ */static int pfil_property_update(dev_info_t *dip){ char *list, *s, *t; int err; if (ddi_prop_update_int(DDI_DEV_T_ANY, dip, "ddi-no-autodetach", 1) == -1) { cmn_err(CE_WARN, "!updating ddi-no-authdetach failed"); return DDI_FAILURE; } list = NULL; err = ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0, "qif_ipmp_set", &list);#ifdef IPFDEBUG cmn_err(CE_CONT, "IP Filter: lookup_string(pfil_ipmp_list) = %d\n", err);#endif if (err == DDI_SUCCESS) { t = NULL; s = list; do { if (t != NULL) s = t + 1; t = strchr(s, ';'); if (t != NULL) *t = '\0'; qif_ipmp_update(s); } while (t != NULL); ddi_prop_free(list); } return DDI_SUCCESS;}#if SOLARIS2 == 8int miocpullup(mblk_t *m, size_t len){ if (m->b_cont == NULL) return 0; return pullupmsg(m->b_cont, len);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -