I'm trying to get IP address of a dns server with the code:
var address = Dns.GetHostAddresses(domain)[0];
Its working on my pc, but when I'm doing it through someone else pc its giving him different result (IPv6 instead of IPv4).
I did try to use the method
var ipV4Address = address.MapToIPv4();
but that just returning the wrong IP address
p.s: btw, when using the command ping dns.address.blabla on both computers the result is the same.
If the domain have IPv4 and IPv6 addresses, you'll get both. Filter by AddressFamily to InterNetwork only (IPv4) instead of InterNetworkV6 (IPv6)
var ipV4Address = Dns.GetHostAddresses(domain)
.First(a => a.AddressFamily == AddressFamily.InterNetwork);
To answer your specific question in the header: Yes, it is. Here's an outline of how to do that:
using System.Net.NetworkInformation;
...
private static bool PingWithResponse(int timeout, string iP, out string response)
{
bool result = false;
using (var p = new Ping())
{
var r = p.Send(iP, timeout);
response = $"Ping to {iP} [{r.Address}]";
if (r.Status == IPStatus.Success)
{
response += $" Successful Response delay = {r.RoundtripTime} ms";
result = true;
}
else
{
response += $" Failed Status: {r.Status}";
}
}
return result;
}
Related
I'm trying to see how pooled database connections are affecting the load balancing of commands between a fleet of read only MySQL database replicas. The data source in the connection string is a DNS entry that has several entries which are served to the client in a round robin fashion.
Is it possible to take the database connection object and extract the IP address that the connection is using to connect?
Update
In this code example:
MySql.Data.MySqlClient.MySqlConnection _mySQL = new MySql.Data.MySqlClient.MySqlConnection(_AuroraClusterEndPoint);
Update #2
My question is more of how to determine what IP an active connection is using and not really how to evenly distribute traffic.
Pseudo Code:
MySql.Data.MySqlClient.MySqlConnection _mySQL = new MySql.Data.MySqlClient.MySqlConnection(_AuroraClusterEndPoint);
_mySQL.Open();
Console.WriteLine(_mySQL.ConnectionInfo.IPAddress); //This is the unknown part
_mySQL.Close();
How would I take _mySQL and extract the IP address it is using?
Yes and no,
Don't store the dns hostname in your connection string. Build the connection string on the fly, (anyway you can or want to store the information).
When building the connection string in code lookup the dns alias/host name to get it's ip addresses (should only return 1 ipv4 address)
IPAddress[] ipv4Addresses = Array.FindAll(
Dns.GetHostEntry("hostnamehere").AddressList,
a => a.AddressFamily == AddressFamily.InterNetwork);
Test it and debug if you get multiple addresses.
Once you get the IP you now know what IP address the round robin gave the request, you can log it, then build your connection string with the IP address instead of the host name.
Here's a rough and dirty example I wrote in 5 minutes:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
string ipAddress;
var newConnectionString = SwapConnectionStringDNSWithIP("Server=google.com;Database=myDataBase;Uid=myUsername;Pwd=myPassword;", out ipAddress);
Console.WriteLine(ipAddress);
Console.WriteLine(newConnectionString);
Console.ReadKey(true);
}
public static string SwapConnectionStringDNSWithIP(string connectionString, out string ipAddress)
{
ipAddress = null;
if (string.IsNullOrEmpty(connectionString))
return null;
var dict = new Dictionary<string, string>();
var pParts = connectionString.Split(';');
foreach (var part in pParts)
{
if (part.IndexOf('=') == -1)
break;
var sParts = part.Split('=');
if (sParts.Length != 2)
break;
string key = sParts[0].ToLower().Trim();
string value = sParts[1];
if (!dict.ContainsKey(key))
{
dict.Add(key, value);
}
}
var server = dict.ContainsKey("server") ? dict["server"] : null;
if (server == null)
return null;
var ret = Dns.GetHostEntry(server);
var addresses = ret.AddressList.Select(a => a.GetAddressBytes()).ToArray();
if (addresses != null && addresses.Length > 0)
{
ipAddress = string.Join(".", addresses[0]);
dict["server"] = ipAddress;
var newConnectionString = string.Join(string.Empty, dict.Keys.Select(k => k + "=" + dict[k] + ";").ToArray());
return newConnectionString;
}
return null;
}
}
}
I am working on a utility for managing multiple computers in a specified domain (not necessarily the domain the computer the application is running on is a member of) within a specified directory root. The problem I am running into is once I have the collection of computer names from the external AD OU, I am unable to manage based on computer name because of DNS. Is it possible to perform DNS lookup on an external DNS server provided the IP of DNS server and credentials for that domain?
Here is the code that I have for the initialization process (works within the same domain). Really appreciate any input!
private Task InitializeComputers()
{
try
{
Computers.Clear();
object cLock = new object();
PrincipalContext context = new PrincipalContext(ContextType.Domain, CurrentConfiguration.LDAPAddress,
CurrentConfiguration.DirectoryRoot, ContextOptions.Negotiate,
CurrentConfiguration.AdminUser, CurrentConfiguration.AdminPassword);
ComputerPrincipal computer = new ComputerPrincipal(context);
computer.Name = "*";
PrincipalSearcher searcher = new PrincipalSearcher(computer);
PrincipalSearchResult<Principal> result = searcher.FindAll();
Parallel.ForEach(result, (r) =>
{
ComputerPrincipal principal = r as ComputerPrincipal;
DirectoryObject cObject = new DirectoryObject(CurrentConfiguration)
{
Name = principal.Name
};
lock (cLock)
{
Computers.Add(cObject);
}
});
}
... // Catch stuff here
}
private async Task InitializeConnections()
{
Task[] tasks = Computers.Select(x => x.CheckConnectionAsync()).ToArray();
await Task.WhenAll(tasks);
}
// This is where I need to be able to get the IP Address. Thoughts???
public Task CheckConnectionAsync()
{
return Task.Run(() =>
{
try
{
Ping PingCheck = new Ping();
PingReply Reply = PingCheck.Send(Name); // <--- need IP Address instead
if (Reply.Status == IPStatus.Success)
{
IsAvailable = true;
IPHostEntry host = Dns.GetHostEntry(Name); // Does not work for machines on different domain.
IPAddress = host.AddressList.FirstOrDefault().ToString();
}
else
{
IsAvailable = false;
IsWMIActive = false;
}
}
... // catch stuff here ...
});
}
To follow up, the solution that I found is derived from Heijden's DNS Resolver. I wrote a simple DnsManager class with a single static GetIPAddress method for extracting the IP out of an A Record.
public static string GetIPAddress(string name)
{
Resolver resolver = new Resolver();
resolver.DnsServer = ((App)App.Current).CurrentConfiguration.DNSAddress;
resolver.Recursion = true;
resolver.Retries = 3;
resolver.TimeOut = 1;
resolver.TranportType = TransportType.Udp;
Response response = resolver.Query(name, QType.A);
if (response.header.ANCOUNT > 0)
{
return ((AnswerRR)response.Answer[0]).RECORD.ToString();
}
return null;
}
Then, the updated CheckConnectionAsync method is now written like so:
public Task CheckConnectionAsync()
{
return Task.Run(() =>
{
try
{
IPAddress = DnsManager.GetIPAddress(Name + "." + CurrentConfig.DomainName);
... // check availability by IP rather than name...
}
// catch stuff here...
});
}
As soon as you plan to query dedicated server as DNS source, you have to step aside from default libs. I tried this (if remember correctly) once investigating dedicated DNS requests:
http://www.codeproject.com/Articles/12072/C-NET-DNS-query-component
First of all sry about my english. My problem is i have electronic circuit on press machine. This circuit sending data to my server without a problem. After i recieve data i need to send command to circuit. In LAN its working like a charm. But out of lan circuit dont recieving my command somehow. Any idea how i can send to udp pocked to machine behind NAT ? my code is bellow , ty for any help.
private void ReceiveMessage()
{
while (true)
{
try
{
var remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
var content = _udpClient.Receive(ref remoteIpEndPoint);
if (content.Length > 0)
{
var message = Encoding.ASCII.GetString(content);
var smsg = message.Split('|');
var pin1 = int.Parse(smsg[13]);
var pin2 = int.Parse(smsg[14]);
var isChanged = CheckChanges(smsg[1]);
if (isChanged == 1)
{
**var recvpt = new IPEndPoint(remoteIpEndPoint.Address, remoteIpEndPoint.Port);
var client = new UdpClient();
var cmd1 = "CP1S" + _pin1Time + "F";
var cmd2 = "CP2S" + _pin2Time + "F";
var senddata1 = Encoding.UTF8.GetBytes(cmd1);
var senddata2 = Encoding.UTF8.GetBytes(cmd2);
client.Send(senddata1, senddata1.Length, recvpt);
client.Send(senddata2, senddata2.Length, recvpt);
client.Close();**
// UpdateChanges(smsg[1]);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToStrin<wbr ></wbr>g());
}
}
}
}
Computers that are behind a NAT router are not directly accessible from a remote network. There would need to be rules put in place on your firewall/router to route this traffic to the remote machine. For explicit directions see your WAN/LAN admin. If you don't have one you could try asking over on Server Fault with more information about your network.
I'm trying to ping a server based on an IP Address and a port, using the Ping class,
I have to convert the IP Address to an array of bytes, how am I doing it?
I took this method from somewhere
bool IsConnectedToInternet
{
get
{
Uri url = new Uri("www.abhisheksur.com");
string pingurl = string.Format("{0}", url.Host);
string host = pingurl;
bool result = false;
Ping p = new Ping();
try
{
PingReply reply = p.Send(host, 3000);
if (reply.Status == IPStatus.Success)
return true;
}
catch { }
return result;
}
}
I just have to ping the server based on an IP, not a URL.
Thank you.
Can you not just do this:
public static bool IsConnectedToInternet
{
get
{
using (var ping = new Ping())
{
try
{
var reply = ping.Send("173.194.41.168", 3000);
return reply.Status == IPStatus.Success;
}
catch
{
return false;
}
}
}
}
Although your code snippet does not require it, here is an answer to the question in the title of your post:
You can use System.Net.Dns.GetHostAddresses("www.abhisheksur.com") to get an array of IPAdresses objects representing the addresses of your host. You can then call GetAddressBytes() on an individual IPAddress object to convert it to an array of bytes.
Use the IPAddress class and Ping.Send(IPAddress address) method. If you're trying to convert from IPAddress to bytes, it offers handy hosttonetwork and networktohost methods.
http://msdn.microsoft.com/en-us/library/system.net.ipaddress.aspx
http://msdn.microsoft.com/en-us/library/hb7xxkfx.aspx
Try using the documentation for Ping.Send
Ive seen some php examples of how you can ping an inbox(without sending any mail to it) to check whether it exists. I was wondering if anyone knows if this is possible with .net? If it is Im going to write an app to do a bulk check on list of emails i have captured through my site.
SMTP defines the VRFY command for this, but since abuse by spammers totally overwhelmed the number of legitimate uses, virtually every e-mail server in the world is configured to lie.
What you mean about if you writing "check email"? Without sending some unique link for email owner you can't check this, you can only check syntax of email, and connection to smtp.
public static bool isEmail(string inputEmail)
{
inputEmail = NulltoString(inputEmail);
string strRegex = #"^([a-zA-Z0-9_\-\.]+)#((\[[0-9]{1,3}" +
#"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
#".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
Regex re = new Regex(strRegex);
if (re.IsMatch(inputEmail))
return (true);
else
return (false);
}
smtp check
string[] host = (address.Split('#'));
string hostname = host[1];
IPHostEntry IPhst = Dns.Resolve(hostname);
IPEndPoint endPt = new IPEndPoint(IPhst.AddressList[0], 25);
Socket s= new Socket(endPt.AddressFamily,
SocketType.Stream,ProtocolType.Tcp);
s.Connect(endPt);
No, it is impossible in principle to check if an email exists - independent of language.
There is simply no protocol to do it.
There are some partial solutions, but none of them are reliable.
See How to check if an email address exists without sending an email? for details.
1. Get the MX record for the email provider by using following command:
nslookup -type=mx gmail.com
Make call to tcp client to check if email is valid:
private static void Main(string[] args)
{
var gMail = IsEmailAccountValid("gmail-smtp-in.l.google.com", "aa.aa#gmail.com");
Console.WriteLine($"Gmail account is valid - {gMail.ToString()}");
var live = IsEmailAccountValid("live-com.olc.protection.outlook.com", "aa.aa#live.com");
Console.WriteLine($"Live account is valid - {live.ToString()}");
}
private static byte[] BytesFromString(string str)
{
return Encoding.ASCII.GetBytes(str);
}
private static int GetResponseCode(string ResponseString)
{
return int.Parse(ResponseString.Substring(0, 3));
}
private static bool IsEmailAccountValid(string tcpClient, string emailAddress)
{
TcpClient tClient = new TcpClient(tcpClient, 25);
string CRLF = "\r\n";
byte[] dataBuffer;
string ResponseString;
NetworkStream netStream = tClient.GetStream();
StreamReader reader = new StreamReader(netStream);
ResponseString = reader.ReadLine();
/* Perform HELO to SMTP Server and get Response */
dataBuffer = BytesFromString("HELO Hi" + CRLF);
netStream.Write(dataBuffer, 0, dataBuffer.Length);
ResponseString = reader.ReadLine();
dataBuffer = BytesFromString("MAIL FROM:<YourGmailIDHere#gmail.com>" + CRLF);
netStream.Write(dataBuffer, 0, dataBuffer.Length);
ResponseString = reader.ReadLine();
/* Read Response of the RCPT TO Message to know from google if it exist or not */
dataBuffer = BytesFromString($"RCPT TO:<{emailAddress}>" + CRLF);
netStream.Write(dataBuffer, 0, dataBuffer.Length);
ResponseString = reader.ReadLine();
var responseCode = GetResponseCode(ResponseString);
if (responseCode == 550)
{
return false;
}
/* QUITE CONNECTION */
dataBuffer = BytesFromString("QUITE" + CRLF);
netStream.Write(dataBuffer, 0, dataBuffer.Length);
tClient.Close();
return true;
}
The MX record can be obtained using code:
var lookup = new LookupClient();
var result = lookup.QueryAsync("gmail.com", QueryType.ANY).Result;
var domainName = result.Additionals[result.Additionals.Count - 1].DomainName.Value;
Using above code find the MX lookup and use that MX lookup to check if email is valid or not.
http://www.codicode.com/art/free_asp_net_email_validator_verifier.aspx.
Use the dll reference to your code. It is free both for personal use and redistribution. It checks for the domain name existence without actually sending an email.
This is not foolproof. The best you can do is check syntax and see if the domain name resolves.
Email syntax RegEx:
(?<username>#?[_a-zA-Z0-9-+]+(\.[_a-zA-Z0-9-+]+)*)#(?<domain>[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.(([0-9]{1,3})|([a-zA-Z]{2,3})|(aero|arpa|asia|coop|info|jobs|mobi|museum|name|travel)))
protected bool checkDNS(string host, string recType = "MX")
{
bool result = false;
try
{
using (Process proc = new Process())
{
proc.StartInfo.FileName = "nslookup";
proc.StartInfo.Arguments = string.Format("-type={0} {1}", recType, host);
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.ErrorDialog = false;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
{
if ((e.Data != null) && (!result))
result = e.Data.StartsWith(host);
};
proc.ErrorDataReceived += (object sender, DataReceivedEventArgs e) =>
{
if (e.Data != null)
{
//read error output here, not sure what for?
}
};
proc.Start();
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();
proc.WaitForExit(30000); //timeout after 30 seconds.
}
}
catch
{
result = false;
}
return result;
}