Open Ethernet Networking (OpEN) API Guide and Reference Manual  3.6.0.3
acl_pkt_cap.c
/*********************************************************************
*
* Copyright 2016-2018 Broadcom.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************
*
* @filename rx_packet_example.c
*
* @purpose Example for Packet receive funcationality using TCAM API
*
* @detail Example application that uses the OpEN API to insert
* various policies in the TCAM and sets up to receives those packets.
*
* @component TCAM API Example
*
* @note none
* @end
*
**********************************************************************/
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "rpcclt_openapi.h"
#include "proc_util.h"
#include "openapi_common.h"
#include "openapi_tcam.h"
#define REDIRECT_NOT_MIRROR 0
#define PRINTSANITYRESULTS(result, test, msg, feat) \
if (result==OPEN_E_UNAVAIL) { printf("Sanity test skipped.\n"); } \
else if ((result==OPEN_E_NONE) && (test)) { printf("Sanity Success - %s - %s.\n", msg, feat); } \
else { printf("Sanity Failure - %s - %s.\n", msg, feat); }
#define PRINTBADRESULT(result, msg) \
if (result==OPEN_E_UNAVAIL) { printf("Feature not supported - %s (err %d).\n", msg, result); } \
else if (result!=OPEN_E_NONE) { printf("Test Failure - %s (err %d).\n", msg, result); }
#define TCAM_MAX_STR_LENGTH 256
#define MACADDR_STR_LEN 18
#define PKT_SIZE 96
int isprint ( int c );
/*****************************************************************/
open_error_t pktCapValidateMac(char *macStr)
{
uint32_t value, tst[6];
value = sscanf(macStr, "%x:%x:%x:%x:%x:%x",
&tst[0], &tst[1], &tst[2], &tst[3], &tst[4], &tst[5]);
if (6 == value)
{
result = OPEN_E_NONE;
for (value = 0; value < 6; value++)
{
if (tst[value] > 255)
{
result = OPEN_E_ERROR;
break;
}
}
}
return result;
}
/*****************************************************************/
void pktCapPktDump(char *pkt, uint32_t len)
{
int row, column;
char c, buf[100];
uint32_t row_count, temp_len;
printf("======================================\n");
if (len < PKT_SIZE)
{
temp_len = len;
}
else
{
temp_len = PKT_SIZE;
}
row_count = temp_len / 16;
if (temp_len % 16)
{
row_count++;
}
for (row = 0; row < row_count; row++)
{
buf[0] = 0;
sprintf(&buf[strlen(buf)], "%02x ", row * 16);
for (column = 0; (column < 8) && ((row * 16 + column) < temp_len); column++)
{
sprintf(&buf[strlen(buf)], "%2.2x ", pkt[row * 16 + column]);
}
sprintf(&buf[strlen(buf)], " ");
for ( ; (column < 16) && ((row * 16 + column) < temp_len); column++)
{
sprintf(&buf[strlen(buf)], "%2.2x ", pkt[row * 16 + column]);
}
for ( ; column < 16; column++)
{
strcat(buf, " ");
}
sprintf(&buf[strlen(buf)], " ");
for (column = 0; (column < 16) && ((row * 16 + column) < temp_len); column++)
{
c = pkt[row * 16 + column];
if (isprint(c))
{
sprintf(&buf[strlen(buf)], "%c", c);
}
else
{
sprintf(&buf[strlen(buf)], ".");
}
}
printf("%s\n", buf);
}
printf("======================================\n");
}
/*****************************************************************/
void pktCapAclReceivePackets(uint32_t agentNum, uint32_t packetCount)
{
uint32_t pktCount, offset, bytesRcvd;
int sockfd = -1;
int maxfd, stdinfd, fd;
open_buffdesc agentNameBuff;
char agentName[] = "Test Agent";
unsigned char buffer[OPEN_TXRX_MAX_FRAME_SIZE + 64];
fd_set readfds, masterfds;
struct timeval timeout;
int timed;
agentNameBuff.pstart = agentName;
agentNameBuff.size = sizeof(agentName);
if (rc != OPEN_E_NONE)
{
printf("Failed to register as rx agent: %d\n", rc);
return;
}
/* Create the socket end-point to receive frames */
if (l7proc_extagentpkt_rxsockcreate(agentNum, &sockfd) != 0)
{
return;
}
printf("Waiting for packets. Press 'q'+<cr> to quit ...\n");
sleep(1);
/* Child*/
pktCount = 0;
while (pktCount < packetCount)
{
memset(buffer, 0, sizeof(buffer));
timeout.tv_sec = 100; /*set the timeout to 100 seconds*/
timeout.tv_usec = 0;
FD_ZERO(&masterfds);
FD_SET(sockfd, &masterfds); /* monitor the socket */
maxfd = stdinfd = fileno(stdin);
FD_SET(stdinfd, &masterfds); /* monitor stdin */
if (sockfd > maxfd)
{
maxfd = sockfd;
}
memcpy(&readfds, &masterfds, sizeof(fd_set));
timed = 1;
if (select(maxfd+1, &readfds, NULL, NULL, &timeout) < 0)
{
if (EINTR == errno)
{
continue;
}
perror("on select");
exit(1);
}
/* check which fd is avaialble for read */
for (fd = 0; fd <= maxfd; fd++)
{
if (FD_ISSET(fd, &readfds))
{
if (fd == stdinfd)
{
timed = 0;
fgets((char *)buffer, sizeof(buffer), stdin);
if ('q' == buffer[0])
{
printf(" Quit!\n");
pktCount = packetCount; /* to break the loop */
break;
}
}
else if (fd == sockfd)
{
timed = 0;
/* read from the socket */
do
{
bytesRcvd = recvfrom(sockfd, buffer, sizeof(buffer), 0, 0, 0);
} while ((bytesRcvd < 0) && (EINTR == errno));
if (bytesRcvd <= 0)
{
continue;
}
pktCount++;
pktDesc = (open_sysExtAgentPktRxDesc_t *)buffer;
printf("Packet %d Received from ifNum %d, pktLen %d\n",
pktCount, pktDesc->rxIfNum, pktDesc->pktLength);
offset = pktDesc->descLen;
pktCapPktDump((char *)&buffer[offset], pktDesc->pktLength);
}
else
{
printf("Unknown FD\n\n");
}
}
}
if (timed)
{
printf("Timeout\n");
pktCount = packetCount; /* to break the loop */
break;
}
} /* while (pktCount < packetCount) */
l7proc_extagentpkt_rxsockclose(agentNum, sockfd);
exit(0);
return;
}
/*****************************************************************/
open_error_t pktCapAclCreate(openapiClientHandle_t *clientHandle,
OPEN_ACL_TYPE_t aclType,
char *aclName, uint32_t *aclId)
{
open_buffdesc aclDesc;
char str[32];
uint32_t tmp1, tmp2;
strcpy(str, aclName);
aclDesc.pstart = str;
aclDesc.size = strlen(str) + 1;
/* start fresh */
openapiAclDeleteByName(clientHandle, aclType, &aclDesc);
result = openapiAclCreate(clientHandle, aclType, &aclDesc, &tmp1);
PRINTBADRESULT(result, "openapiAclCreate");
if (result == OPEN_E_NONE)
{
result = openapiAclGet(clientHandle, aclType, &aclDesc, &tmp2);
PRINTBADRESULT(result, "openapiAclGet");
}
PRINTSANITYRESULTS(result, tmp1==tmp2, __func__, "");
*aclId = tmp2;
return (result);
}
/*****************************************************************/
open_error_t pktCapAclMacRules(openapiClientHandle_t *clientHandle,
uint32_t agentCookie, uint32_t aclId,
char *macStr, char *macMaskStr,
uint32_t isSrcRule, uint32_t *aclRule)
{
open_buffdesc macDesc;
open_buffdesc macMaskDesc;
uint32_t temp;
char buff[80];
char tmpMacStr[MACADDR_STR_LEN];
char tmpMaskStr[MACADDR_STR_LEN];
macDesc.pstart = macStr;
macDesc.size = strlen(macStr)+1;
macMaskDesc.pstart = macMaskStr;
macMaskDesc.size = strlen(macMaskStr)+1;
if (0 == *aclRule)
{
/* Create a Permit action rule */
{
result = openapiAclRuleActionAdd(clientHandle, aclId, aclRule, OPEN_ACL_PERMIT);
PRINTBADRESULT(result, "openapiAclRuleActionAdd - PERMIT");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleActionGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleActionGet - PERMIT");
PRINTSANITYRESULTS(result, OPEN_ACL_PERMIT==temp, __func__, "PERMIT");
}
}
/* Add match criteria - destination address and prefix */
}
if (isSrcRule)
{
result = openapiAclRuleMatchMacSrcMacAdd(clientHandle, aclId, *aclRule, &macDesc, &macMaskDesc);
PRINTBADRESULT(result, "openapiAclRuleMatchMacSrcMacAdd");
memset(&tmpMacStr, 0, MACADDR_STR_LEN);
memset(&tmpMaskStr, 0, MACADDR_STR_LEN);
macDesc.pstart = tmpMacStr;
macDesc.size = MACADDR_STR_LEN;
macMaskDesc.pstart = tmpMaskStr;
macMaskDesc.size = MACADDR_STR_LEN;
result = openapiAclRuleMatchMacSrcMacGet(clientHandle, aclId, *aclRule, &macDesc, &macMaskDesc);
PRINTBADRESULT(result, "openapiAclRuleMatchMacSrcMacGet");
if (result == OPEN_E_NONE)
{
PRINTSANITYRESULTS(result,
((strcmp(macDesc.pstart, macStr) == 0) &&
(strcmp(macMaskDesc.pstart, macMaskStr) == 0)),
__func__, "Source MAC Address/Mask");
printf("Source MAC Address/Mask: %s/%s\n", macStr, macMaskStr);
}
}
else
{
result = openapiAclRuleMatchMacDstMacAdd(clientHandle, aclId, *aclRule, &macDesc, &macMaskDesc);
PRINTBADRESULT(result, "openapiAclRuleMatchMacDstMacAdd");
memset(&tmpMacStr, 0, MACADDR_STR_LEN);
memset(&tmpMaskStr, 0, MACADDR_STR_LEN);
macDesc.pstart = tmpMacStr;
macDesc.size = MACADDR_STR_LEN;
macMaskDesc.pstart = tmpMaskStr;
macMaskDesc.size = MACADDR_STR_LEN;
result = openapiAclRuleMatchMacDstMacGet(clientHandle, aclId, *aclRule, &macDesc, &macMaskDesc);
PRINTBADRESULT(result, "openapiAclRuleMatchMacDstMacGet");
if (result == OPEN_E_NONE)
{
PRINTSANITYRESULTS(result,
((strcmp(macDesc.pstart, macStr) == 0) &&
(strcmp(macMaskDesc.pstart, macMaskStr) == 0)),
__func__, "Destination MAC Address/Mask");
printf("Destination MAC Address/Mask: %s/%s\n", macStr, macMaskStr);
}
}
/* Add match criteria - Packet Mirroring or Packet Redirection
*/
{
#if REDIRECT_NOT_MIRROR
result = openapiAclRuleMatchRedirectAgentAdd(clientHandle, aclId, *aclRule, agentCookie);
PRINTBADRESULT(result, "openapiAclRuleMatchRedirectAgentAdd");
#else
result = openapiAclRuleMatchMirrorAgentAdd(clientHandle, aclId, *aclRule, agentCookie);
PRINTBADRESULT(result, "openapiAclRuleMatchMirrorAgentAdd");
#endif
if (result == OPEN_E_NONE)
{
#if REDIRECT_NOT_MIRROR
result = openapiAclRuleMatchRedirectAgentGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleMatchRedirectGet");
sprintf(buff, "Packet Redirect to Extenal Agent: %d", temp);
#else
result = openapiAclRuleMatchMirrorAgentGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleMatchMirrorAgentGet");
sprintf(buff, "Packet Mirror to Extenal Agent: %d", temp);
#endif
}
if (result == OPEN_E_NONE)
{
PRINTSANITYRESULTS(result, (agentCookie == temp), __func__, buff);
}
}
return result;
}
/*****************************************************************/
open_error_t pktCapAclIpRules(openapiClientHandle_t *clientHandle,
uint32_t agentCookie, uint32_t aclId,
uint32_t isSrcRule, uint32_t *aclRule)
{
uint32_t temp;
char buff[80];
if (0 == *aclRule)
{
/* Create a Permit action rule */
{
result = openapiAclRuleActionAdd(clientHandle, aclId, aclRule, OPEN_ACL_PERMIT);
PRINTBADRESULT(result, "openapiAclRuleActionAdd - PERMIT");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleActionGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleActionGet - PERMIT");
PRINTSANITYRESULTS(result, OPEN_ACL_PERMIT==temp, __func__, "PERMIT");
}
}
/* Add match criteria - IP Any protocol */
{
result = openapiAclRuleMatchProtocolAdd(clientHandle, aclId, *aclRule, OPENAPI_ACL_PROTOCOL_IP);
PRINTBADRESULT(result, "openapiAclRuleMatchProtocolAdd");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchProtocolGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleMatchProtocolGet");
PRINTSANITYRESULTS(result, OPENAPI_ACL_PROTOCOL_IP==temp, __func__, "IP Protocol");
}
}
}
/* Add match criteria - destination address and prefix */
if (isSrcRule)
{
result = openapiAclRuleMatchIpSrcMaskAdd(clientHandle, aclId, *aclRule, ipAddr, maskAddr);
PRINTBADRESULT(result, "openapiAclRuleMatchIpSrcMaskAdd");
memset(&ipAddr, 0, sizeof(ipAddr));
memset(&maskAddr, 0, sizeof(maskAddr));
result = openapiAclRuleMatchIpSrcMaskGet(clientHandle, aclId, *aclRule, &ipAddr, &maskAddr);
PRINTBADRESULT(result, "openapiAclRuleMatchIpSrcMaskGet");
if (result == OPEN_E_NONE)
{
open_buffdesc ipDesc;
open_buffdesc maskDesc;
char ipDescStr[32];
char maskDescStr[32];
ipDesc.pstart = ipDescStr;
ipDesc.size = sizeof(ipDescStr)-1;
maskDesc.pstart = maskDescStr;
maskDesc.size = sizeof(maskDescStr)-1;
(void)openapiOpenIPtoStringGet(clientHandle, ipAddr, &ipDesc);
(void)openapiOpenIPtoStringGet(clientHandle, maskAddr, &maskDesc);
printf("Source IPv4 Address/Mask: %s/%s\n", (char *)ipDesc.pstart, (char *)maskDesc.pstart);
}
}
else
{
result = openapiAclRuleMatchIpDstMaskAdd(clientHandle, aclId, *aclRule, ipAddr, maskAddr);
PRINTBADRESULT(result, "openapiAclRuleMatchIpDstMaskAdd");
memset(&ipAddr, 0, sizeof(ipAddr));
memset(&maskAddr, 0, sizeof(maskAddr));
result = openapiAclRuleMatchIpDstMaskGet(clientHandle, aclId, *aclRule, &ipAddr, &maskAddr);
PRINTBADRESULT(result, "openapiAclRuleMatchIpDstMaskGet");
if (result == OPEN_E_NONE)
{
open_buffdesc ipDesc;
open_buffdesc maskDesc;
char ipDescStr[32];
char maskDescStr[32];
ipDesc.pstart = ipDescStr;
ipDesc.size = sizeof(ipDescStr)-1;
maskDesc.pstart = maskDescStr;
maskDesc.size = sizeof(maskDescStr)-1;
(void)openapiOpenIPtoStringGet(clientHandle, ipAddr, &ipDesc);
(void)openapiOpenIPtoStringGet(clientHandle, maskAddr, &maskDesc);
printf("Destination IPv4 Address/Mask: %s/%s\n", (char *)ipDesc.pstart, (char *)maskDesc.pstart);
}
}
/* Add match criteria - Packet Mirroring or Packet Redirection
*/
{
#if REDIRECT_NOT_MIRROR
result = openapiAclRuleMatchRedirectAgentAdd(clientHandle, aclId, *aclRule, agentCookie);
PRINTBADRESULT(result, "openapiAclRuleMatchRedirectAgentAdd");
#else
result = openapiAclRuleMatchMirrorAgentAdd(clientHandle, aclId, *aclRule, agentCookie);
PRINTBADRESULT(result, "openapiAclRuleMatchMirrorAgentAdd");
#endif
if (result == OPEN_E_NONE)
{
#if REDIRECT_NOT_MIRROR
result = openapiAclRuleMatchRedirectAgentGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleMatchRedirectGet");
sprintf(buff, "Packet Redirect to Extenal Agent: %d", temp);
#else
result = openapiAclRuleMatchMirrorAgentGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleMatchMirrorAgentGet");
sprintf(buff, "Packet Mirror to Extenal Agent: %d", temp);
#endif
}
if (result == OPEN_E_NONE)
{
PRINTSANITYRESULTS(result, (agentCookie == temp), __func__, buff);
}
}
return result;
}
/*****************************************************************/
open_error_t pktCapAclOddBallRules(openapiClientHandle_t *clientHandle,
uint32_t agentCookie, uint32_t aclId,
uint32_t *aclRule)
{
uint32_t temp;
char buff[80];
{
*aclRule = 0;
/* permit icmp any any mirrorExtAgent # */
{
result = openapiAclRuleActionAdd(clientHandle, aclId, aclRule, OPEN_ACL_PERMIT);
PRINTBADRESULT(result, "openapiAclRuleActionAdd - PERMIT");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleActionGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleActionGet - PERMIT");
PRINTSANITYRESULTS(result, OPEN_ACL_PERMIT==temp, __func__, "PERMIT");
}
}
/* Add match criteria - ICMP */
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchProtocolAdd(clientHandle, aclId, *aclRule, OPENAPI_ACL_PROTOCOL_ICMP);
PRINTBADRESULT(result, "openapiAclRuleMatchProtocolAdd");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchProtocolGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleMatchProtocolGet");
PRINTSANITYRESULTS(result, OPENAPI_ACL_PROTOCOL_ICMP==temp, __func__, "ICMP Protocol");
}
}
/* Add action criteria - Packet Mirror external Agent */
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchMirrorAgentAdd(clientHandle, aclId, *aclRule, agentCookie);
PRINTBADRESULT(result, "openapiAclRuleMatchMirrorAgentAdd");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchMirrorAgentGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleMatchMirrorAgentGet");
sprintf(buff, "Packet Mirror to Extenal Agent: %d", temp);
PRINTSANITYRESULTS(result, (agentCookie == temp), __func__, buff);
}
}
}
if (result == OPEN_E_NONE)
{
*aclRule = 0;
/* permit tcp any any flag +fin +syn mirrorExtAgent */
{
result = openapiAclRuleActionAdd(clientHandle, aclId, aclRule, OPEN_ACL_PERMIT);
PRINTBADRESULT(result, "openapiAclRuleActionAdd - PERMIT");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleActionGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleActionGet - PERMIT");
PRINTSANITYRESULTS(result, OPEN_ACL_PERMIT==temp, __func__, "PERMIT");
}
}
/* Add match criteria - TCP */
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchProtocolAdd(clientHandle, aclId, *aclRule, OPENAPI_ACL_PROTOCOL_TCP);
PRINTBADRESULT(result, "openapiAclRuleMatchProtocolAdd");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchProtocolGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleMatchProtocolGet");
PRINTSANITYRESULTS(result, OPENAPI_ACL_PROTOCOL_TCP==temp, __func__, "TCP Protocol");
}
}
/* Add match criteria - TCP Flags */
{
uint32_t flagVal=0, flagMask=0;
uint32_t tmpVal, tmpMask;
/* Set Finish flag */
flagMask |= (true << OPENAPI_ACL_TCP_FLAG_FIN);
flagVal |= (true << OPENAPI_ACL_TCP_FLAG_FIN);
/* Set Synchronize flag */
flagMask |= (true << OPENAPI_ACL_TCP_FLAG_SYN);
flagVal |= (true << OPENAPI_ACL_TCP_FLAG_SYN);
result = openapiAclRuleMatchTcpFlagsAdd(clientHandle, aclId, *aclRule, flagVal, flagMask);
PRINTBADRESULT(result, "openapiAclRuleMatchTcpFlagsAdd");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchTcpFlagsGet(clientHandle, aclId, *aclRule, &tmpVal, &tmpMask);
PRINTBADRESULT(result, "openapiAclRuleMatchTcpFlagsGet");
PRINTSANITYRESULTS(result, ((flagVal==tmpVal)&&(flagMask==tmpMask)), __func__, "Oddball TCP Flags test");
}
}
/* Add action criteria - Packet Mirror external Agent */
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchMirrorAgentAdd(clientHandle, aclId, *aclRule, agentCookie);
PRINTBADRESULT(result, "openapiAclRuleMatchMirrorAgentAdd");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchMirrorAgentGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleMatchMirrorAgentGet");
sprintf(buff, "Packet Mirror to Extenal Agent: %d", temp);
PRINTSANITYRESULTS(result, (agentCookie == temp), __func__, buff);
}
}
}
if (result == OPEN_E_NONE)
{
*aclRule = 0;
/* permit udp any eq domain any eq domain mirrorExtAgent */
{
result = openapiAclRuleActionAdd(clientHandle, aclId, aclRule, OPEN_ACL_PERMIT);
PRINTBADRESULT(result, "openapiAclRuleActionAdd - PERMIT");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleActionGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleActionGet - PERMIT");
PRINTSANITYRESULTS(result, OPEN_ACL_PERMIT==temp, __func__, "PERMIT");
}
}
/* Add match criteria - UDP */
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchProtocolAdd(clientHandle, aclId, *aclRule, OPENAPI_ACL_PROTOCOL_UDP);
PRINTBADRESULT(result, "openapiAclRuleMatchProtocolAdd");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchProtocolGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleMatchProtocolGet");
PRINTSANITYRESULTS(result, OPENAPI_ACL_PROTOCOL_UDP==temp, __func__, "UDP Protocol");
}
}
/* Add match criteria - Source Layer 4 port 53 */
{
uint32_t tmpStartPort;
uint32_t tmpEndPort;
result = openapiAclRuleMatchL4SrcPortAdd(clientHandle, aclId, *aclRule,
PRINTBADRESULT(result, "openapiAclRuleMatchL4SrcPortAdd");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchL4SrcPortGet(clientHandle, aclId, *aclRule, &tmpOper,
&tmpStartPort, &tmpEndPort);
PRINTBADRESULT(result, "openapiAclRuleMatchL4SrcPortGet");
PRINTSANITYRESULTS(result,
__func__, "Source Layer 4 port 53");
}
}
/* Add match criteria - Destination Layer 4 port 53 */
{
uint32_t tmpStartPort;
uint32_t tmpEndPort;
result = openapiAclRuleMatchL4DstPortAdd(clientHandle, aclId, *aclRule,
PRINTBADRESULT(result, "openapiAclRuleMatchL4DstPortAdd");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchL4DstPortGet(clientHandle, aclId, *aclRule, &tmpOper,
&tmpStartPort, &tmpEndPort);
PRINTBADRESULT(result, "openapiAclRuleMatchL4DstPortGet");
PRINTSANITYRESULTS(result,
__func__, "Source Layer 4 port 53");
}
}
/* Add action criteria - Packet Mirror external Agent */
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchMirrorAgentAdd(clientHandle, aclId, *aclRule, agentCookie);
PRINTBADRESULT(result, "openapiAclRuleMatchMirrorAgentAdd");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchMirrorAgentGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleMatchMirrorAgentGet");
sprintf(buff, "Packet Mirror to Extenal Agent: %d", temp);
PRINTSANITYRESULTS(result, (agentCookie == temp), __func__, buff);
}
}
}
return result;
}
/*****************************************************************/
open_error_t pktCapAclPermitRules(openapiClientHandle_t *clientHandle,
uint32_t aclId, uint32_t *aclRule)
{
uint32_t temp;
/* Create a Permit action rule */
{
result = openapiAclRuleActionAdd(clientHandle, aclId, aclRule, OPEN_ACL_PERMIT);
PRINTBADRESULT(result, "openapiAclRuleActionAdd - PERMIT");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleActionGet(clientHandle, aclId, *aclRule, &temp);
PRINTBADRESULT(result, "openapiAclRuleActionGet - PERMIT");
PRINTSANITYRESULTS(result, OPEN_ACL_PERMIT==temp, __func__, "PERMIT");
}
}
/* Add match criteria - IP Any protocol */
{
result = openapiAclRuleMatchEveryAdd(clientHandle, aclId, *aclRule, OPEN_TRUE);
PRINTBADRESULT(result, "openapiAclRuleMatchEveryAdd");
if (result == OPEN_E_NONE)
{
result = openapiAclRuleMatchEveryGet(clientHandle, aclId, *aclRule, (bool *)&temp);
PRINTBADRESULT(result, "openapiAclRuleMatchEveryGet");
PRINTSANITYRESULTS(result, (uint32_t)OPEN_TRUE==temp, __func__, "Every");
}
}
return result;
}
/*****************************************************************/
open_error_t pktCapAclAddClassifiers(openapiClientHandle_t *clientHandle,
uint32_t agentCookie, OPEN_BOOL_t allRule,
uint32_t *aclId)
{
uint32_t response;
uint32_t value;
char strSubnetMask[TCAM_MAX_STR_LENGTH];
char strIpaddr[TCAM_MAX_STR_LENGTH];
uint32_t aclRule;
open_inet_addr_t ipDstAddr, ipSrcAddr;
open_inet_addr_t maskDstIp, maskSrcIp;
char matchDstMac[TCAM_MAX_STR_LENGTH], matchSrcMac[TCAM_MAX_STR_LENGTH];
char maskDstMac[TCAM_MAX_STR_LENGTH], maskSrcMac[TCAM_MAX_STR_LENGTH];
uint16_t matchEthType;
open_buffdesc buffDesc;
OPEN_BOOL_t isDstMac = OPEN_FALSE;
OPEN_BOOL_t isSrcMac = OPEN_FALSE;
printf("This selection will create %s ACL.\n",
allRule==OPEN_TRUE?"a simple":"and add simple classifiers to an");
do
{
if (allRule==OPEN_TRUE)
break;
response = 99;
printf("Enter classification type:\n"
"\t1\tto match Dest MAC\n"
"\t2\tto match Src MAC\n"
"\t3\tto match EtherType\n"
"\t4\tto match Dest IPv4 address\n"
"\t5\tto match Src IPv4 address\n"
"\t6\tto match canned oddball IPv4 options\n"
"\t0\tquit \n");
scanf("%d", &response);
/* Classification*/
switch (response)
{
case 1:
memset(matchDstMac, 0, sizeof(matchDstMac));
memset(maskDstMac, 0, sizeof(maskDstMac));
printf("Enter Mac address (i.e. 00:00:04:00:05:00) ");
scanf("%s", matchDstMac);
printf("Enter Mac address mask (i.e. 00:00:00:00:00:07) ");
scanf("%s", maskDstMac);
/* test validity of input */
if (OPEN_E_NONE == pktCapValidateMac(matchDstMac))
{
isDstMac = OPEN_TRUE;
if (OPEN_E_NONE != pktCapValidateMac(maskDstMac))
{
strcpy(maskDstMac, "00:00:00:00:00:00");
printf("Error: Incorrect Input. Using NULL mask: %s\n", maskDstMac);
}
}
else
{
printf("Error: Incorrect Input: %s\n", matchDstMac);
}
break;
case 2:
memset(matchSrcMac, 0, sizeof(matchSrcMac));
memset(maskSrcMac, 0, sizeof(maskSrcMac));
printf("Enter Mac address (i.e. 00:00:04:00:04:00) ");
scanf("%s", matchSrcMac);
printf("Enter Mac address mask (i.e. 00:00:00:00:00:07) ");
scanf("%s", maskSrcMac);
/* test validity of input */
if (OPEN_E_NONE == pktCapValidateMac(matchSrcMac))
{
isSrcMac = OPEN_TRUE;
if (OPEN_E_NONE != pktCapValidateMac(maskSrcMac))
{
strcpy(maskSrcMac, "00:00:00:00:00:00");
printf("Error: Incorrect Input. Using NULL mask: %s\n", maskSrcMac);
}
}
else
{
printf("Error: Incorrect Input: %s\n", matchSrcMac);
}
break;
case 3:
printf("This option is not yet available.\n");
break;
printf("Enter ether type in hex\n");
scanf("%x",&value);
matchEthType = value;
printf("Match EType: %d\n", matchEthType);
break;
case 4:
printf("Enter Dest IP address \n");
scanf("%s", strIpaddr);
buffDesc.pstart = strIpaddr;
buffDesc.size = strlen(strIpaddr) + 1;
if (openapiInetAddrGet(clientHandle, &buffDesc, &ipDstAddr) == OPEN_E_NONE)
{
ipDstAddr.addr.ipv4 = ipDstAddr.addr.ipv4;
printf("Enter Mask \n");
scanf("%s", strSubnetMask);
buffDesc.pstart = strSubnetMask;
buffDesc.size = strlen(strSubnetMask) + 1;
if (openapiInetAddrGet(clientHandle, &buffDesc, &maskDstIp) != OPEN_E_NONE)
{
maskDstIp.family = OPEN_AF_INET;
maskDstIp.addr.ipv4 = 0;
printf("Incorrect Input, using mask 0.0.0.0\n");
}
maskDstIp.addr.ipv4 = maskDstIp.addr.ipv4;
}
else
{
printf("Error: Incorrect Input\n");
break;
}
isDstIp = OPEN_TRUE;
break;
case 5:
printf("Enter Src IP address \n");
scanf("%s", strIpaddr);
buffDesc.pstart = strIpaddr;
buffDesc.size = strlen(strIpaddr) + 1;
if (openapiInetAddrGet(clientHandle, &buffDesc, &ipSrcAddr) == OPEN_E_NONE)
{
ipSrcAddr.addr.ipv4 = ipSrcAddr.addr.ipv4;
printf("Enter Mask \n");
scanf("%s", strSubnetMask);
buffDesc.pstart = strSubnetMask;
buffDesc.size = strlen(strSubnetMask) + 1;
if (openapiInetAddrGet(clientHandle, &buffDesc, &maskSrcIp) != OPEN_E_NONE)
{
maskSrcIp.family = OPEN_AF_INET;
maskSrcIp.addr.ipv4 = 0;
printf("Incorrect Input, using mask 0.0.0.0\n");
}
maskSrcIp.addr.ipv4 = maskSrcIp.addr.ipv4;
}
else
{
printf("Error: Incorrect Input\n");
break;
}
isSrcIp = OPEN_TRUE;
break;
case 6:
oddBall = OPEN_TRUE;
break;
case 0:
default:
response = 0;
}
} while (response != 0);
if (isDstMac || isSrcMac)
{
/* MAC ACL Rule */
result = pktCapAclCreate(clientHandle, OPEN_ACL_TYPE_MAC, "pkt_mirror_mac", aclId);
if (result == OPEN_E_NONE)
{
aclRule = 0;
if (isDstMac)
{
result = pktCapAclMacRules(clientHandle, agentCookie, *aclId, matchDstMac, maskDstMac, 0, &aclRule);
}
if ((isSrcMac) && (result == OPEN_E_NONE))
{
result = pktCapAclMacRules(clientHandle, agentCookie, *aclId, matchSrcMac, maskSrcMac, 1, &aclRule);
}
}
}
else if (isDstIp || isSrcIp)
{
/* IP ACL Rule */
result = pktCapAclCreate(clientHandle, OPEN_ACL_TYPE_IP, "pkt_mirror_IP", aclId);
if (result == OPEN_E_NONE)
{
aclRule = 0;
if (isDstIp)
{
result = pktCapAclIpRules(clientHandle, agentCookie, *aclId, ipDstAddr, maskDstIp, 0, &aclRule);
}
if ((isSrcIp) && (result == OPEN_E_NONE))
{
result = pktCapAclIpRules(clientHandle, agentCookie, *aclId, ipSrcAddr, maskSrcIp, 1, &aclRule);
}
}
}
else if (oddBall == OPEN_TRUE)
{
printf("\tip access-list odd_ball\n");
printf("\tpermit icmp any any mirrorExtAgent %d\n", agentCookie);
printf("\tpermit tcp any any flag +fin +syn mirrorExtAgent %d\n", agentCookie);
printf("\tpermit udp any eq domain any eq domain mirrorExtAgent %d\n", agentCookie);
printf("\tpermit ip any any\n");
printf("\texit\n");
result = pktCapAclCreate(clientHandle, OPEN_ACL_TYPE_IP, "odd_ball", aclId);
if (result == OPEN_E_NONE)
{
aclRule = 0;
result = pktCapAclOddBallRules(clientHandle, agentCookie, *aclId, &aclRule);
}
}
else
{
result = pktCapAclCreate(clientHandle, OPEN_ACL_TYPE_MAC, "pkt_mirror_all", aclId);
strcpy(matchDstMac, "FF:FF:FF:FF:FF:FF");
strcpy(maskDstMac, "FF:FF:FF:FF:FF:FF");
if (result == OPEN_E_NONE)
{
result = pktCapAclMacRules(clientHandle, agentCookie, *aclId, matchDstMac, maskDstMac, 0, &aclRule);
}
}
if ((result == OPEN_E_NONE) && (0 != aclId))
{
aclRule = 0;
result = pktCapAclPermitRules(clientHandle, *aclId, &aclRule);
if (result == OPEN_E_NONE)
{
printf("ACL %d created.\n", *aclId);
}
}
return result;
}
/*****************************************************************/
void pktCapAclTrafficFilterIntfAdd(openapiClientHandle_t *clientHandle,
uint32_t aclId, uint32_t intf,
uint32_t seqNum)
{
char str[256];
if (result == OPEN_E_NONE)
{
result = openapiAclIntfDirAdd(clientHandle, intf, dir, aclId, seqNum);
PRINTBADRESULT(result, "openapiAclIntfDirAdd");
sprintf(str, "ACL:%d intf:%d dir:%d seq:%d", aclId, intf, dir, seqNum);
PRINTSANITYRESULTS(result, result==OPEN_E_NONE, __func__, str);
}
}
/*****************************************************************/
void pktCapAclShowSummary(openapiClientHandle_t *clientHandle)
{
char str[256];
uint32_t tmp;
printf("\n");
result = openapiAclCountGet(clientHandle, &tmp);
PRINTBADRESULT(result, "openapiAclCountGet");
sprintf(str, "Total number of configured ACLs ... %d", tmp);
PRINTSANITYRESULTS(result, (1==1), "openapiAclCountGet", str);
result = openapiAclMacCountGet(clientHandle, &tmp);
PRINTBADRESULT(result, "openapiAclMacCountGet");
sprintf(str, "Number of configured MAC ACLs ... %d", tmp);
PRINTSANITYRESULTS(result, (1==1), "openapiAclMacCountGet", str);
}
/***************************************************************/
int main (int argc, char **argv)
{
openapiClientHandle_t clientHandle;
open_error_t result;
open_buffdesc switch_os_revision;
char switch_os_revision_string[100];
uint32_t packetCount = 0;
uint32_t agentCookie = 79;
char *intfString;
uint32_t intfNum;
open_buffdesc buffDesc;
if (argc == 2)
{
intfString = argv[1];
}
else if (argc == 3)
{
intfString = argv[1];
packetCount = atoi(argv[2]);
}
else if ((argc == 4) && (0 == strcmp("all", argv[3])))
{
intfString = argv[1];
packetCount = atoi(argv[2]);
allRule = OPEN_TRUE;
}
else if ((argc == 4) && (0 == strcmp("none", argv[3])))
{
intfString = argv[1];
packetCount = atoi(argv[2]);
noRulz = OPEN_TRUE;
}
else
{
printf("\nUsage: %s\tinterface <count> <'all | none'>\nWhere:\n", argv[0]);
printf("\t\t\tinterface\tUSP of a valid physical interface (i.e. 1/0/5).\n");
printf("\t\t\tcount\tCount of the number of packet to capture (optional).\n");
printf("\t\t\t'all'\tTo captures ALL packets.\n");
printf("\t\t\t'none'\tTo predefine rules for capture.\n");
exit (1);
}
l7proc_crashlog_register ();
/* Register with OpEN */
if ((result =
openapiClientRegister ("Packet Capture Example", &clientHandle)) != OPEN_E_NONE)
{
printf ("\nFailed to initialize RPC to OpEN. Exiting (result = %d)\n", result);
exit (2);
}
/* RPC call can fail until server starts. Keep trying */
while (openapiConnectivityCheck (&clientHandle) != OPEN_E_NONE)
{
sleep (1);
}
L7PROC_LOGF (L7PROC_LOG_SEVERITY_INFO, 0, "Starting Packet Capture example application");
printf ("\n");
switch_os_revision.pstart = switch_os_revision_string;
switch_os_revision.size = sizeof (switch_os_revision_string);
if (openapiNetworkOSVersionGet (&clientHandle, &switch_os_revision) == OPEN_E_NONE)
{
printf ("Network OS version = %s\n", switch_os_revision_string);
}
else
{
printf ("Network OS version retrieve error\n");
}
printf ("\n");
/* convert specified interface to an ifNum*/
buffDesc.size = strlen(intfString) + 1;
buffDesc.pstart = intfString;
result = openapiIfNumGet(&clientHandle, &buffDesc, &intfNum);
printf("%s: (%d %d %d)\n", intfString, buffDesc.size, result, intfNum);
if (result != OPEN_E_NONE)
{
printf("Error: Incorrect interface name %s\n", intfString);
}
else
{
uint32_t aclId = 0;
if (noRulz == OPEN_FALSE)
{
if (OPEN_E_NONE == pktCapAclAddClassifiers(&clientHandle, agentCookie, allRule, &aclId))
{
pktCapAclTrafficFilterIntfAdd(&clientHandle, aclId, intfNum, OPEN_ACL_INBOUND_ACL, 5);
}
}
printf("Make sure 'PROTO_API' was selected. Check flex.h.\n");
pktCapAclShowSummary(&clientHandle);
pktCapAclReceivePackets(agentCookie, packetCount);
(void) openapiClientTearDown(&clientHandle);
}
return (int)result;
}