コード例 #1
0
ファイル: Vxlan.c プロジェクト: Altiscale/ovs
NDIS_STATUS
OvsSlowPathDecapVxlan(const PNET_BUFFER_LIST packet,
                   OvsIPv4TunnelKey *tunnelKey)
{
    NDIS_STATUS status = NDIS_STATUS_FAILURE;
    UDPHdr udpStorage;
    const UDPHdr *udp;
    VXLANHdr *VxlanHeader;
    VXLANHdr  VxlanHeaderBuffer;
    struct IPHdr ip_storage;
    const struct IPHdr *nh;
    OVS_PACKET_HDR_INFO layers;

    layers.value = 0;

    do {
        nh = OvsGetIp(packet, layers.l3Offset, &ip_storage);
        if (nh) {
            layers.l4Offset = layers.l3Offset + nh->ihl * 4;
        } else {
            break;
        }

        /* make sure it's a VXLAN packet */
        udp = OvsGetUdp(packet, layers.l4Offset, &udpStorage);
        if (udp) {
            layers.l7Offset = layers.l4Offset + sizeof *udp;
        } else {
            break;
        }

        /* XXX Should be tested against the dynamic port # in the VXLAN vport */
        ASSERT(udp->dest == RtlUshortByteSwap(VXLAN_UDP_PORT));

        VxlanHeader = (VXLANHdr *)OvsGetPacketBytes(packet,
                                                    sizeof(*VxlanHeader),
                                                    layers.l7Offset,
                                                    &VxlanHeaderBuffer);

        if (VxlanHeader) {
            tunnelKey->src = nh->saddr;
            tunnelKey->dst = nh->daddr;
            tunnelKey->ttl = nh->ttl;
            tunnelKey->tos = nh->tos;
            if (VxlanHeader->instanceID) {
                tunnelKey->flags = OVS_TNL_F_KEY;
                tunnelKey->tunnelId = VXLAN_VNI_TO_TUNNELID(VxlanHeader->vxlanID);
            } else {
                tunnelKey->flags = 0;
                tunnelKey->tunnelId = 0;
            }
        } else {
            break;
        }
        status = NDIS_STATUS_SUCCESS;

    } while(FALSE);

    return status;
}
コード例 #2
0
ファイル: BufferMgmt.c プロジェクト: digideskio/ovs-reviews
/*
 * --------------------------------------------------------------------------
 * GetSegmentHeaderInfo
 *
 *    Extract header size and sequence number for the segment.
 * --------------------------------------------------------------------------
 */
static NDIS_STATUS
GetSegmentHeaderInfo(PNET_BUFFER_LIST nbl,
                     const POVS_PACKET_HDR_INFO hdrInfo,
                     UINT32 *hdrSize, UINT32 *seqNumber)
{
    TCPHdr tcpStorage;
    const TCPHdr *tcp;

    /* Parse the orginal Eth/IP/TCP header */
    tcp = OvsGetPacketBytes(nbl, sizeof *tcp, hdrInfo->l4Offset, &tcpStorage);
    if (tcp == NULL) {
        return NDIS_STATUS_FAILURE;
    }
    *seqNumber = ntohl(tcp->seq);
    *hdrSize = hdrInfo->l4Offset + TCP_HDR_LEN(tcp);

    return NDIS_STATUS_SUCCESS;
}
コード例 #3
0
ファイル: Conntrack-ftp.c プロジェクト: Grim-lock/ovs
/*
 *----------------------------------------------------------------------------
 * OvsCtHandleFtp
 *     Extract the FTP control data from the packet and created a related
 *     entry if it's a valid connection. This method doesn't support extended
 *     FTP yet. Supports PORT and PASV commands.
 *     Eg:
 *     'PORT 192,168,137,103,192,22\r\n' -> '192.168.137.103' and 49174
 *     '227 Entering Passive Mode (192,168,137,104,194,14)\r\n' gets extracted
 *      to '192.168.137.104' and 49678
 *----------------------------------------------------------------------------
 */
NDIS_STATUS
OvsCtHandleFtp(PNET_BUFFER_LIST curNbl,
               OvsFlowKey *key,
               OVS_PACKET_HDR_INFO *layers,
               UINT64 currentTime,
               POVS_CT_ENTRY entry,
               BOOLEAN request)
{
    NDIS_STATUS status;
    FTP_TYPE ftpType = 0;
    const char *buf;
    char temp[256] = { 0 };
    char ftpMsg[256] = { 0 };

    TCPHdr tcpStorage;
    const TCPHdr *tcp;
    tcp = OvsGetTcp(curNbl, layers->l4Offset, &tcpStorage);
    if (!tcp) {
        return NDIS_STATUS_INVALID_PACKET;
    }

    UINT32 len = OvsGetTcpPayloadLength(curNbl);
    if (len > sizeof(temp)) {
        /* We only care up to 256 */
        len = sizeof(temp);
    }

    buf = OvsGetPacketBytes(curNbl, len,
                            layers->l4Offset + TCP_HDR_LEN(tcp),
                            temp);
    if (buf == NULL) {
        return NDIS_STATUS_INVALID_PACKET;
    }

    OvsStrlcpy((char *)ftpMsg, (char *)buf, min(len, sizeof(ftpMsg)));
    char *req = NULL;

    if (request) {
        if ((len >= 5) && (OvsStrncmp("PORT", ftpMsg, 4) == 0)) {
            ftpType = FTP_TYPE_ACTIVE;
            req = ftpMsg + 4;
        }
    } else {
        if ((len >= 4) && (OvsStrncmp(FTP_PASV_RSP_PREFIX, ftpMsg, 3) == 0)) {
            ftpType = FTP_TYPE_PASV;
            /* There are various formats for PASV command. We try to support
             * some of them. This has been addressed by RFC 2428 - EPSV.
             * Eg:
             *    227 Entering Passive Mode (h1,h2,h3,h4,p1,p2).
             *    227 Entering Passive Mode (h1,h2,h3,h4,p1,p2
             *    227 Entering Passive Mode. h1,h2,h3,h4,p1,p2
             *    227 =h1,h2,h3,h4,p1,p2
             */
            char *paren;
            paren = strchr(ftpMsg, '(');
            if (paren) {
                req = paren + 1;
            } else {
                /* PASV command without ( */
                req = ftpMsg + 3;
            }
        }
    }

    if (req == NULL) {
        /* Not a PORT/PASV control packet */
        return NDIS_STATUS_SUCCESS;
    }

    UINT32 arr[6] = {0};
    status = OvsCtExtractNumbers(req, len, arr, 6, ',');

    if (status != NDIS_STATUS_SUCCESS) {
        return status;
    }

    UINT32 ip = ntohl((arr[0] << 24) | (arr[1] << 16) |
                      (arr[2] << 8) | arr[3]);
    UINT16 port = ntohs(((arr[4] << 8) | arr[5]));

    switch (ftpType) {
    case FTP_TYPE_PASV:
        /* Ensure that the command states Server's IP address */
        ASSERT(ip == key->ipKey.nwSrc);

        OvsCtRelatedEntryCreate(key->ipKey.nwProto,
                                key->l2.dlType,
                                /* Server's IP */
                                ip,
                                /* Use intended client's IP */
                                key->ipKey.nwDst,
                                /* Dynamic port opened on server */
                                port,
                                /* We don't know the client port */
                                0,
                                currentTime,
                                entry);
        break;
    case FTP_TYPE_ACTIVE:
        OvsCtRelatedEntryCreate(key->ipKey.nwProto,
                                key->l2.dlType,
                                /* Server's default IP address */
                                key->ipKey.nwDst,
                                /* Client's IP address */
                                ip,
                                /* FTP Data Port is 20 */
                                ntohs(IPPORT_FTP_DATA),
                                /* Port opened up on Client */
                                port,
                                currentTime,
                                entry);
        break;
    default:
        OVS_LOG_ERROR("invalid ftp type:%d", ftpType);
        status = NDIS_STATUS_INVALID_PARAMETER;
        break;
    }

    return status;
}