static int protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah) { if (ntohs(*ah->dport) == TFTP_PORT_NUMBER) FindRtspOut(la, pip->ip_src, pip->ip_dst, *ah->sport, *ah->aport, IPPROTO_UDP); else AliasHandleRtspOut(la, pip, ah->lnk, ah->maxpktsize); return (0); }
static int alias_rtsp_out(struct libalias *la, struct ip *pip, struct alias_link *lnk, char *data, const char *port_str) { int hlen, tlen, dlen; struct tcphdr *tc; int i, j, pos, state, port_dlen, new_dlen, delta; u_short p[2], new_len; u_short sport, eport, base_port; u_short salias = 0, ealias = 0, base_alias = 0; const char *transport_str = "transport:"; char newdata[2048], *port_data, *port_newdata, stemp[80]; int links_created = 0, pkt_updated = 0; struct alias_link *rtsp_lnk = NULL; struct in_addr null_addr; /* Calculate data length of TCP packet */ tc = (struct tcphdr *)ip_next(pip); hlen = (pip->ip_hl + tc->th_off) << 2; tlen = ntohs(pip->ip_len); dlen = tlen - hlen; /* Find keyword, "Transport: " */ pos = search_string(data, dlen, transport_str); if (pos < 0) { return (-1); } port_data = data + pos; port_dlen = dlen - pos; memcpy(newdata, data, pos); port_newdata = newdata + pos; while (port_dlen > (int)strlen(port_str)) { /* Find keyword, appropriate port string */ pos = search_string(port_data, port_dlen, port_str); if (pos < 0) { break; } memcpy(port_newdata, port_data, pos + 1); port_newdata += (pos + 1); p[0] = p[1] = 0; sport = eport = 0; state = 0; for (i = pos; i < port_dlen; i++) { switch (state) { case 0: if (port_data[i] == '=') { state++; } break; case 1: if (ISDIGIT(port_data[i])) { p[0] = p[0] * 10 + port_data[i] - '0'; } else { if (port_data[i] == ';') { state = 3; } if (port_data[i] == '-') { state++; } } break; case 2: if (ISDIGIT(port_data[i])) { p[1] = p[1] * 10 + port_data[i] - '0'; } else { state++; } break; case 3: base_port = p[0]; sport = htons(p[0]); eport = htons(p[1]); if (!links_created) { links_created = 1; /* * Find an even numbered port * number base that satisfies the * contiguous number of ports we * need */ null_addr.s_addr = 0; if (0 == (salias = FindNewPortGroup(la, null_addr, FindAliasAddress(la, pip->ip_src), sport, 0, RTSP_PORT_GROUP, IPPROTO_UDP, 1))) { #ifdef LIBALIAS_DEBUG fprintf(stderr, "PacketAlias/RTSP: Cannot find contiguous RTSP data ports\n"); #endif } else { base_alias = ntohs(salias); for (j = 0; j < RTSP_PORT_GROUP; j++) { /* * Establish link * to port found in * RTSP packet */ rtsp_lnk = FindRtspOut(la, GetOriginalAddress(lnk), null_addr, htons(base_port + j), htons(base_alias + j), IPPROTO_UDP); if (rtsp_lnk != NULL) { #ifndef NO_FW_PUNCH /* * Punch * hole in * firewall */ PunchFWHole(rtsp_lnk); #endif } else { #ifdef LIBALIAS_DEBUG fprintf(stderr, "PacketAlias/RTSP: Cannot allocate RTSP data ports\n"); #endif break; } } } ealias = htons(base_alias + (RTSP_PORT_GROUP - 1)); } if (salias && rtsp_lnk) { pkt_updated = 1; /* Copy into IP packet */ sprintf(stemp, "%d", ntohs(salias)); memcpy(port_newdata, stemp, strlen(stemp)); port_newdata += strlen(stemp); if (eport != 0) { *port_newdata = '-'; port_newdata++; /* Copy into IP packet */ sprintf(stemp, "%d", ntohs(ealias)); memcpy(port_newdata, stemp, strlen(stemp)); port_newdata += strlen(stemp); } *port_newdata = ';'; port_newdata++; } state++; break; } if (state > 3) { break; } } port_data += i; port_dlen -= i; } if (!pkt_updated) return (-1); memcpy(port_newdata, port_data, port_dlen); port_newdata += port_dlen; *port_newdata = '\0'; /* Create new packet */ new_dlen = port_newdata - newdata; memcpy(data, newdata, new_dlen); SetAckModified(lnk); tc = (struct tcphdr *)ip_next(pip); delta = GetDeltaSeqOut(tc->th_seq, lnk); AddSeq(lnk, delta + new_dlen - dlen, pip->ip_hl, pip->ip_len, tc->th_seq, tc->th_off); new_len = htons(hlen + new_dlen); DifferentialChecksum(&pip->ip_sum, &new_len, &pip->ip_len, 1); pip->ip_len = new_len; tc->th_sum = 0; #ifdef _KERNEL tc->th_x2 = 1; #else tc->th_sum = TcpChecksum(pip); #endif return (0); }
static int UdpAliasOut(struct ip *pip) { struct udphdr *ud; struct alias_link *link; /* Return if proxy-only mode is enabled */ if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) return PKT_ALIAS_OK; ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); link = FindUdpTcpOut(pip->ip_src, pip->ip_dst, ud->uh_sport, ud->uh_dport, IPPROTO_UDP, 1); if (link != NULL) { u_short alias_port; struct in_addr alias_address; alias_address = GetAliasAddress(link); alias_port = GetAliasPort(link); /* Special processing for IP encoding protocols */ if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER) AliasHandleCUSeeMeOut(pip, link); /* If NETBIOS Datagram, It should be alias address in UDP Data, too */ else if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER) AliasHandleUdpNbt(pip, link, &alias_address, alias_port); else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER) AliasHandleUdpNbtNS(pip, link, &pip->ip_src, &ud->uh_sport, &alias_address, &alias_port); /* * We don't know in advance what TID the TFTP server will choose, * so we create a wilcard link (destination port is unspecified) * that will match any TID from a given destination. */ else if (ntohs(ud->uh_dport) == TFTP_PORT_NUMBER) FindRtspOut(pip->ip_src, pip->ip_dst, ud->uh_sport, alias_port, IPPROTO_UDP); /* If UDP checksum is not zero, adjust since source port is */ /* being aliased and source address is being altered */ if (ud->uh_sum != 0) { int accumulate; u_short *sptr; accumulate = ud->uh_sport; accumulate -= alias_port; sptr = (u_short *) &(pip->ip_src); accumulate += *sptr++; accumulate += *sptr; sptr = (u_short *) &alias_address; accumulate -= *sptr++; accumulate -= *sptr; ADJUST_CHECKSUM(accumulate, ud->uh_sum); } /* Put alias port in UDP header */ ud->uh_sport = alias_port; /* Change source address */ DifferentialChecksum(&pip->ip_sum, (u_short *) &alias_address, (u_short *) &pip->ip_src, 2); pip->ip_src = alias_address; return(PKT_ALIAS_OK); } return(PKT_ALIAS_IGNORED); }