1507 * timer on it as we'll never see an error if it fails to
1508 * connect.
1509 */
1510 (void) fr_tcp_age(&is->is_sti, fin, ifs->ifs_ips_tqtqb,
1511 is->is_flags);
1512 MUTEX_EXIT(&is->is_lock);
1513 #ifdef IPFILTER_SCAN
1514 if ((is->is_flags & SI_CLONE) == 0)
1515 (void) ipsc_attachis(is);
1516 #endif
1517 } else {
1518 MUTEX_EXIT(&is->is_lock);
1519 }
1520 #ifdef IPFILTER_SYNC
1521 if ((is->is_flags & IS_STATESYNC) && ((is->is_flags & SI_CLONE) == 0))
1522 is->is_sync = ipfsync_new(SMC_STATE, fin, is);
1523 #endif
1524 if (ifs->ifs_ipstate_logging)
1525 ipstate_log(is, ISL_NEW, ifs);
1526
1527 RWLOCK_EXIT(&ifs->ifs_ipf_state);
1528 fin->fin_rev = IP6_NEQ(&is->is_dst, &fin->fin_daddr);
1529 fin->fin_flx |= FI_STATE;
1530 if (fin->fin_flx & FI_FRAG)
1531 (void) fr_newfrag(fin, pass ^ FR_KEEPSTATE);
1532
1533 return is;
1534 }
1535
1536
1537 /* ------------------------------------------------------------------------ */
1538 /* Function: fr_tcpoptions */
1539 /* Returns: int - 1 == packet matches state entry, 0 == it does not */
1540 /* Parameters: fin(I) - pointer to packet information */
1541 /* tcp(I) - pointer to TCP packet header */
1542 /* td(I) - pointer to TCP data held as part of the state */
1543 /* */
1544 /* Look after the TCP header for any options and deal with those that are */
1545 /* present. Record details about those that we recogise. */
1546 /* ------------------------------------------------------------------------ */
2297 is->is_sport = sp;
2298 is->is_send = ntohl(tcp->th_seq);
2299 } else {
2300 is->is_sport = dp;
2301 is->is_send = ntohl(tcp->th_ack);
2302 }
2303 is->is_maxsend = is->is_send + 1;
2304 } else if ((flags & SI_W_DPORT) != 0) {
2305 if (rev == 0) {
2306 is->is_dport = dp;
2307 is->is_dend = ntohl(tcp->th_ack);
2308 } else {
2309 is->is_dport = sp;
2310 is->is_dend = ntohl(tcp->th_seq);
2311 }
2312 is->is_maxdend = is->is_dend + 1;
2313 }
2314 is->is_flags &= ~(SI_W_SPORT|SI_W_DPORT);
2315 if ((flags & SI_CLONED) && ifs->ifs_ipstate_logging)
2316 ipstate_log(is, ISL_CLONE, ifs);
2317 }
2318
2319 ret = -1;
2320
2321 if (is->is_flx[out][rev] == 0) {
2322 is->is_flx[out][rev] = flx;
2323 /*
2324 * If we are dealing with the first packet coming in reverse
2325 * direction (sent by peer), then we have to set options into
2326 * state.
2327 */
2328 if (rev == 1 && is->is_optmsk[1] == 0x0) {
2329 is->is_optmsk[1] = 0xffffffff;
2330 is->is_opt[1] = fin->fin_optmsk;
2331 DTRACE_PROBE(set_rev_opts);
2332 }
2333 if (is->is_v == 6) {
2334 is->is_opt[rev] &= ~0x8;
2335 is->is_optmsk[rev] &= ~0x8;
2336 }
3380 ipfsync_del(is->is_sync);
3381 #endif
3382 #ifdef IPFILTER_SCAN
3383 (void) ipsc_detachis(is);
3384 #endif
3385
3386 /*
3387 * Now remove it from master list of state table entries.
3388 */
3389 if (is->is_pnext != NULL) {
3390 *is->is_pnext = is->is_next;
3391 if (is->is_next != NULL) {
3392 is->is_next->is_pnext = is->is_pnext;
3393 is->is_next = NULL;
3394 }
3395 is->is_pnext = NULL;
3396 }
3397
3398 if (ifs->ifs_ipstate_logging != 0 && why != 0)
3399 ipstate_log(is, why, ifs);
3400
3401 if (is->is_rule != NULL) {
3402 is->is_rule->fr_statecnt--;
3403 (void)fr_derefrule(&is->is_rule, ifs);
3404 }
3405
3406 MUTEX_DESTROY(&is->is_lock);
3407 KFREE(is);
3408 ifs->ifs_ips_num--;
3409
3410 return (0);
3411 }
3412
3413
3414 /* ------------------------------------------------------------------------ */
3415 /* Function: fr_timeoutstate */
3416 /* Returns: Nil */
3417 /* Parameters: ifs - ipf stack instance */
3418 /* */
3419 /* Slowly expire held state for thingslike UDP and ICMP. The algorithm */
3420 /* used here is to keep the queue sorted with the oldest things at the top */
3914 if (rval == 2) {
3915 DTRACE_PROBE1(state_keeping_timer, int, nstate);
3916 rval = 1;
3917 }
3918 else if (rval == 1) {
3919 tqe->tqe_state[dir] = nstate;
3920 /*
3921 * The nstate can either advance to a new state, or remain
3922 * unchanged, resetting the timer by moving to the bottom of
3923 * the queue.
3924 */
3925 DTRACE_PROBE1(state_done, int, nstate);
3926
3927 if ((tqe->tqe_flags & TQE_RULEBASED) == 0)
3928 fr_movequeue(tqe, tqe->tqe_ifq, tqtab + nstate, ifs);
3929 }
3930
3931 return rval;
3932 }
3933
3934
3935 /* ------------------------------------------------------------------------ */
3936 /* Function: ipstate_log */
3937 /* Returns: Nil */
3938 /* Parameters: is(I) - pointer to state structure */
3939 /* type(I) - type of log entry to create */
3940 /* */
3941 /* Creates a state table log entry using the state structure and type info. */
3942 /* passed in. Log packet/byte counts, source/destination address and other */
3943 /* protocol specific information. */
3944 /* ------------------------------------------------------------------------ */
3945 void ipstate_log(is, type, ifs)
3946 struct ipstate *is;
3947 u_int type;
3948 ipf_stack_t *ifs;
3949 {
3950 #ifdef IPFILTER_LOG
3951 struct ipslog ipsl;
3952 size_t sizes[1];
3953 void *items[1];
3954 int types[1];
|
1507 * timer on it as we'll never see an error if it fails to
1508 * connect.
1509 */
1510 (void) fr_tcp_age(&is->is_sti, fin, ifs->ifs_ips_tqtqb,
1511 is->is_flags);
1512 MUTEX_EXIT(&is->is_lock);
1513 #ifdef IPFILTER_SCAN
1514 if ((is->is_flags & SI_CLONE) == 0)
1515 (void) ipsc_attachis(is);
1516 #endif
1517 } else {
1518 MUTEX_EXIT(&is->is_lock);
1519 }
1520 #ifdef IPFILTER_SYNC
1521 if ((is->is_flags & IS_STATESYNC) && ((is->is_flags & SI_CLONE) == 0))
1522 is->is_sync = ipfsync_new(SMC_STATE, fin, is);
1523 #endif
1524 if (ifs->ifs_ipstate_logging)
1525 ipstate_log(is, ISL_NEW, ifs);
1526
1527 if (IFS_CFWLOG(ifs))
1528 ipf_log_cfwlog(is, ISL_NEW, ifs);
1529
1530 RWLOCK_EXIT(&ifs->ifs_ipf_state);
1531 fin->fin_rev = IP6_NEQ(&is->is_dst, &fin->fin_daddr);
1532 fin->fin_flx |= FI_STATE;
1533 if (fin->fin_flx & FI_FRAG)
1534 (void) fr_newfrag(fin, pass ^ FR_KEEPSTATE);
1535
1536 return is;
1537 }
1538
1539
1540 /* ------------------------------------------------------------------------ */
1541 /* Function: fr_tcpoptions */
1542 /* Returns: int - 1 == packet matches state entry, 0 == it does not */
1543 /* Parameters: fin(I) - pointer to packet information */
1544 /* tcp(I) - pointer to TCP packet header */
1545 /* td(I) - pointer to TCP data held as part of the state */
1546 /* */
1547 /* Look after the TCP header for any options and deal with those that are */
1548 /* present. Record details about those that we recogise. */
1549 /* ------------------------------------------------------------------------ */
2300 is->is_sport = sp;
2301 is->is_send = ntohl(tcp->th_seq);
2302 } else {
2303 is->is_sport = dp;
2304 is->is_send = ntohl(tcp->th_ack);
2305 }
2306 is->is_maxsend = is->is_send + 1;
2307 } else if ((flags & SI_W_DPORT) != 0) {
2308 if (rev == 0) {
2309 is->is_dport = dp;
2310 is->is_dend = ntohl(tcp->th_ack);
2311 } else {
2312 is->is_dport = sp;
2313 is->is_dend = ntohl(tcp->th_seq);
2314 }
2315 is->is_maxdend = is->is_dend + 1;
2316 }
2317 is->is_flags &= ~(SI_W_SPORT|SI_W_DPORT);
2318 if ((flags & SI_CLONED) && ifs->ifs_ipstate_logging)
2319 ipstate_log(is, ISL_CLONE, ifs);
2320 if ((flags & SI_CLONED) && IFS_CFWLOG(ifs))
2321 ipf_log_cfwlog(is, ISL_CLONE, ifs);
2322 }
2323
2324 ret = -1;
2325
2326 if (is->is_flx[out][rev] == 0) {
2327 is->is_flx[out][rev] = flx;
2328 /*
2329 * If we are dealing with the first packet coming in reverse
2330 * direction (sent by peer), then we have to set options into
2331 * state.
2332 */
2333 if (rev == 1 && is->is_optmsk[1] == 0x0) {
2334 is->is_optmsk[1] = 0xffffffff;
2335 is->is_opt[1] = fin->fin_optmsk;
2336 DTRACE_PROBE(set_rev_opts);
2337 }
2338 if (is->is_v == 6) {
2339 is->is_opt[rev] &= ~0x8;
2340 is->is_optmsk[rev] &= ~0x8;
2341 }
3385 ipfsync_del(is->is_sync);
3386 #endif
3387 #ifdef IPFILTER_SCAN
3388 (void) ipsc_detachis(is);
3389 #endif
3390
3391 /*
3392 * Now remove it from master list of state table entries.
3393 */
3394 if (is->is_pnext != NULL) {
3395 *is->is_pnext = is->is_next;
3396 if (is->is_next != NULL) {
3397 is->is_next->is_pnext = is->is_pnext;
3398 is->is_next = NULL;
3399 }
3400 is->is_pnext = NULL;
3401 }
3402
3403 if (ifs->ifs_ipstate_logging != 0 && why != 0)
3404 ipstate_log(is, why, ifs);
3405 #if 0
3406 /*
3407 * For now, ipf_log_cfwlog() copes with all "why" values.
3408 * strictly speaking, though, they all map to one event, which for
3409 * now is not supported.
3410 */
3411 if (why != 0 && IFS_CFWLOG(ifs))
3412 ipf_log_cfwlog(is, why, ifs);
3413 #endif
3414 if (is->is_rule != NULL) {
3415 is->is_rule->fr_statecnt--;
3416 (void)fr_derefrule(&is->is_rule, ifs);
3417 }
3418
3419 MUTEX_DESTROY(&is->is_lock);
3420 KFREE(is);
3421 ifs->ifs_ips_num--;
3422
3423 return (0);
3424 }
3425
3426
3427 /* ------------------------------------------------------------------------ */
3428 /* Function: fr_timeoutstate */
3429 /* Returns: Nil */
3430 /* Parameters: ifs - ipf stack instance */
3431 /* */
3432 /* Slowly expire held state for thingslike UDP and ICMP. The algorithm */
3433 /* used here is to keep the queue sorted with the oldest things at the top */
3927 if (rval == 2) {
3928 DTRACE_PROBE1(state_keeping_timer, int, nstate);
3929 rval = 1;
3930 }
3931 else if (rval == 1) {
3932 tqe->tqe_state[dir] = nstate;
3933 /*
3934 * The nstate can either advance to a new state, or remain
3935 * unchanged, resetting the timer by moving to the bottom of
3936 * the queue.
3937 */
3938 DTRACE_PROBE1(state_done, int, nstate);
3939
3940 if ((tqe->tqe_flags & TQE_RULEBASED) == 0)
3941 fr_movequeue(tqe, tqe->tqe_ifq, tqtab + nstate, ifs);
3942 }
3943
3944 return rval;
3945 }
3946
3947 /* ------------------------------------------------------------------------ */
3948 /* Function: ipstate_log */
3949 /* Returns: Nil */
3950 /* Parameters: is(I) - pointer to state structure */
3951 /* type(I) - type of log entry to create */
3952 /* */
3953 /* Creates a state table log entry using the state structure and type info. */
3954 /* passed in. Log packet/byte counts, source/destination address and other */
3955 /* protocol specific information. */
3956 /* ------------------------------------------------------------------------ */
3957 void ipstate_log(is, type, ifs)
3958 struct ipstate *is;
3959 u_int type;
3960 ipf_stack_t *ifs;
3961 {
3962 #ifdef IPFILTER_LOG
3963 struct ipslog ipsl;
3964 size_t sizes[1];
3965 void *items[1];
3966 int types[1];
|