Make a certain link go through the firewall */
| 2682 | |
| 2683 | /* Make a certain link go through the firewall */ |
| 2684 | void |
| 2685 | PunchFWHole(struct alias_link *lnk) |
| 2686 | { |
| 2687 | struct libalias *la; |
| 2688 | int r; /* Result code */ |
| 2689 | struct ip_fw rule; /* On-the-fly built rule */ |
| 2690 | int fwhole; /* Where to punch hole */ |
| 2691 | |
| 2692 | la = lnk->la; |
| 2693 | |
| 2694 | /* Don't do anything unless we are asked to */ |
| 2695 | if (!(la->packetAliasMode & PKT_ALIAS_PUNCH_FW) || |
| 2696 | la->fireWallFD < 0 || |
| 2697 | lnk->link_type != LINK_TCP) |
| 2698 | return; |
| 2699 | |
| 2700 | memset(&rule, 0, sizeof rule); |
| 2701 | |
| 2702 | /** Build rule **/ |
| 2703 | |
| 2704 | /* Find empty slot */ |
| 2705 | for (fwhole = la->fireWallActiveNum; |
| 2706 | fwhole < la->fireWallBaseNum + la->fireWallNumNums && |
| 2707 | fw_tstfield(la, la->fireWallField, fwhole); |
| 2708 | fwhole++); |
| 2709 | if (fwhole == la->fireWallBaseNum + la->fireWallNumNums) { |
| 2710 | for (fwhole = la->fireWallBaseNum; |
| 2711 | fwhole < la->fireWallActiveNum && |
| 2712 | fw_tstfield(la, la->fireWallField, fwhole); |
| 2713 | fwhole++); |
| 2714 | if (fwhole == la->fireWallActiveNum) { |
| 2715 | /* No rule point empty - we can't punch more holes. */ |
| 2716 | la->fireWallActiveNum = la->fireWallBaseNum; |
| 2717 | #ifdef LIBALIAS_DEBUG |
| 2718 | fprintf(stderr, "libalias: Unable to create firewall hole!\n"); |
| 2719 | #endif |
| 2720 | return; |
| 2721 | } |
| 2722 | } |
| 2723 | /* Start next search at next position */ |
| 2724 | la->fireWallActiveNum = fwhole + 1; |
| 2725 | |
| 2726 | /* |
| 2727 | * generate two rules of the form |
| 2728 | * |
| 2729 | * add fwhole accept tcp from OAddr OPort to DAddr DPort add fwhole |
| 2730 | * accept tcp from DAddr DPort to OAddr OPort |
| 2731 | */ |
| 2732 | if (GetOriginalPort(lnk) != 0 && GetDestPort(lnk) != 0) { |
| 2733 | u_int32_t rulebuf[255]; |
| 2734 | int i; |
| 2735 | |
| 2736 | i = fill_rule(rulebuf, sizeof(rulebuf), fwhole, |
| 2737 | O_ACCEPT, IPPROTO_TCP, |
| 2738 | GetOriginalAddress(lnk), ntohs(GetOriginalPort(lnk)), |
| 2739 | GetDestAddress(lnk), ntohs(GetDestPort(lnk))); |
| 2740 | r = setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_ADD, rulebuf, i); |
| 2741 | if (r) |
no test coverage detected