/* *=========================================================================== * ipcom_drv_eth_filter_add_mcast_addr *=========================================================================== * Description: Adds a multicast Ethernet address that should be passed * by the filter. * Parameters: filter - A filter to where the address should be added. * eth_mcast_addr - The address to add. * Returns: 0 = success, <0 = error code. * */ IP_PUBLIC int ipcom_drv_eth_filter_add_mcast_addr(Ipcom_drv_eth_filter *filter, Ip_u8 eth_mcast_addr[IPCOM_DRV_ETH_ADDR_SIZE]) { int i; int insert = -1; for (i = IPCOM_DRV_ETH_MAX_MULTIADDR - 1; i >= 0 ; i--) { if (filter->ref[i] == 0) insert = i; else { if (ipcom_memcmp(eth_mcast_addr, filter->mcast_addr[i], IPCOM_DRV_ETH_ADDR_SIZE) == 0) { filter->ref[i]++; return 0; } } } if (insert < 0) /* Cannot join any more Ethernet multicast addresses */ return -IP_ERRNO_ENOSPC; /* Add this multicast address */ filter->ref[insert] = 1; ipcom_memcpy(filter->mcast_addr[insert], eth_mcast_addr, IPCOM_DRV_ETH_ADDR_SIZE); return 0; }
/* *=========================================================================== * ipnet_nat_proxy_sip_keyfind *=========================================================================== * Description: Find a string in a structured message. * This routine searches a string in a structured message. * It assumes the searched string always starts at the beginning * of each line of data terminated by \r\n characters. A message * should be terminated by \r\n preceded by the line terminator * \r\n. * Parameters: pdata - pointer to message. * pstr - key to look for. * ppos - found string position relative to pdata. * searchlen - searchlen. * Returns: IP_TRUE = found key. * IP_FALSE = key not found. */ IP_STATIC Ip_bool ipnet_nat_proxy_sip_keyfind(char *pdata, char *pstr, int *ppos, int searchlen) { char *pstart = pdata; int i = 0; if (!searchlen) searchlen = 1000; /* max default search length */ while (IP_TRUE) { if (pstr) { /* skip all space */ while (*pdata == ' ') pdata++; if (ipcom_memcmp(pdata, pstr, ipcom_strlen(pstr)) == 0) break; } /* advance to next line */ for (i = 0; i < (searchlen - 1); i++) { if (pdata[i] == '\r') if (pdata[i+1] == '\n') break; } if (i >= (searchlen - 1)) { IPCOM_LOG1(ERR, "ipnet_nat_proxy_sip_keyfind() :: single message exceeds max len: %d", searchlen); *ppos = searchlen; /* reaches the end */ return IP_FALSE; } pdata += i + 2; searchlen -= (i + 2); if ((pdata[0] == '\r' && pdata[1] == '\n') || (searchlen <= 0)) { /* reach the end mark \r\n\r\n */ if (searchlen) pdata += 2; *ppos = pdata - pstart; return (pstr ? IP_FALSE : IP_TRUE); } } *ppos = pdata - pstart; return IP_TRUE; }
/* *=========================================================================== * ipcom_drv_eth_filter_pkt_to_me *=========================================================================== * Description: Returns if this packet was sent to this node. * Parameters: filter - The current filter for this interface. * frame - An Ethernet frame. * Returns: IP_TRUE if this packet was sent to this node. * */ IP_PUBLIC Ip_bool ipcom_drv_eth_filter_pkt_to_me(Ipcom_drv_eth_filter *filter, Ipcom_eth_hdr *frame) { int i; if (filter->promisc) /* Driver in software-promiscuous mode, accept all packets. */ return IP_TRUE; if (frame->dst[0] == 0xFF) /* Ethernet broadcast is always accepted */ return IP_TRUE; if (IP_BIT_ISFALSE(frame->dst[0], 0x01)) { /* Unicast packet */ if (ipcom_memcmp(filter->unicast_addr, frame->dst, IPCOM_DRV_ETH_ADDR_SIZE) != 0) /* Not my MAC address */ return IP_FALSE; #ifdef IPCOM_USE_INET if (filter->in_block_addr.s_addr && ip_ntohs(frame->type) == 0x0800 && ipcom_memcmp(&filter->in_block_addr, &frame->data[16], 4) == 0) /*lint !e416 !e420 */ return IP_FALSE; #endif return IP_TRUE; } /* Check multicast groups */ for (i = 0; i < IPCOM_DRV_ETH_MAX_MULTIADDR; i++) if (filter->ref[i] != 0 && ipcom_memcmp(filter->mcast_addr[i], frame->dst, IPCOM_DRV_ETH_ADDR_SIZE) == 0) return IP_TRUE; /* This multicast frame was not sent to this interface */ return IP_FALSE; }
/* *=========================================================================== * ipcom_drv_eth_filter_remove_mcast_addr *=========================================================================== * Description: Removes a multicast Ethernet address that should be passed * by the filter. * Parameters: filter - A filter from where the address should be removed. * eth_mcast_addr - The address to remove. * Returns: 0 = success, <0 = error code. * */ IP_PUBLIC int ipcom_drv_eth_filter_remove_mcast_addr(Ipcom_drv_eth_filter *filter, Ip_u8 eth_mcast_addr[IPCOM_DRV_ETH_ADDR_SIZE]) { int i; for (i = 0; i < IPCOM_DRV_ETH_MAX_MULTIADDR; i++) { if (filter->ref[i] != 0 && ipcom_memcmp(eth_mcast_addr, filter->mcast_addr[i], IPCOM_DRV_ETH_ADDR_SIZE) == 0) { /* Address found */ if (--filter->ref[i] == 0) /* Last reference, remove the address */ ipcom_memset(filter->mcast_addr[i], 0, IPCOM_DRV_ETH_ADDR_SIZE); return 0; } } /* Unknown address */ return -IP_ERRNO_EADDRNOTAVAIL; }
/* *=========================================================================== * ipsecctrl_flows *=========================================================================== */ static int ipsecctrl_flows(Argvars *vars) { Ipipsec_ctrl_selector sel; char srcport[32], dstport[32]; int num = 0; char str[IP_INET6_ADDRSTRLEN]; char str2[IP_INET6_ADDRSTRLEN+1]; ipcom_printf("Flows:"IP_LF); sel.Index = 0; /* get first selector. */ /* Get and print the Selectors in MIB format. */ for (;;) { /* Get first/next Selector */ if (ipcom_socketioctl(vars->fd, IP_SIOCXIPSEC_SELECTOR, &sel) < 0) { ipcom_printf("ipsecctrl: ipcom_socketioctl(SELECTOR) failed (%s)"IP_LF, ipcom_strerror(ipcom_errno)); return -1; } if (sel.Index == 0) break; /* Print selector aka flow: */ num++; ipcom_printf("[%ld] :: %s ", sel.Index, FLOW_TYPE(sel.flowtype)); if (sel.flowpri != 0) ipcom_printf("pri=%d ", (signed char)sel.flowpri); /* source */ if (sel.LocalPort != sel.LocalMaxPort) ipcom_sprintf(srcport, "%d-%d", (int)ip_ntohs(sel.LocalPort), (int)ip_ntohs(sel.LocalMaxPort)); else if (sel.LocalPort == 0) ipcom_strcpy(srcport, "any"); else ipcom_sprintf(srcport, "%d", (int)ip_ntohs(sel.LocalPort)); if (ipcom_memcmp(&sel.LocalId, &sel.LocalMaxId, sizeof(union Ip_in_addr_union))) ipcom_sprintf(str2, "-%s", ipcom_inet_ntop(sel.domain, &sel.LocalMaxId, str, sizeof(str))); else *str2 = '\0'; ipcom_printf("src=%s%s/%d:%s ", ipcom_inet_ntop(sel.domain, &sel.LocalId, str, sizeof(str)), str2, ipipsec_addrmasklen(sel.domain, (Ip_u8 *)&sel.local_mask), srcport); /* destination */ if (sel.RemotePort != sel.RemoteMaxPort) ipcom_sprintf(dstport, "%d-%d", (int)ip_ntohs(sel.RemotePort), (int)ip_ntohs(sel.RemoteMaxPort)); else if (sel.RemotePort == 0) ipcom_strcpy(dstport, "any"); else ipcom_sprintf(dstport, "%d", (int)ip_ntohs(sel.RemotePort)); if (ipcom_memcmp(&sel.RemoteId, &sel.RemoteMaxId, sizeof(union Ip_in_addr_union))) ipcom_sprintf(str2, "-%s", ipcom_inet_ntop(sel.domain, &sel.RemoteMaxId, str, sizeof(str))); else *str2 = '\0'; ipcom_printf("dst=%s%s/%d:%s ", ipcom_inet_ntop(sel.domain, &sel.RemoteId, str, sizeof(str)), str2, ipipsec_addrmasklen(sel.domain, (Ip_u8 *)&sel.remote_mask), dstport); ipcom_printf("%s", ipcom_ipproto_name(sel.Protocol)); switch (sel.Protocol) { case IP_IPPROTO_ICMP: case IP_IPPROTO_ICMPV6: if (sel.ports[0] || sel.ports[1]) ipcom_printf(" type=%d code=%d", sel.ports[0], sel.ports[1]); break; case IP_IPPROTO_MH: if (sel.ports[0]) ipcom_printf(" type=%d", sel.ports[0]); break; default: break; } /* Print SA */ if (sel.sa.domain) { if (sel.sa.domain == IPIPSEC_AF_BYPASS) ipcom_printf(" %s SA: %s", sel.direction == IPIPSEC_SADIR_INPUT ? "<-" : sel.direction == IPIPSEC_SADIR_OUTPUT ? "->" : "--", IPSECSATYPENAME(sel.sa.satype)); else ipcom_printf(" %s SA: %s spi=0x%lx src=%s dst=%s", sel.direction == IPIPSEC_SADIR_INPUT ? "<-" : sel.direction == IPIPSEC_SADIR_OUTPUT ? "->" : "--", IPSECSATYPENAME(sel.sa.satype), ip_ntohl(sel.sa.spi_n), ipcom_inet_ntop(sel.sa.domain, &sel.sa.src, str, sizeof(str)), ipcom_inet_ntop(sel.sa.domain, &sel.sa.dst, str2, sizeof(str2))); } else ipcom_printf(" %s SA: none", sel.direction == IPIPSEC_SADIR_INPUT ? "<-" : sel.direction == IPIPSEC_SADIR_OUTPUT ? "->" : "--"); ipcom_printf(IP_LF); } ipcom_printf("Total of %d flows."IP_LF, num); return 0; }