// Stop all L3 switches in the Cedar void L3FreeAllSw(CEDAR *c) { LIST *o; UINT i; // Validate arguments if (c == NULL) { return; } o = NewListFast(NULL); LockList(c->L3SwList); { for (i = 0;i < LIST_NUM(c->L3SwList);i++) { L3SW *s = LIST_DATA(c->L3SwList, i); Insert(o, CopyStr(s->Name)); } for (i = 0;i < LIST_NUM(o);i++) { char *name = LIST_DATA(o, i); L3DelSw(c, name); Free(name); } ReleaseList(o); } UnlockList(c->L3SwList); }
// Clean-up the L3 switch void CleanupL3Sw(L3SW *s) { UINT i; // Validate arguments if (s == NULL) { return; } for (i = 0;i < LIST_NUM(s->IfList);i++) { L3IF *f = LIST_DATA(s->IfList, i); Free(f); } ReleaseList(s->IfList); for (i = 0;i < LIST_NUM(s->TableList);i++) { L3TABLE *t = LIST_DATA(s->TableList, i); Free(t); } ReleaseList(s->TableList); DeleteLock(s->lock); Free(s); }
// Configuration release void ElFreeConfig(EL *e) { UINT i; LIST *o; // Validate arguments if (e == NULL) { return; } // Write the configuration file ElSaveConfig(e); FreeCfgRw(e->CfgRw); // Stop all capture o = NewList(NULL); LockList(e->DeviceList); { for (i = 0;i < LIST_NUM(e->DeviceList);i++) { EL_DEVICE *d = LIST_DATA(e->DeviceList, i); Insert(o, CopyStr(d->DeviceName)); } for (i = 0;i < LIST_NUM(o);i++) { char *name = LIST_DATA(o, i); ElDeleteCaptureDevice(e, name); Free(name); } ReleaseList(o); } UnlockList(e->DeviceList); ReleaseList(e->DeviceList); }
// Delete old entries in Non-SSL connection list void DeleteOldNoSsl(CEDAR *c) { UINT i; LIST *o; // Validate arguments if (c == NULL) { return; } o = NewListFast(NULL); for (i = 0;i < LIST_NUM(c->NonSslList);i++) { NON_SSL *n = LIST_DATA(c->NonSslList, i); if (n->EntryExpires <= Tick64()) { Add(o, n); } } for (i = 0;i < LIST_NUM(o);i++) { NON_SSL *n = LIST_DATA(o, i); Delete(c->NonSslList, n); Free(n); } ReleaseList(o); }
// Search adapter with the name struct WP_ADAPTER *Win32EthSearch(char *name) { UINT i; UINT id; char simple_name[MAX_SIZE]; WP_ADAPTER *ret = NULL; id = Win32EthGetNameAndIdFromCombinedName(simple_name, sizeof(simple_name), name); if (id != 0) { UINT num_match = 0; // Search with ID when ID is specified for (i = 0;i < LIST_NUM(eth_list);i++) { WP_ADAPTER *a = LIST_DATA(eth_list, i); if (a->Id != 0 && a->Id == id) { ret = a; num_match++; } } if (num_match >= 2) { // If the ID matches to 2 or more devices, search with the name for (i = 0;i < LIST_NUM(eth_list);i++) { WP_ADAPTER *a = LIST_DATA(eth_list, i); if (a->Id != 0 && a->Id == id) { if (StrCmpi(a->Title, name) == 0) { ret = a; break; } } } } } else { // Search with name when ID is not specified for (i = 0;i < LIST_NUM(eth_list);i++) { WP_ADAPTER *a = LIST_DATA(eth_list, i); if (StrCmpi(a->Title, name) == 0) { ret = a; break; } } } return ret; }
// Release the Layer-3 interface void L3FreeInterface(L3IF *f) { UINT i; L3PACKET *p; PKT *pkt; // Validate arguments if (f == NULL) { return; } for (i = 0;i < LIST_NUM(f->ArpTable);i++) { L3ARPENTRY *a = LIST_DATA(f->ArpTable, i); Free(a); } ReleaseList(f->ArpTable); f->ArpTable = NULL; for (i = 0;i < LIST_NUM(f->ArpWaitTable);i++) { L3ARPWAIT *w = LIST_DATA(f->ArpWaitTable, i); Free(w); } ReleaseList(f->ArpWaitTable); f->ArpWaitTable = NULL; while (p = GetNext(f->IpPacketQueue)) { Free(p->Packet->PacketData); FreePacket(p->Packet); Free(p); } ReleaseQueue(f->IpPacketQueue); f->IpPacketQueue = NULL; for (i = 0;i < LIST_NUM(f->IpWaitList);i++) { L3PACKET *p = LIST_DATA(f->IpWaitList, i); Free(p->Packet->PacketData); FreePacket(p->Packet); Free(p); } ReleaseList(f->IpWaitList); f->IpWaitList = NULL; while (pkt = GetNext(f->SendQueue)) { Free(pkt->PacketData); FreePacket(pkt); } ReleaseQueue(f->SendQueue); f->SendQueue = NULL; }
// Stop the iptables management void EndAddIpTablesEntryForNativeStack(IPTABLES_STATE *s) { UINT i; if (s == NULL) { return; } // Delete entries for (i = 0; i < LIST_NUM(s->EntryList);i++) { IPTABLES_ENTRY *e = LIST_DATA(s->EntryList, i); UINT j; for (j = 0;j < 100;j++) { if (GetCurrentIpTableLineNumber(e->Chain, &e->DummySrcIp, &e->DummyDestIP, e->DummyMark) != 0) { char cmdline[MAX_PATH]; Format(cmdline, sizeof(cmdline), "iptables -D %s %s", e->Chain, e->ConditionAndArgs); system(cmdline); } else { break; } } } FreeIpTablesState(s); }
// Build the Attribute list BUF *SstpBuildAttributeList(LIST *o, USHORT message_type) { UINT i; BUF *b; USHORT us; // Validate arguments if (o == NULL) { return NULL; } b = NewBuf(); us = Endian16(message_type); WriteBuf(b, &us, sizeof(USHORT)); us = Endian16((USHORT)LIST_NUM(o)); WriteBuf(b, &us, sizeof(USHORT)); for (i = 0;i < LIST_NUM(o);i++) { SSTP_ATTRIBUTE *a = LIST_DATA(o, i); BUF *ab = SstpBuildAttribute(a); if (ab != NULL) { WriteBufBuf(b, ab); FreeBuf(ab); } } return b; }
// Delete trusted CA from Cedar bool DeleteCa(CEDAR *cedar, UINT ptr) { bool b = false; // Validate arguments if (cedar == NULL || ptr == 0) { return false; } LockList(cedar->CaList); { UINT i; for (i = 0;i < LIST_NUM(cedar->CaList);i++) { X *x = LIST_DATA(cedar->CaList, i); if (POINTER_TO_KEY(x) == ptr) { Delete(cedar->CaList, x); FreeX(x); b = true; break; } } } UnlockList(cedar->CaList); return b; }
// Add trusted CA to Cedar void AddCa(CEDAR *cedar, X *x) { // Validate arguments if (cedar == NULL || x == NULL) { return; } LockList(cedar->CaList); { UINT i; bool ok = true; for (i = 0;i < LIST_NUM(cedar->CaList);i++) { X *exist_x = LIST_DATA(cedar->CaList, i); if (CompareX(exist_x, x)) { ok = false; break; } } if (ok) { Insert(cedar->CaList, CloneX(x)); } } UnlockList(cedar->CaList); }
// Check whether there is any EAP-enabled RADIUS configuration bool CedarIsThereAnyEapEnabledRadiusConfig(CEDAR *c) { bool ret = false; UINT i; if (c == NULL) { return false; } LockHubList(c); { for (i = 0;i < LIST_NUM(c->HubList);i++) { HUB *hub = LIST_DATA(c->HubList, i); if (hub->RadiusConvertAllMsChapv2AuthRequestToEap) { ret = true; break; } } } UnlockHubList(c); return ret; }
// Search an entry IPTABLES_ENTRY *SearchIpTables(IPTABLES_STATE *s, char *chain, IP *src_ip, IP *dest_ip, UINT mark) { char ip_str1[64]; char ip_str2[64]; char mark_str1[64]; char mark_str2[64]; UINT i; if (s == NULL || chain == NULL || src_ip == NULL || dest_ip == NULL || mark == 0) { return NULL; } IPToStr(ip_str1, sizeof(ip_str1), src_ip); IPToStr(ip_str2, sizeof(ip_str2), dest_ip); ToStr(mark_str1, mark); Format(mark_str2, sizeof(mark_str2), "%x", mark); for (i = 0;i < LIST_NUM(s->EntryList);i++) { IPTABLES_ENTRY *e = LIST_DATA(s->EntryList, i); if (StrCmpi(e->Chain, chain) == 0) { if (InStr(e->ConditionAndArgs, ip_str1) && InStr(e->ConditionAndArgs, ip_str2) && (InStr(e->ConditionAndArgs, mark_str1) || InStr(e->ConditionAndArgs, mark_str2))) { return e; } } } return NULL; }
// Get reverse listener socket in Cedar SOCK *GetReverseListeningSock(CEDAR *c) { SOCK *s = NULL; // Validate arguments if (c == NULL) { return NULL; } LockList(c->ListenerList); { UINT i; for (i = 0;i < LIST_NUM(c->ListenerList);i++) { LISTENER *r = LIST_DATA(c->ListenerList, i); if (r->Protocol == LISTENER_REVERSE) { Lock(r->lock); { s = r->Sock; AddRef(s->ref); } Unlock(r->lock); break; } } } UnlockList(c->ListenerList); return s; }
// Delete the UDP session from the UDP entry void DelUDPEntry(CEDAR *cedar, SESSION *session) { UINT num, i; // Validate arguments if (cedar == NULL || session == NULL) { return; } LockList(cedar->UDPEntryList); { num = LIST_NUM(cedar->UDPEntryList); for (i = 0;i < num;i++) { UDP_ENTRY *e = LIST_DATA(cedar->UDPEntryList, i); if (e->Session == session) { ReleaseSession(e->Session); Delete(cedar->UDPEntryList, e); Free(e); UnlockList(cedar->UDPEntryList); Debug("UDP_Entry Deleted.\n"); return; } } } UnlockList(cedar->UDPEntryList); }
// Get the best routing table entry for the specified IP address L3TABLE *L3GetBestRoute(L3SW *s, UINT ip) { UINT i; UINT max_mask = 0; UINT min_metric = INFINITE; L3TABLE *ret = NULL; // Validate arguments if (s == NULL || ip == 0) { return NULL; } // 1st condition: Choose the one which have the largest subnet mask // 2nd condition: Choose the one which have the smallest metric for (i = 0;i < LIST_NUM(s->TableList);i++) { L3TABLE *t = LIST_DATA(s->TableList, i); if ((t->NetworkAddress & t->SubnetMask) == (ip & t->SubnetMask)) { if (t->SubnetMask >= max_mask) { max_mask = t->SubnetMask; if (min_metric >= t->Metric) { min_metric = t->Metric; ret = t; } } } } return ret; }
// Enumerate VLANs TOKEN_LIST *UnixVLanEnum() { TOKEN_LIST *ret; UINT i; if (unix_vlan == NULL) { return NullToken(); } ret = ZeroMalloc(sizeof(TOKEN_LIST)); LockList(unix_vlan); { ret->NumTokens = LIST_NUM(unix_vlan); ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens); for (i = 0;i < ret->NumTokens;i++) { UNIX_VLAN_LIST *t = LIST_DATA(unix_vlan, i); ret->Token[i] = CopyStr(t->Name); } } UnlockList(unix_vlan); return ret; }
// Save the Unicode cache void SaveUnicodeCache(wchar_t *strfilename, UINT strfilesize, UCHAR *hash) { UNICODE_CACHE c; BUF *b; UINT i; IO *io; wchar_t name[MAX_PATH]; UCHAR binhash[MD5_SIZE]; // Validate arguments if (strfilename == NULL || hash == NULL) { return; } Zero(&c, sizeof(c)); UniToStr(c.StrFileName, sizeof(c.StrFileName), strfilename); c.StrFileSize = strfilesize; GetMachineName(c.MachineName, sizeof(c.MachineName)); c.OsType = GetOsInfo()->OsType; Copy(c.hash, hash, MD5_SIZE); #ifdef OS_UNIX GetCurrentCharSet(c.CharSet, sizeof(c.CharSet)); #else // OS_UNIX { UINT id = MsGetThreadLocale(); Copy(c.CharSet, &id, sizeof(id)); } #endif // OS_UNIX b = NewBuf(); WriteBuf(b, &c, sizeof(c)); WriteBufInt(b, LIST_NUM(TableList)); for (i = 0;i < LIST_NUM(TableList);i++) { TABLE *t = LIST_DATA(TableList, i); WriteBufInt(b, StrLen(t->name)); WriteBuf(b, t->name, StrLen(t->name)); WriteBufInt(b, StrLen(t->str)); WriteBuf(b, t->str, StrLen(t->str)); WriteBufInt(b, UniStrLen(t->unistr)); WriteBuf(b, t->unistr, UniStrLen(t->unistr) * sizeof(wchar_t)); } Hash(binhash, b->Buf, b->Size, false); WriteBuf(b, binhash, MD5_SIZE); GenerateUnicodeCacheFileName(name, sizeof(name), strfilename, strfilesize, hash); io = FileCreateW(name); if (io != NULL) { SeekBuf(b, 0, 0); BufToFile(io, b); FileClose(io); } FreeBuf(b); }
// 文字列リストを文字列に変換する BUF *StrListToStr(LIST *o) { BUF *b; UINT i; char c; // 引数チェック if (o == NULL) { return NULL; } b = NewBuf(); for (i = 0;i < LIST_NUM(o);i++) { char *s = LIST_DATA(o, i); WriteBuf(b, s, StrLen(s) + 1); } c = 0; WriteBuf(b, &c, 1); SeekBuf(b, 0, 0); return b; }
// Enumerate items and store these to the token list TOKEN_LIST *CfgEnumItemToTokenList(FOLDER *f) { TOKEN_LIST *t, *ret; UINT i; // Validate arguments if (f == NULL) { return NULL; } t = ZeroMalloc(sizeof(TOKEN_LIST)); t->NumTokens = LIST_NUM(f->Items); t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); for (i = 0;i < t->NumTokens;i++) { FOLDER *ff = LIST_DATA(f->Items, i); t->Token[i] = CopyStr(ff->Name); } ret = UniqueToken(t); FreeToken(t); return ret; }
// Device enumeration UINT EtEnumDevice(EL *e, RPC_ENUM_DEVICE *t) { bool is_beta_expired = ElIsBetaExpired(); if (is_beta_expired) { // The beta version has expired return ERR_BETA_EXPIRES; } FreeRpcEnumDevice(t); Zero(t, sizeof(RPC_ENUM_DEVICE)); LockList(e->DeviceList); { UINT i; t->NumItem = LIST_NUM(e->DeviceList); t->Items = ZeroMalloc(sizeof(RPC_ENUM_DEVICE_ITEM) * t->NumItem); for (i = 0;i < t->NumItem;i++) { RPC_ENUM_DEVICE_ITEM *d = &t->Items[i]; EL_DEVICE *eld = LIST_DATA(e->DeviceList, i); StrCpy(d->DeviceName, sizeof(d->DeviceName), eld->DeviceName); d->Active = eld->Active && ((ELOG_IS_BETA || e->LicenseStatus->Valid) ? true : false); } } UnlockList(e->DeviceList); return ERR_NO_ERROR; }
// Release of the Tick64 void FreeTick64() { UINT i; if (tk64 == NULL) { // Uninitialized return; } // Termination process tk64->Halt = true; Set(halt_tick_event); WaitThread(tk64->Thread, INFINITE); ReleaseThread(tk64->Thread); // Releasing process for (i = 0;i < LIST_NUM(tk64->AdjustTime);i++) { ADJUST_TIME *t = LIST_DATA(tk64->AdjustTime, i); Free(t); } ReleaseList(tk64->AdjustTime); DeleteLock(tk64->TickLock); Free(tk64); tk64 = NULL; ReleaseEvent(halt_tick_event); halt_tick_event = NULL; }
// Convert an integer list to a string void IntListToStr(char *str, UINT str_size, LIST *o, char *separate_str) { UINT i; ClearStr(str, str_size); // Validate arguments if (o == NULL) { return; } if (IsEmptyStr(separate_str)) { separate_str = ", "; } for (i = 0;i < LIST_NUM(o);i++) { char tmp[MAX_SIZE]; UINT *v = LIST_DATA(o, i); ToStr(tmp, *v); StrCat(str, str_size, tmp); if (i != (LIST_NUM(o) - 1)) { StrCat(str, str_size, separate_str); } } }
// Convert the Tick value to time UINT64 Tick64ToTime64(UINT64 tick) { UINT64 ret = 0; if (tick == 0) { return 0; } LockList(tk64->AdjustTime); { UINT i; for (i = 0;i < LIST_NUM(tk64->AdjustTime);i++) { ADJUST_TIME *t = LIST_DATA(tk64->AdjustTime, i); if (t->Tick <= tick) { ret = t->Time + (tick - t->Tick); } } } UnlockList(tk64->AdjustTime); if (ret == 0) { ret++; } return ret; }
// Get Ethernet device list on Solaris TOKEN_LIST *GetEthListSolaris() { TOKEN_LIST *t; int i, s; LIST *o; o = NewListFast(CompareStr); s = socket(AF_INET, SOCK_DGRAM, 0); if (s != INVALID_SOCKET) { struct lifnum lifn; lifn.lifn_family = AF_INET; lifn.lifn_flags = 0; if (ioctl(s, SIOCGLIFNUM, (char *)&lifn) >= 0) { struct lifconf lifc; struct lifreq *buf; UINT numifs; UINT bufsize; numifs = lifn.lifn_count; Debug("NumIFs:%d\n",numifs); bufsize = numifs * sizeof(struct lifreq); buf = Malloc(bufsize); lifc.lifc_family = AF_INET; lifc.lifc_flags = 0; lifc.lifc_len = bufsize; lifc.lifc_buf = (char*) buf; if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) >= 0) { for (i = 0; i<numifs; i++) { if(StartWith(buf[i].lifr_name, "lo") == false){ Add(o, CopyStr(buf[i].lifr_name)); } } } Free(buf); } closesocket(s); } Sort(o); t = ZeroMalloc(sizeof(TOKEN_LIST)); t->NumTokens = LIST_NUM(o); t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); for (i = 0;i < LIST_NUM(o);i++) { char *name = LIST_DATA(o, i); t->Token[i] = name; } ReleaseList(o); return t; }
// Get the string name that begins with the specified name TOKEN_LIST *GetTableNameStartWith(char *str) { UINT i; UINT len; LIST *o; TOKEN_LIST *t; char tmp[MAX_SIZE]; // Validate arguments if (str == NULL) { return NullToken(); } StrCpy(tmp, sizeof(tmp), str); StrUpper(tmp); len = StrLen(tmp); o = NewListFast(NULL); for (i = 0;i < LIST_NUM(TableList);i++) { TABLE *t = LIST_DATA(TableList, i); UINT len2 = StrLen(t->name); if (len2 >= len) { if (Cmp(t->name, tmp, len) == 0) { Insert(o, CopyStr(t->name)); } } } t = ZeroMalloc(sizeof(TOKEN_LIST)); t->NumTokens = LIST_NUM(o); t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); for (i = 0;i < t->NumTokens;i++) { t->Token[i] = LIST_DATA(o, i); } ReleaseList(o); return t; }
// Normalize the IPsec service setttings void IPsecNormalizeServiceSetting(IPSEC_SERVER *s) { CEDAR *c; // Validate arguments if (s == NULL) { return; } c = s->Cedar; Lock(s->LockSettings); { bool reset_hub_setting = false; if (IsEmptyStr(s->Services.IPsec_Secret)) { // If the secret is not set, set the default one StrCpy(s->Services.IPsec_Secret, sizeof(s->Services.IPsec_Secret), IPSEC_DEFAULT_SECRET); } LockList(c->HubList); { if (IsEmptyStr(s->Services.L2TP_DefaultHub)) { reset_hub_setting = true; } else { if (IsHub(c, s->Services.L2TP_DefaultHub) == false) { reset_hub_setting = true; } } if (reset_hub_setting) { // Select the first Virtual HUB if there is no HUB HUB *h = NULL; if (LIST_NUM(c->HubList) >= 1) { h = LIST_DATA(c->HubList, 0); } if (h != NULL) { StrCpy(s->Services.L2TP_DefaultHub, sizeof(s->Services.L2TP_DefaultHub), h->Name); } else { StrCpy(s->Services.L2TP_DefaultHub, sizeof(s->Services.L2TP_DefaultHub), ""); } } } UnlockList(c->HubList); } Unlock(s->LockSettings); }
// Cut out the token from the string (not ignore the blanks between delimiters) TOKEN_LIST *ParseTokenWithNullStr(char *str, char *split_chars) { LIST *o; UINT i, len; BUF *b; char zero = 0; TOKEN_LIST *t; // Validate arguments if (str == NULL) { return NullToken(); } if (split_chars == NULL) { split_chars = DefaultTokenSplitChars(); } b = NewBuf(); o = NewListFast(NULL); len = StrLen(str); for (i = 0;i < (len + 1);i++) { char c = str[i]; bool flag = IsCharInStr(split_chars, c); if (c == '\0') { flag = true; } if (flag == false) { WriteBuf(b, &c, sizeof(char)); } else { WriteBuf(b, &zero, sizeof(char)); Insert(o, CopyStr((char *)b->Buf)); ClearBuf(b); } } t = ZeroMalloc(sizeof(TOKEN_LIST)); t->NumTokens = LIST_NUM(o); t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); for (i = 0;i < t->NumTokens;i++) { t->Token[i] = LIST_DATA(o, i); } ReleaseList(o); FreeBuf(b); return t; }
// Search for the best language from LANG string of UNIX LANGLIST *GetBestLangByLangStr(LIST *o, char *str) { UINT i; LANGLIST *ret; // Validate arguments if (o == NULL) { return NULL; } for (i = 0;i < LIST_NUM(o);i++) { LANGLIST *e = LIST_DATA(o, i); UINT j; for (j = 0;j < LIST_NUM(e->LangList);j++) { char *v = LIST_DATA(e->LangList, j); if (StrCmpi(v, str) == 0) { return e; } } } for (i = 0;i < LIST_NUM(o);i++) { LANGLIST *e = LIST_DATA(o, i); UINT j; for (j = 0;j < LIST_NUM(e->LangList);j++) { char *v = LIST_DATA(e->LangList, j); if (StartWith(str, v) || StartWith(v, str)) { return e; } } } ret = GetBestLangByName(o, "en"); return ret; }
// Polling for the ARP resolution waiting list void L3PollingArpWaitTable(L3IF *f) { UINT i; LIST *o = NULL; // Validate arguments if (f == NULL) { return; } for (i = 0;i < LIST_NUM(f->ArpWaitTable);i++) { L3ARPWAIT *w = LIST_DATA(f->ArpWaitTable, i); if (w->Expire <= Tick64()) { // The ARP request entry is expired if (o == NULL) { o = NewListFast(NULL); } Insert(o, w); } else if ((w->LastSentTime + ARP_REQUEST_TIMEOUT) <= Tick64()) { // Send a next ARP request packet w->LastSentTime = Tick64(); L3SendArpRequestNow(f, w->IpAddress); } } if (o != NULL) { for (i = 0;i < LIST_NUM(o);i++) { L3ARPWAIT *w = LIST_DATA(o, i); Delete(f->ArpWaitTable, w); Free(w); } ReleaseList(o); } }
// Clear old ARP table entries void L3DeleteOldArpTable(L3IF *f) { UINT i; LIST *o = NULL; // Validate arguments if (f == NULL) { return; } if ((f->LastDeleteOldArpTable + ARP_ENTRY_POLLING_TIME) > Tick64()) { return; } f->LastDeleteOldArpTable = Tick64(); for (i = 0;i < LIST_NUM(f->ArpTable);i++) { L3ARPENTRY *a = LIST_DATA(f->ArpTable, i); if (a->Expire <= Tick64()) { // Expired if (o == NULL) { o = NewListFast(NULL); } Insert(o, a); } } if (o != NULL) { for (i = 0;i < LIST_NUM(o);i++) { L3ARPENTRY *a = LIST_DATA(o, i); Delete(f->ArpTable, a); Free(a); } ReleaseList(o); } }