📄 ip_conntrack_helper_h323.c
字号:
if (ret < 0) return -1; } if ((olc->options & eOpenLogicalChannel_separateStack) && olc->forwardLogicalChannelParameters.dataType.choice == eDataType_data && olc->forwardLogicalChannelParameters.dataType.data.application. choice == eDataApplicationCapability_application_t120 && olc->forwardLogicalChannelParameters.dataType.data.application. t120.choice == eDataProtocolCapability_separateLANStack && olc->separateStack.networkAddress.choice == eNetworkAccessParameters_networkAddress_localAreaAddress) { ret = expect_t120(pskb, ct, ctinfo, data, dataoff, &olc->separateStack.networkAddress. localAreaAddress); if (ret < 0) return -1; } return 0;}/****************************************************************************/static int process_olca(struct sk_buff **pskb, struct ip_conntrack *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, OpenLogicalChannelAck * olca){ H2250LogicalChannelAckParameters *ack; int ret; DEBUGP("ip_ct_h323: OpenLogicalChannelAck\n"); if ((olca->options & eOpenLogicalChannelAck_reverseLogicalChannelParameters) && (olca->reverseLogicalChannelParameters.options & eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters) && (olca->reverseLogicalChannelParameters.multiplexParameters. choice == eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)) { ret = process_h245_channel(pskb, ct, ctinfo, data, dataoff, &olca-> reverseLogicalChannelParameters. multiplexParameters. h2250LogicalChannelParameters); if (ret < 0) return -1; } if ((olca->options & eOpenLogicalChannelAck_forwardMultiplexAckParameters) && (olca->forwardMultiplexAckParameters.choice == eOpenLogicalChannelAck_forwardMultiplexAckParameters_h2250LogicalChannelAckParameters)) { ack = &olca->forwardMultiplexAckParameters. h2250LogicalChannelAckParameters; if (ack->options & eH2250LogicalChannelAckParameters_mediaChannel) { /* RTP */ ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff, &ack->mediaChannel); if (ret < 0) return -1; } if (ack->options & eH2250LogicalChannelAckParameters_mediaControlChannel) { /* RTCP */ ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff, &ack->mediaControlChannel); if (ret < 0) return -1; } } return 0;}/****************************************************************************/static int process_h245(struct sk_buff **pskb, struct ip_conntrack *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, MultimediaSystemControlMessage * mscm){ switch (mscm->choice) { case eMultimediaSystemControlMessage_request: if (mscm->request.choice == eRequestMessage_openLogicalChannel) { return process_olc(pskb, ct, ctinfo, data, dataoff, &mscm->request.openLogicalChannel); } DEBUGP("ip_ct_h323: H.245 Request %d\n", mscm->request.choice); break; case eMultimediaSystemControlMessage_response: if (mscm->response.choice == eResponseMessage_openLogicalChannelAck) { return process_olca(pskb, ct, ctinfo, data, dataoff, &mscm->response. openLogicalChannelAck); } DEBUGP("ip_ct_h323: H.245 Response %d\n", mscm->response.choice); break; default: DEBUGP("ip_ct_h323: H.245 signal %d\n", mscm->choice); break; } return 0;}/****************************************************************************/static int h245_help(struct sk_buff **pskb, struct ip_conntrack *ct, enum ip_conntrack_info ctinfo){ static MultimediaSystemControlMessage mscm; unsigned char *data = NULL; int datalen; int dataoff; int ret; /* Until there's been traffic both ways, don't look in packets. */ if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) { return NF_ACCEPT; } DEBUGP("ip_ct_h245: skblen = %u\n", (*pskb)->len); spin_lock_bh(&ip_h323_lock); /* Process each TPKT */ while (get_tpkt_data(pskb, ct, ctinfo, &data, &datalen, &dataoff)) { DEBUGP("ip_ct_h245: TPKT %u.%u.%u.%u->%u.%u.%u.%u, len=%d\n", NIPQUAD((*pskb)->nh.iph->saddr), NIPQUAD((*pskb)->nh.iph->daddr), datalen); /* Decode H.245 signal */ ret = DecodeMultimediaSystemControlMessage(data, datalen, &mscm); if (ret < 0) { if (net_ratelimit()) printk("ip_ct_h245: decoding error: %s\n", ret == H323_ERROR_BOUND ? "out of bound" : "out of range"); /* We don't drop when decoding error */ break; } /* Process H.245 signal */ if (process_h245(pskb, ct, ctinfo, &data, dataoff, &mscm) < 0) goto drop; } spin_unlock_bh(&ip_h323_lock); return NF_ACCEPT; drop: spin_unlock_bh(&ip_h323_lock); if (net_ratelimit()) printk("ip_ct_h245: packet dropped\n"); return NF_DROP;}/****************************************************************************/static struct ip_conntrack_helper ip_conntrack_helper_h245 = { .name = "H.245", .me = THIS_MODULE, .max_expected = H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */ , .timeout = 240, .tuple = {.dst = {.protonum = IPPROTO_TCP}}, .mask = {.src = {.u = {0xFFFF}}, .dst = {.protonum = 0xFF}}, .help = h245_help};/****************************************************************************/void ip_conntrack_h245_expect(struct ip_conntrack *new, struct ip_conntrack_expect *this){ write_lock_bh(&ip_conntrack_lock); new->helper = &ip_conntrack_helper_h245; write_unlock_bh(&ip_conntrack_lock);}/****************************************************************************/int get_h225_addr(unsigned char *data, TransportAddress * addr, u_int32_t * ip, u_int16_t * port){ unsigned char *p; if (addr->choice != eTransportAddress_ipAddress) return 0; p = data + addr->ipAddress.ip; *ip = htonl((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3])); *port = (p[4] << 8) | (p[5]); return 1;}/****************************************************************************/static int expect_h245(struct sk_buff **pskb, struct ip_conntrack *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, TransportAddress * addr){ int dir = CTINFO2DIR(ctinfo); int ret = 0; u_int32_t ip; u_int16_t port; struct ip_conntrack_expect *exp = NULL; /* Read h245Address */ if (!get_h225_addr(*data, addr, &ip, &port) || ip != ct->tuplehash[dir].tuple.src.ip || port == 0) return 0; /* Create expect for h245 connection */ if ((exp = ip_conntrack_expect_alloc(ct)) == NULL) return -1; exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip; exp->tuple.src.u.tcp.port = 0; exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip; exp->tuple.dst.u.tcp.port = htons(port); exp->tuple.dst.protonum = IPPROTO_TCP; exp->mask.src.ip = 0xFFFFFFFF; exp->mask.src.u.tcp.port = 0; exp->mask.dst.ip = 0xFFFFFFFF; exp->mask.dst.u.tcp.port = 0xFFFF; exp->mask.dst.protonum = 0xFF; exp->flags = 0; if (ct->tuplehash[dir].tuple.src.ip != ct->tuplehash[!dir].tuple.dst.ip && nat_h245_hook) { /* NAT needed */ ret = nat_h245_hook(pskb, ct, ctinfo, data, dataoff, addr, port, exp); } else { /* Conntrack only */ exp->expectfn = ip_conntrack_h245_expect; if (ip_conntrack_expect_related(exp) == 0) { DEBUGP("ip_ct_q931: expect H.245 " "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n", NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port), NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port)); } else ret = -1; } ip_conntrack_expect_put(exp); return ret;}/****************************************************************************/static int process_setup(struct sk_buff **pskb, struct ip_conntrack *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, Setup_UUIE * setup){ int dir = CTINFO2DIR(ctinfo); int ret; int i; u_int32_t ip; u_int16_t port; DEBUGP("ip_ct_q931: Setup\n"); if (setup->options & eSetup_UUIE_h245Address) { ret = expect_h245(pskb, ct, ctinfo, data, dataoff, &setup->h245Address); if (ret < 0) return -1; } if ((setup->options & eSetup_UUIE_destCallSignalAddress) && (set_h225_addr_hook) && get_h225_addr(*data, &setup->destCallSignalAddress, &ip, &port) && ip != ct->tuplehash[!dir].tuple.src.ip) { DEBUGP("ip_ct_q931: set destCallSignalAddress " "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n", NIPQUAD(ip), port, NIPQUAD(ct->tuplehash[!dir].tuple.src.ip), ntohs(ct->tuplehash[!dir].tuple.src.u.tcp.port)); ret = set_h225_addr_hook(pskb, data, dataoff, &setup->destCallSignalAddress, ct->tuplehash[!dir].tuple.src.ip, ntohs(ct->tuplehash[!dir].tuple.src. u.tcp.port)); if (ret < 0) return -1; } if ((setup->options & eSetup_UUIE_sourceCallSignalAddress) && (set_h225_addr_hook) && get_h225_addr(*data, &setup->sourceCallSignalAddress, &ip, &port) && ip != ct->tuplehash[!dir].tuple.dst.ip) { DEBUGP("ip_ct_q931: set sourceCallSignalAddress " "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n", NIPQUAD(ip), port, NIPQUAD(ct->tuplehash[!dir].tuple.dst.ip), ntohs(ct->tuplehash[!dir].tuple.dst.u.tcp.port)); ret = set_h225_addr_hook(pskb, data, dataoff, &setup->sourceCallSignalAddress, ct->tuplehash[!dir].tuple.dst.ip, ntohs(ct->tuplehash[!dir].tuple.dst. u.tcp.port)); if (ret < 0) return -1; } if (setup->options & eSetup_UUIE_fastStart) { for (i = 0; i < setup->fastStart.count; i++) { ret = process_olc(pskb, ct, ctinfo, data, dataoff, &setup->fastStart.item[i]); if (ret < 0) return -1; } } return 0;}/****************************************************************************/static int process_callproceeding(struct sk_buff **pskb, struct ip_conntrack *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, CallProceeding_UUIE * callproc){ int ret; int i; DEBUGP("ip_ct_q931: CallProceeding\n"); if (callproc->options & eCallProceeding_UUIE_h245Address) { ret = expect_h245(pskb, ct, ctinfo, data, dataoff, &callproc->h245Address); if (ret < 0) return -1; } if (callproc->options & eCallProceeding_UUIE_fastStart) { for (i = 0; i < callproc->fastStart.count; i++) { ret = process_olc(pskb, ct, ctinfo, data, dataoff, &callproc->fastStart.item[i]); if (ret < 0) return -1; } } return 0;}/****************************************************************************/static int process_connect(struct sk_buff **pskb, struct ip_conntrack *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, Connect_UUIE * connect){ int ret; int i; DEBUGP("ip_ct_q931: Connect\n"); if (connect->options & eConnect_UUIE_h245Address) { ret = expect_h245(pskb, ct, ctinfo, data, dataoff, &connect->h245Address); if (ret < 0) return -1; } if (connect->options & eConnect_UUIE_fastStart) { for (i = 0; i < connect->fastStart.count; i++) { ret = process_olc(pskb, ct, ctinfo, data, dataoff, &connect->fastStart.item[i]); if (ret < 0) return -1; } } return 0;}/****************************************************************************/static int process_alerting(struct sk_buff **pskb, struct ip_conntrack *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, Alerting_UUIE * alert){ int ret; int i; DEBUGP("ip_ct_q931: Alerting\n"); if (alert->options & eAlerting_UUIE_h245Address) { ret = expect_h245(pskb, ct, ctinfo, data, dataoff, &alert->h245Address); if (ret < 0) return -1; } if (alert->options & eAlerting_UUIE_fastStart) { for (i = 0; i < alert->fastStart.count; i++) { ret = process_olc(pskb, ct, ctinfo, data, dataoff, &alert->fastStart.item[i]); if (ret < 0) return -1; } } return 0;}/****************************************************************************/static int process_information(struct sk_buff **pskb, struct ip_conntrack *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, Information_UUIE * info){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -