Move over all the code which I have written from scratch (i.e. no other developer has contributed to) This code was written without the aid of any dissasemblies. It's just made up as I go along, thus there is no documentation either Added: trunk/reactos/base/ Added: trunk/reactos/base/applications/ Added: trunk/reactos/base/applications/network/ Added: trunk/reactos/base/applications/network/arp/ Added: trunk/reactos/base/applications/network/arp/arp.c Added: trunk/reactos/base/applications/network/arp/arp.rbuild Added: trunk/reactos/base/applications/network/arp/arp.rc Added: trunk/reactos/base/applications/network/ipconfig/ Added: trunk/reactos/base/applications/network/ipconfig/ipconfig.c Added: trunk/reactos/base/applications/network/ipconfig/ipconfig.rbuild Added: trunk/reactos/base/applications/network/ipconfig/ipconfig.rc Added: trunk/reactos/base/applications/network/netstat/ Added: trunk/reactos/base/applications/network/netstat/netstat.c Added: trunk/reactos/base/applications/network/netstat/netstat.h Added: trunk/reactos/base/applications/network/netstat/netstat.rbuild Added: trunk/reactos/base/applications/network/netstat/netstat.rc Added: trunk/reactos/base/applications/network/tracert/ Added: trunk/reactos/base/applications/network/tracert/tracert.c Added: trunk/reactos/base/applications/network/tracert/tracert.h Added: trunk/reactos/base/applications/network/tracert/tracert.rbuild Added: trunk/reactos/base/applications/network/tracert/tracert.rc Added: trunk/reactos/base/services/ Added: trunk/reactos/base/services/tcpsvcs/ Added: trunk/reactos/base/services/tcpsvcs/chargen.c Added: trunk/reactos/base/services/tcpsvcs/daytime.c Added: trunk/reactos/base/services/tcpsvcs/discard.c Added: trunk/reactos/base/services/tcpsvcs/echo.c Added: trunk/reactos/base/services/tcpsvcs/qotd.c Added: trunk/reactos/base/services/tcpsvcs/quotes Added: trunk/reactos/base/services/tcpsvcs/skelserver.c Added: trunk/reactos/base/services/tcpsvcs/tcpsvcs.c Added: trunk/reactos/base/services/tcpsvcs/tcpsvcs.h Added: trunk/reactos/base/services/tcpsvcs/tcpsvcs.rbuild Added: trunk/reactos/base/services/tcpsvcs/tcpsvcs.rc Added: trunk/reactos/base/system/ Added: trunk/reactos/base/system/sc/ Added: trunk/reactos/base/system/sc/control.c Added: trunk/reactos/base/system/sc/create.c Added: trunk/reactos/base/system/sc/delete.c Added: trunk/reactos/base/system/sc/query.c Added: trunk/reactos/base/system/sc/sc.c Added: trunk/reactos/base/system/sc/sc.h Added: trunk/reactos/base/system/sc/sc.rbuild Added: trunk/reactos/base/system/sc/sc.rc Added: trunk/reactos/base/system/sc/start.c Added: trunk/reactos/base/system/sc/usage.c Added: trunk/reactos/base/system/servman/ Added: trunk/reactos/base/system/servman/De.rc Added: trunk/reactos/base/system/servman/En.rc Added: trunk/reactos/base/system/servman/about.c Added: trunk/reactos/base/system/servman/control.c Added: trunk/reactos/base/system/servman/geterror.c Added: trunk/reactos/base/system/servman/progress.c Added: trunk/reactos/base/system/servman/propsheet.c Added: trunk/reactos/base/system/servman/query.c Added: trunk/reactos/base/system/servman/res/ Added: trunk/reactos/base/system/servman/res/system.ico Added: trunk/reactos/base/system/servman/res/toolbar.bmp Added: trunk/reactos/base/system/servman/resource.h Added: trunk/reactos/base/system/servman/servman.c Added: trunk/reactos/base/system/servman/servman.h Added: trunk/reactos/base/system/servman/servman.rbuild Added: trunk/reactos/base/system/servman/servman.rc Added: trunk/reactos/base/system/servman/start.c Added: trunk/reactos/base/system/servman/test.rc Property changes on: trunk/reactos/base/applications/network/arp ___________________________________________________________________ Name: ros:doc + ReactOS arp is a visual copy of the Windows version, however this code was written from scratch without any reverse-engineering _____
Added: trunk/reactos/base/applications/network/arp/arp.c --- trunk/reactos/base/applications/network/arp/arp.c 2006-01-28 17:39:13 UTC (rev 12) +++ trunk/reactos/base/applications/network/arp/arp.c 2006-01-28 17:44:29 UTC (rev 13) @@ -0,0 +1,600 @@
+/* + * PROJECT: ReactOS arp utility + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/network/arp/arp.c + * PURPOSE: view and manipulate the ARP cache + * COPYRIGHT: Copyright 2005 Ged Murphy gedmurphy@gmail.com + * + */ + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#include <tchar.h> +#include <string.h> +#include <ctype.h> +#include <winsock2.h> +#include <iphlpapi.h> + +#define UNICODE +#define _UNICODE + +/* + * Globals + */ +const char SEPERATOR = '-'; +int _CRT_glob = 0; // stop * from listing dir files in arp -d * + + +/* + * function declerations + */ +DWORD DoFormatMessage(VOID); +INT PrintEntries(PMIB_IPNETROW pIpAddRow); +INT DisplayArpEntries(PTCHAR pszInetAddr, PTCHAR pszIfAddr); +INT Addhost(PTCHAR pszInetAddr, PTCHAR pszEthAddr, PTCHAR pszIfAddr); +INT Deletehost(PTCHAR pszInetAddr, PTCHAR pszIfAddr); +VOID Usage(VOID); + + +/* + * convert error code into meaningful message + */ +DWORD DoFormatMessage(VOID) +{ + LPVOID lpMsgBuf; + DWORD RetVal; + + DWORD ErrorCode = GetLastError(); + + if (ErrorCode != ERROR_SUCCESS) + { + RetVal = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + ErrorCode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ + (LPTSTR) &lpMsgBuf, + 0, + NULL ); + + if (RetVal != 0) + { + _tprintf(_T("%s"), (LPTSTR)lpMsgBuf); + + LocalFree(lpMsgBuf); + /* return number of TCHAR's stored in output buffer + * excluding '\0' - as FormatMessage does*/ + return RetVal; + } + } + return 0; +} + + + +/* + * + * Takes an ARP entry and prints the IP address, + * the MAC address and the entry type to screen + * + */ +INT PrintEntries(PMIB_IPNETROW pIpAddRow) +{ + IN_ADDR inaddr; + TCHAR cMacAddr[20]; + + /* print IP addresses */ + inaddr.S_un.S_addr = pIpAddRow->dwAddr; + _tprintf(_T(" %-22s"), inet_ntoa(inaddr)); + + /* print MAC address */ + _stprintf(cMacAddr, _T("%02x-%02x-%02x-%02x-%02x-%02x"), + pIpAddRow->bPhysAddr[0], + pIpAddRow->bPhysAddr[1], + pIpAddRow->bPhysAddr[2], + pIpAddRow->bPhysAddr[3], + pIpAddRow->bPhysAddr[4], + pIpAddRow->bPhysAddr[5]); + _tprintf(_T("%-22s"), cMacAddr); + + /* print cache type */ + switch (pIpAddRow->dwType) + { + case MIB_IPNET_TYPE_DYNAMIC : _tprintf(_T("dynamic\n")); + break; + case MIB_IPNET_TYPE_STATIC : _tprintf(_T("static\n")); + break; + case MIB_IPNET_TYPE_INVALID : _tprintf(_T("invalid\n")); + break; + case MIB_IPNET_TYPE_OTHER : _tprintf(_T("other\n")); + break; + } + return EXIT_SUCCESS; +} + + +/* + * + * Takes optional parameters of an internet address and interface address. + * Retrieve all entries in the ARP cache. If an internet address is + * specified, display the ARP entry relating to that address. If an + * interface address is specified, display all entries relating to + * that interface. + * + */ +/* FIXME: allow user to specify an interface address, via pszIfAddr */ +INT DisplayArpEntries(PTCHAR pszInetAddr, PTCHAR pszIfAddr) +{ + INT iRet; + UINT i, k; + PMIB_IPNETTABLE pIpNetTable = NULL; + PMIB_IPADDRTABLE pIpAddrTable = NULL; + DWORD Size = 0; + struct in_addr inaddr, inaddr2; + PTCHAR pszIpAddr; + TCHAR szIntIpAddr[20]; + + /* retrieve the IP-to-physical address mapping table */ + + /* get table size */ + GetIpNetTable(pIpNetTable, &Size, 0); + + /* allocate memory for ARP address table */ + pIpNetTable = (PMIB_IPNETTABLE) HeapAlloc(GetProcessHeap(), 0, Size); + if (pIpNetTable == NULL) + goto cleanup; + + ZeroMemory(pIpNetTable, sizeof(*pIpNetTable)); + + iRet = GetIpNetTable(pIpNetTable, &Size, TRUE); + + if (iRet != NO_ERROR) + { + _tprintf(_T("failed to allocate memory for GetIpNetTable\n")); + DoFormatMessage(); + goto cleanup; + } + + /* check there are entries in the table */ + if (pIpNetTable->dwNumEntries == 0) + { + _tprintf(_T("No ARP entires found\n")); + goto cleanup; + } + + + + /* Retrieve the interface-to-ip address mapping + * table to get the IP address for adapter */ + + /* get table size */ + Size = 0; + GetIpAddrTable(pIpAddrTable, &Size, 0); + + pIpAddrTable = (MIB_IPADDRTABLE *) HeapAlloc(GetProcessHeap(), 0, Size); + if (pIpAddrTable == NULL) + goto cleanup; + + ZeroMemory(pIpAddrTable, sizeof(*pIpAddrTable)); + + iRet = GetIpAddrTable(pIpAddrTable, &Size, TRUE); + + if (iRet != NO_ERROR) + { + _tprintf(_T("GetIpAddrTable failed: %d\n"), iRet); + DoFormatMessage(); + goto cleanup; + } + + + for (k=0; k < pIpAddrTable->dwNumEntries; k++) + { + if (pIpNetTable->table[0].dwIndex == pIpAddrTable->table[k].dwIndex) + { + //printf("debug print: pIpAddrTable->table[?].dwIndex = %lx\n", pIpNetTable->table[k].dwIndex); + inaddr2.s_addr = pIpAddrTable->table[k].dwAddr; + pszIpAddr = inet_ntoa(inaddr2); + strcpy(szIntIpAddr, pszIpAddr); + } + } + + + /* print header, including interface IP address and index number */ + _tprintf(_T("\nInterface: %s --- 0x%lx \n"), szIntIpAddr, pIpNetTable->table[0].dwIndex); + _tprintf(_T(" Internet Address Physical Address Type\n")); + + /* go through all ARP entries */ + for (i=0; i < pIpNetTable->dwNumEntries; i++) + { + + /* if the user has supplied their own internet addesss * + * only print the arp entry which matches that */ + if (pszInetAddr) + { + inaddr.S_un.S_addr = pIpNetTable->table[i].dwAddr; + pszIpAddr = inet_ntoa(inaddr); + + /* check if it matches, print it */ + if (strcmp(pszIpAddr, pszInetAddr) == 0) + PrintEntries(&pIpNetTable->table[i]); + } + else + /* if an address is not supplied, print all entries */ + PrintEntries(&pIpNetTable->table[i]); + } + + return EXIT_SUCCESS; + +cleanup: + if (pIpNetTable != NULL) + HeapFree(GetProcessHeap(), 0, pIpNetTable); + if (pIpAddrTable != NULL) + HeapFree(GetProcessHeap(), 0, pIpAddrTable); + return EXIT_FAILURE; +} + + +/* + * + * Takes an internet address, a MAC address and an optional interface + * address as arguments and checks their validity. + * Fill out an MIB_IPNETROW structure and insert the data into the + * ARP cache as a static entry. + * + */ +INT Addhost(PTCHAR pszInetAddr, PTCHAR pszEthAddr, PTCHAR pszIfAddr) +{ + PMIB_IPNETROW pAddHost = NULL; + PMIB_IPNETTABLE pIpNetTable = NULL; + DWORD dwIpAddr = 0; + ULONG Size = 0; + INT iRet, i, val, c; + + /* error checking */ + + /* check IP address */ + if (pszInetAddr != NULL) + { + if ((dwIpAddr = inet_addr(pszInetAddr)) == INADDR_NONE) + { + _tprintf(_T("ARP: bad IP address: %s\n"), pszInetAddr); + return EXIT_FAILURE; + } + } + else + { + Usage(); + return EXIT_FAILURE; + } + + /* check MAC address */ + if (strlen(pszEthAddr) != 17) + { + _tprintf(_T("ARP: bad argument: %s\n"), pszEthAddr); + return EXIT_FAILURE; + } + for (i=0; i<17; i++) + { + if (pszEthAddr[i] == SEPERATOR) + continue; + + if (!isxdigit(pszEthAddr[i])) + { + _tprintf(_T("ARP: bad argument: %s\n"), pszEthAddr); + return EXIT_FAILURE; + } + } + + /* We need the IpNetTable to get the adapter index */ + /* Return required buffer size */ + GetIpNetTable(pIpNetTable, &Size, 0); + + /* allocate memory for ARP address table */ + pIpNetTable = (PMIB_IPNETTABLE) HeapAlloc(GetProcessHeap(), 0, Size); + if (pIpNetTable == NULL) + goto cleanup; + + ZeroMemory(pIpNetTable, sizeof(*pIpNetTable)); + + iRet = GetIpNetTable(pIpNetTable, &Size, TRUE); + + if (iRet != NO_ERROR) + { + _tprintf(_T("failed to allocate memory for GetIpNetTable\n")); + DoFormatMessage(); + goto cleanup; + } + + + /* reserve memory on heap and zero */ + pAddHost = (MIB_IPNETROW *) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_IPNETROW)); + if (pAddHost == NULL) + goto cleanup; + + ZeroMemory(pAddHost, sizeof(MIB_IPNETROW)); + + /* set dwIndex field to the index of a local IP address to + * indicate the network on which the ARP entry applies */ + if (pszIfAddr) + { + if (sscanf(pszIfAddr, "%lx", &pAddHost->dwIndex) == EOF) + { + goto cleanup; + } + } + else + { + //printf("debug print: pIpNetTable->table[0].dwIndex = %lx\n", pIpNetTable->table[0].dwIndex); + /* needs testing. I get the correct index on my machine, but need others + * to test their card index. Any problems and we can use GetAdaptersInfo instead */ + pAddHost->dwIndex = pIpNetTable->table[0].dwIndex; + } + + /* Set MAC address to 6 bytes (typical) */ + pAddHost->dwPhysAddrLen = 6; + + + /* Encode bPhysAddr into correct byte array */ + for (i=0; i<6; i++) + { + val =0; + c = toupper(pszEthAddr[i*3]); + c = c - (isdigit(c) ? '0' : ('A' - 10)); + val += c; + val = (val << 4); + c = toupper(pszEthAddr[i*3 + 1]); + c = c - (isdigit(c) ? '0' : ('A' - 10)); + val += c; + pAddHost->bPhysAddr[i] = (BYTE)val; + } + + + /* copy converted IP address */ + pAddHost->dwAddr = dwIpAddr; + + + /* set type to static */ + pAddHost->dwType = MIB_IPNET_TYPE_STATIC; + + + /* Add the ARP entry */ + if ((iRet = SetIpNetEntry(pAddHost)) != NO_ERROR) + { + DoFormatMessage(); + goto cleanup; + } + + HeapFree(GetProcessHeap(), 0, pAddHost); + + return EXIT_SUCCESS; + +cleanup: + if (pIpNetTable != NULL) + HeapFree(GetProcessHeap(), 0, pIpNetTable); + if (pAddHost != NULL) + HeapFree(GetProcessHeap(), 0, pAddHost); + return EXIT_FAILURE; +} + + +/* + * + * Takes an internet address and an optional interface address as + * arguments and checks their validity. + * Add the interface number and IP to an MIB_IPNETROW structure + * and remove the entry from the ARP cache. + * + */ +INT Deletehost(PTCHAR pszInetAddr, PTCHAR pszIfAddr) +{ + PMIB_IPNETROW pDelHost = NULL; + PMIB_IPNETTABLE pIpNetTable = NULL; + DWORD Size = 0; + DWORD dwIpAddr = 0; + INT iRet; + BOOL bFlushTable = FALSE; + + /* error checking */ + + /* check IP address */ + if (pszInetAddr != NULL) + { + /* if wildcard is given, set flag to delete all hosts */ + if (strncmp(pszInetAddr, "*", 1) == 0) + bFlushTable = TRUE; + else if ((dwIpAddr = inet_addr(pszInetAddr)) == INADDR_NONE) + { + _tprintf(_T("ARP: bad IP address: %s\n"), pszInetAddr); + exit(EXIT_FAILURE); + } + } + else + { + Usage(); + exit(EXIT_FAILURE); + } + + /* We need the IpNetTable to get the adapter index */ + /* Return required buffer size */ + GetIpNetTable(NULL, &Size, 0); + + /* allocate memory for ARP address table */ + pIpNetTable = (PMIB_IPNETTABLE) HeapAlloc(GetProcessHeap(), 0, Size); + if (pIpNetTable == NULL) + goto cleanup; + + ZeroMemory(pIpNetTable, sizeof(*pIpNetTable)); + + iRet = GetIpNetTable(pIpNetTable, &Size, TRUE); + + if (iRet != NO_ERROR) + { + _tprintf(_T("failed to allocate memory for GetIpNetTable\n")); + DoFormatMessage(); + goto cleanup; + } + + /* reserve memory on heap and zero */ + pDelHost = (MIB_IPNETROW *) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_IPNETROW)); + if (pDelHost == NULL) + goto cleanup; + + ZeroMemory(pDelHost, sizeof(MIB_IPNETROW)); + + + /* set dwIndex field to the index of a local IP address to + * indicate the network on which the ARP entry applies */ + if (pszIfAddr) + { + if (sscanf(pszIfAddr, "%lx", &pDelHost->dwIndex) == EOF) + { + goto cleanup; + } + } + else + { + /* needs testing. I get the correct index on my machine, but need others + * to test their card index. Any problems and we can use GetAdaptersInfo instead */ + pDelHost->dwIndex = pIpNetTable->table[0].dwIndex; + } + + if (bFlushTable == TRUE) + { + /* delete arp cache */ + if ((iRet = FlushIpNetTable(pDelHost->dwIndex)) != NO_ERROR) + { + DoFormatMessage(); + goto cleanup; + } + else + { + HeapFree(GetProcessHeap(), 0, pDelHost); + return EXIT_SUCCESS; + } + } + else + /* copy converted IP address */ + pDelHost->dwAddr = dwIpAddr; + + /* Add the ARP entry */ + if ((iRet = DeleteIpNetEntry(pDelHost)) != NO_ERROR) + { + DoFormatMessage(); + goto cleanup; + } + + HeapFree(GetProcessHeap(), 0, pDelHost); + + return EXIT_SUCCESS; + +cleanup: + if (pIpNetTable != NULL) + HeapFree(GetProcessHeap(), 0, pIpNetTable); + if (pDelHost != NULL) + HeapFree(GetProcessHeap(), 0, pDelHost); + return EXIT_FAILURE; +} + + + +/* + * + * print program usage to screen + * + */ +VOID Usage(VOID) +{ + _tprintf(_T("\nDisplays and modifies the IP-to-Physical address translation tables used by\n" + "address resolution protocol (ARP).\n" + "\n" + "ARP -s inet_addr eth_addr [if_addr]\n" + "ARP -d inet_addr [if_addr]\n" + "ARP -a [inet_addr] [-N if_addr]\n" + "\n" + " -a Displays current ARP entries by interrogating the current\n" + " protocol data. If inet_addr is specified, the IP and Physical\n" + " addresses for only the specified computer are displayed. If\n" + " more than one network interface uses ARP, entries for each ARP\n" + " table are displayed.\n" + " -g Same as -a.\n" + " inet_addr Specifies an internet address.\n" + " -N if_addr Displays the ARP entries for the network interface specified\n" + " by if_addr.\n" + " -d Deletes the host specified by inet_addr. inet_addr may be\n" + " wildcarded with * to delete all hosts.\n" + " -s Adds the host and associates the Internet address inet_addr\n" + " with the Physical address eth_addr. The Physical address is\n" + " given as 6 hexadecimal bytes separated by hyphens. The entry\n" + " is permanent.\n" + " eth_addr Specifies a physical address.\n" + " if_addr If present, this specifies the Internet address of the\n" + " interface whose address translation table should be modified.\n" + " If not present, the first applicable interface will be used.\n" + "Example:\n" + " > arp -s 157.55.85.212 00-aa-00-62-c6-09 .... Adds a static entry.\n" + " > arp -a .... Displays the arp table.\n\n")); +} + + + +/* + * + * Program entry. + * Parse command line and call the required function + * + */ +INT main(int argc, char* argv[]) +{ + if ((argc < 2) || (argc > 5)) + { + Usage(); + return EXIT_FAILURE; + } + + if (argv[1][0] == '-') + { + switch (argv[1][1]) + { + case 'a': /* fall through */ + case 'g': + if (argc == 2) + DisplayArpEntries(NULL, NULL); + else if (argc == 3) + DisplayArpEntries(argv[2], NULL); + else if ((argc == 4) && ((strcmp(argv[2], "-N")) == 0)) + DisplayArpEntries(NULL, argv[3]); + else if ((argc == 5) && ((strcmp(argv[3], "-N")) == 0)) + DisplayArpEntries(argv[2], argv[4]); + else + Usage(); + return EXIT_FAILURE; + break; + case 'd': if (argc == 3) + Deletehost(argv[2], NULL); + else if (argc == 4) + Deletehost(argv[2], argv[3]); + else + Usage(); + return EXIT_FAILURE; + break; + case 's': if (argc == 4) + Addhost(argv[2], argv[3], NULL); + else if (argc == 5) + Addhost(argv[2], argv[3], argv[4]); + else + Usage(); + return EXIT_FAILURE; + break; + default: + Usage(); + return EXIT_FAILURE; + } + } + else + Usage(); + + return EXIT_SUCCESS; +} _____
Added: trunk/reactos/base/applications/network/arp/arp.rbuild --- trunk/reactos/base/applications/network/arp/arp.rbuild 2006-01-28 17:39:13 UTC (rev 12) +++ trunk/reactos/base/applications/network/arp/arp.rbuild 2006-01-28 17:44:29 UTC (rev 13) @@ -0,0 +1,11 @@
+<module name="arp" type="win32cui" installbase="system32" installname="arp.exe"> + <include base="arp">.</include> + <define name="__USE_W32API" /> + <library>kernel32</library> + <library>iphlpapi</library> + <library>ws2_32</library> + <library>shlwapi</library> + <file>arp.c</file> + <file>arp.rc</file> +</module> + _____
Added: trunk/reactos/base/applications/network/arp/arp.rc --- trunk/reactos/base/applications/network/arp/arp.rc 2006-01-28 17:39:13 UTC (rev 12) +++ trunk/reactos/base/applications/network/arp/arp.rc 2006-01-28 17:44:29 UTC (rev 13) @@ -0,0 +1,5 @@
+#define REACTOS_STR_FILE_DESCRIPTION "ReactOS TCP/IPv4 Win32 arp\0" +#define REACTOS_STR_INTERNAL_NAME "arp\0" +#define REACTOS_STR_ORIGINAL_FILENAME "arp.exe\0" +#define REACTOS_STR_ORIGINAL_COPYRIGHT "Ged Murphy (gedmurphy@gmail.com)\0" +#include <reactos/version.rc> Property changes on: trunk/reactos/base/applications/network/ipconfig ___________________________________________________________________ Name: ros:doc + ReactOS ipconfig is a visual copy of the Windows version, however this code was written from scratch without any reverse-engineering _____
Added: trunk/reactos/base/applications/network/ipconfig/ipconfig.c --- trunk/reactos/base/applications/network/ipconfig/ipconfig.c 2006-01-28 17:39:13 UTC (rev 12) +++ trunk/reactos/base/applications/network/ipconfig/ipconfig.c 2006-01-28 17:44:29 UTC (rev 13) @@ -0,0 +1,514 @@
+/* + * PROJECT: ReactOS ipconfig utility + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/network/ipconfig/ipconfig.c + * PURPOSE: Control access to a resource + * COPYRIGHT: Copyright 2005 Ged Murphy gedmurphy@gmail.com + * + */ + + +/* + * TODO: + * fix renew / release + * implement flushdns, registerdns, displaydns, showclassid, setclassid + * allow globbing on adapter names + */ +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <tchar.h> +#include <string.h> +#include <ctype.h> +#include <winsock2.h> +#include <iphlpapi.h> + +#define UNICODE +#define _UNICODE + + + +LPCTSTR GetNodeTypeName(UINT NodeType) +{ + switch (NodeType) { + case 1: return _T("Broadcast"); + case 2: return _T("Peer To Peer"); + case 4: return _T("Mixed"); + case 8: return _T("Hybrid"); + default : return _T("unknown"); + } +} + +LPCTSTR GetInterfaceTypeName(UINT InterfaceType) +{ + switch (InterfaceType) { + case MIB_IF_TYPE_OTHER: return _T("Other Type Of Adapter"); + case MIB_IF_TYPE_ETHERNET: return _T("Ethernet Adapter"); + case MIB_IF_TYPE_TOKENRING: return _T("Token Ring Adapter"); + case MIB_IF_TYPE_FDDI: return _T("FDDI Adapter"); + case MIB_IF_TYPE_PPP: return _T("PPP Adapter"); + case MIB_IF_TYPE_LOOPBACK: return _T("Loopback Adapter"); + case MIB_IF_TYPE_SLIP: return _T("SLIP Adapter"); + default: return _T("unknown"); + } +} + +/* print MAC address */ +PTCHAR PrintMacAddr(PBYTE Mac) +{ + static TCHAR MacAddr[20]; + + _stprintf(MacAddr, _T("%02x-%02x-%02x-%02x-%02x-%02x"), + Mac[0], Mac[1], Mac[2], Mac[3], Mac[4], Mac[5]); + + return MacAddr; +} + +DWORD DoFormatMessage(DWORD ErrorCode) +{ + LPVOID lpMsgBuf; + DWORD RetVal; + + if ((RetVal = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + ErrorCode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ + (LPTSTR) &lpMsgBuf, + 0, + NULL ))) { + _tprintf(_T("%s"), (LPTSTR)lpMsgBuf); + + LocalFree(lpMsgBuf); + /* return number of TCHAR's stored in output buffer + * excluding '\0' - as FormatMessage does*/ + return RetVal; + } + else + return 0; +} + +INT ShowInfo(BOOL bAll) +{ + PIP_ADAPTER_INFO pAdapterInfo = NULL; + PIP_ADAPTER_INFO pAdapter = NULL; + ULONG adaptOutBufLen; + + PFIXED_INFO pFixedInfo; + ULONG netOutBufLen; + PIP_ADDR_STRING pIPAddr = NULL; + + DWORD ErrRet = 0; + + /* assign memory for call to GetNetworkParams */ + pFixedInfo = (FIXED_INFO *) GlobalAlloc( GPTR, sizeof( FIXED_INFO ) ); + netOutBufLen = sizeof(FIXED_INFO); + + /* assign memory for call to GetAdapterInfo */ + pAdapterInfo = (IP_ADAPTER_INFO *) malloc( sizeof(IP_ADAPTER_INFO) ); + adaptOutBufLen = sizeof(IP_ADAPTER_INFO); + + /* set required buffer size */ + if(GetNetworkParams(pFixedInfo, &netOutBufLen) == ERROR_BUFFER_OVERFLOW) + { + GlobalFree(pFixedInfo); + pFixedInfo = (FIXED_INFO *) GlobalAlloc(GPTR, netOutBufLen); + } + + /* set required buffer size */ + if (GetAdaptersInfo( pAdapterInfo, &adaptOutBufLen) == ERROR_BUFFER_OVERFLOW) + { + free(pAdapterInfo); + pAdapterInfo = (IP_ADAPTER_INFO *) malloc (adaptOutBufLen); + } + + if ((ErrRet = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen)) != NO_ERROR) + { + _tprintf(_T("GetAdaptersInfo failed : ")); + DoFormatMessage(ErrRet); + return EXIT_FAILURE; + } + + if ((ErrRet = GetNetworkParams(pFixedInfo, &netOutBufLen)) != NO_ERROR) + { + _tprintf(_T("GetNetworkParams failed : ")); + DoFormatMessage(ErrRet); + return EXIT_FAILURE; + } + + pAdapter = pAdapterInfo; + + _tprintf(_T("\nReactOS IP Configuration\n\n")); + + if (bAll) + { + _tprintf(_T("\tHost Name . . . . . . . . . . . . : %s\n"), pFixedInfo->HostName); + _tprintf(_T("\tPrimary DNS Suffix. . . . . . . . : \n")); + _tprintf(_T("\tNode Type . . . . . . . . . . . . : %s\n"), GetNodeTypeName(pFixedInfo->NodeType)); + if (pFixedInfo->EnableRouting) + _tprintf(_T("\tIP Routing Enabled. . . . . . . . : Yes\n")); + else + _tprintf(_T("\tIP Routing Enabled. . . . . . . . : No\n")); + if (pAdapter->HaveWins) + _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : Yes\n")); + else + _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : No\n")); + _tprintf(_T("\tDNS Suffix Search List. . . . . . : %s\n"), pFixedInfo->DomainName); + } + + while (pAdapter) + { + + _tprintf(_T("\n%s ...... : \n\n"), GetInterfaceTypeName(pAdapter->Type)); + + /* check if the adapter is connected to the media */ + if (_tcscmp(pAdapter->IpAddressList.IpAddress.String, "0.0.0.0") == 0) + { + _tprintf(_T("\tMedia State . . . . . . . . . . . : Media disconnected\n")); + pAdapter = pAdapter->Next; + continue; + } + + _tprintf(_T("\tConnection-specific DNS Suffix. . : %s\n"), pFixedInfo->DomainName); + + if (bAll) + { + _tprintf(_T("\tDescription . . . . . . . . . . . : %s\n"), pAdapter->Description); + _tprintf(_T("\tPhysical Address. . . . . . . . . : %s\n"), PrintMacAddr(pAdapter->Address)); + if (pAdapter->DhcpEnabled) + _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : Yes\n")); + else + _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : No\n")); + _tprintf(_T("\tAutoconfiguration Enabled . . . . : \n")); + } + + _tprintf(_T("\tIP Address. . . . . . . . . . . . : %s\n"), pAdapter->IpAddressList.IpAddress.String); + _tprintf(_T("\tSubnet Mask . . . . . . . . . . . : %s\n"), pAdapter->IpAddressList.IpMask.String); + _tprintf(_T("\tDefault Gateway . . . . . . . . . : %s\n"), pAdapter->GatewayList.IpAddress.String); + + if (bAll) + { + if (pAdapter->DhcpEnabled) + _tprintf(_T("\tDHCP Server . . . . . . . . . . . : %s\n"), pAdapter->DhcpServer.IpAddress.String); + + _tprintf(_T("\tDNS Servers . . . . . . . . . . . : ")); + _tprintf(_T("%s\n"), pFixedInfo->DnsServerList.IpAddress.String); + pIPAddr = pFixedInfo -> DnsServerList.Next; + while (pIPAddr) + { + _tprintf(_T("\t\t\t\t\t %s\n"), pIPAddr ->IpAddress.String ); + pIPAddr = pIPAddr ->Next; + } + if (pAdapter->HaveWins) + { + _tprintf(_T("\tPrimary WINS Server . . . . . . . : %s\n"), pAdapter->PrimaryWinsServer.IpAddress.String); + _tprintf(_T("\tSecondard WINS Server . . . . . . : %s\n"), pAdapter->SecondaryWinsServer.IpAddress.String); + } + if (pAdapter->DhcpEnabled) + { + _tprintf(_T("\tLease Obtained. . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter->LeaseObtained))); + _tprintf(_T("\tLease Expires . . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter->LeaseExpires))); + } + } + _tprintf(_T("\n")); + + pAdapter = pAdapter->Next; + + } + + return 0; +} + +INT Release(TCHAR Index) +{ + IP_ADAPTER_INDEX_MAP AdapterInfo; + DWORD dwRetVal = 0; + + /* if interface is not given, query GetInterfaceInfo */ + if (Index == (TCHAR)NULL) + { + PIP_INTERFACE_INFO pInfo; + ULONG ulOutBufLen; + pInfo = (IP_INTERFACE_INFO *) malloc(sizeof(IP_INTERFACE_INFO)); + ulOutBufLen = 0; + + /* Make an initial call to GetInterfaceInfo to get + * the necessary size into the ulOutBufLen variable */ + if ( GetInterfaceInfo(pInfo, &ulOutBufLen) == ERROR_INSUFFICIENT_BUFFER) + { + GlobalFree(pInfo); + pInfo = (IP_INTERFACE_INFO *) malloc (ulOutBufLen); + } + + /* Make a second call to GetInterfaceInfo to get the actual data we want */ + if ((dwRetVal = GetInterfaceInfo(pInfo, &ulOutBufLen)) == NO_ERROR ) + { + AdapterInfo = pInfo->Adapter[0]; + _tprintf(_T("name - %S\n"), pInfo->Adapter[0].Name); + } + else + { + _tprintf(_T("\nGetInterfaceInfo failed : ")); + DoFormatMessage(dwRetVal); + } + } + else + { + ; + /* we need to be able to release connections by name with support for globbing + * i.e. ipconfig /release Eth* will release all cards starting with Eth... + * ipconfig /release *con* will release all cards with 'con' in their name + */ + } + + + /* Call IpReleaseAddress to release the IP address on the specified adapter. */ + if ((dwRetVal = IpReleaseAddress(&AdapterInfo)) != NO_ERROR) + { + _tprintf(_T("\nAn error occured while releasing interface %s : "), _T("*name*")); + DoFormatMessage(dwRetVal); + } + return 0; +} + + + + +INT Renew(TCHAR Index) +{ + IP_ADAPTER_INDEX_MAP AdapterInfo; + DWORD dwRetVal = 0; + + /* if interface is not given, query GetInterfaceInfo */ + if (Index == (TCHAR)NULL) + { + PIP_INTERFACE_INFO pInfo; + ULONG ulOutBufLen; + pInfo = (IP_INTERFACE_INFO *) malloc(sizeof(IP_INTERFACE_INFO)); + ulOutBufLen = 0; + + /* Make an initial call to GetInterfaceInfo to get + * the necessary size into the ulOutBufLen variable */ + if ( GetInterfaceInfo(pInfo, &ulOutBufLen) == ERROR_INSUFFICIENT_BUFFER) + { + GlobalFree(pInfo); + pInfo = (IP_INTERFACE_INFO *) malloc (ulOutBufLen); + } + + /* Make a second call to GetInterfaceInfo to get the actual data we want */ + if ((dwRetVal = GetInterfaceInfo(pInfo, &ulOutBufLen)) == NO_ERROR ) + { + AdapterInfo = pInfo->Adapter[0]; + _tprintf(_T("name - %S\n"), pInfo->Adapter[0].Name); + } else { + _tprintf(_T("\nGetInterfaceInfo failed : ")); + DoFormatMessage(dwRetVal); + } + } + else + { + ; + /* we need to be able to renew connections by name with support for globbing + * i.e. ipconfig /renew Eth* will renew all cards starting with Eth... + * ipconfig /renew *con* will renew all cards with 'con' in their name + */ + } + + + /* Call IpRenewAddress to renew the IP address on the specified adapter. */ + if ((dwRetVal = IpRenewAddress(&AdapterInfo)) != NO_ERROR) + { + _tprintf(_T("\nAn error occured while renew interface %s : "), _T("*name*")); + DoFormatMessage(dwRetVal); + } + return 0; +} + +/* temp func for testing purposes */ +VOID Info() +{ + // Declare and initialize variables + PIP_INTERFACE_INFO pInfo; + ULONG ulOutBufLen; + DWORD dwRetVal; + + pInfo = (IP_INTERFACE_INFO *) malloc( sizeof(IP_INTERFACE_INFO) ); + ulOutBufLen = sizeof(IP_INTERFACE_INFO); + dwRetVal = 0; + + + // Make an initial call to GetInterfaceInfo to get + // the necessary size in the ulOutBufLen variable + if ( GetInterfaceInfo(pInfo, &ulOutBufLen) == ERROR_INSUFFICIENT_BUFFER) + { + free(pInfo); + pInfo = (IP_INTERFACE_INFO *) malloc (ulOutBufLen); + } + + // Make a second call to GetInterfaceInfo to get + // the actual data we need + if ((dwRetVal = GetInterfaceInfo(pInfo, &ulOutBufLen)) == NO_ERROR ) + { + int i; [truncated at 1000 lines; 6526 more skipped]