How could I make a mDNS Query with Pcap.net? - vb.net

Problem: I'm looking to make a mDNS packet, while having searching stackflow for options. I tried bonjour and some wrappers but had very limited success, especially when I requested a second time and get socket binding complaints (Which, of course, may have been my code not them).
Since VB.net didn't have a really editable dnsquery that I know of, I'm using the DNS layer in the build DNS packet in pcapdotnet and just kind of making the packet myself layer by layer. I'm thinking it's a good alternative, but I'm kind of lost on how I would do it.
Here's the question we want:
q_name = new QuestionName("_axis-video._tcp.local"),
q_type = QueryConstants.Question.QuestionType.PTR,
q_class = QueryConstants.Question.QuestionClass.IN
Here's my edited BuildDNSPacket function from their standard:
Private Shared Function BuildDnsPacket(destmac As String, domainName As String) As Packet
'get source MAC address of PC
Dim nic = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
Dim source As String = nic(0).GetPhysicalAddress().ToString
Dim sourcearray As Byte() = System.Text.Encoding.ASCII.GetBytes(source)
'format
Dim sourceMacStr As String = ""
For i As Integer = 0 To sourcearray.Count - 1 Step 2
sourceMacStr += Chr(sourcearray(i)) & Chr(sourcearray(i + 1)) & ":"
Next
' Will be filled automatically.
Dim ethernetLayer As New EthernetLayer() With { _
.Source = New MacAddress(sourceMacStr.Substring(0, 17)), _
.Destination = New MacAddress(destmac), _
.EtherType = EthernetType.None _
}
' Will be filled automatically.
Dim ipV4Layer As New IpV4Layer() With { _
.Source = New IpV4Address("1.2.3.4"), _
.CurrentDestination = New IpV4Address(destmac), _
.Fragmentation = IpV4Fragmentation.None, _
.HeaderChecksum = Nothing, _
.Identification = 123, _
.Options = IpV4Options.None, _
.Protocol = Nothing, _
.Ttl = 100, _
.TypeOfService = 0 _
}
' Will be filled automatically.
Dim udpLayer As New UdpLayer() With { _
.SourcePort = 5353, _
.DestinationPort = 5353, _
.Checksum = Nothing, _
.CalculateChecksumValue = False _
}
Dim dnsLayer As New DnsLayer() With { _
.Id = 0, _
.IsResponse = False, _
.OpCode = DnsOpCode.Query, _
.IsAuthoritativeAnswer = False, _
.IsTruncated = False, _
.IsRecursionDesired = False, _
.IsRecursionAvailable = False, _
.FutureUse = False, _
.IsAuthenticData = False, _
.IsCheckingDisabled = False, _
.ResponseCode = DnsResponseCode.NoError, _
.Queries = {New DnsQueryResourceRecord(New DnsDomainName(domainName), DnsType.Ptr, DnsClass.Any)}, _
.Answers = Nothing, _
.Authorities = Nothing, _
.Additionals = Nothing, _
.DomainNameCompressionMode = DnsDomainNameCompressionMode.All _
}
Dim builder As New PacketBuilder(ethernetLayer, ipV4Layer, udpLayer, dnsLayer)
Return builder.Build(DateTime.Now)
End Function
The main differences is my changing the DnsType to PTR and the port to 5353.
Question: What else should I add or change to make it mDNS? What could I put into the domainName? Should I vary the dnsclass?
All or any suggestions are definitely welcomed.

I am answering my question in case others who need to do mDNS in vb.net needs this:
Solution: I didn't need to add anything to the DNS layer to make this work. I changed the DNS layer to below:
Dim dnsLayer As New DnsLayer() With { _
.Id = 0, _
.IsResponse = False, _
.OpCode = DnsOpCode.Query, _
.IsAuthoritativeAnswer = False, _
.IsTruncated = False, _
.IsRecursionDesired = False, _
.IsRecursionAvailable = False, _
.FutureUse = False, _
.IsAuthenticData = False, _
.IsCheckingDisabled = False, _
.ResponseCode = DnsResponseCode.NoError, _
.Queries = {New DnsQueryResourceRecord(New DnsDomainName(domainName), DnsType.Ptr, DnsClass.Any)}, _
.Answers = Nothing, _
.Authorities = Nothing, _
.Additionals = Nothing, _
.DomainNameCompressionMode = DnsDomainNameCompressionMode.All _
}
I made the output address of the Ipv4 layer to be the multicast address of "224.0.0.251", changed my ports to 5353, and used the domain name of the question I listed above.
Here's a wireshark to show the responses:

Related

local variable 'request' cannot be referred to before it is declared

Dim list = New List(Of ECozum.HPM.Helper.Models.CustomData)
list.Add(cdata)
Dim request = New HttpPostRequestMessage() With { _
.User = New User() With { _
.Verify = 1, _
.VerifyFailAct = 1, _
.Id = 2 _
}, _
.Order = New Order() With { _
.DateTime = DateTime.UtcNow.ToString("u"), _
.Reference = Guid.NewGuid().ToString() _
}, _
.Payment = New Payment() With { _
.CData = list, _
.Method = New List(Of Integer)() From { _
-1 _
}, _
.Amount = tutar, _
.AmntEdit = 1, _
.SuccessUrl = "http://localhost:50/sonuc.aspx?s=basarili", _
.FailUrl = "http://localhost:50/sonuc.aspx?s=basarisiz", _
.ReturnUrl = "http://localhost:50/sonuc.aspx?s=return" _
}, _
.HashMethod = CInt(Hash.HashType.HMACSHA256) _
}
In this page I get the error:
"local variable 'request' cannot be referred to before it is declared"
at line: tutar = Request.QueryString("tutar")
Dim request = New HttpPostRequestMessage() change this line. Use any random name like 'requestobject' or 'rnd123'. Since you have it declared as a variable, it is conflicting with default request object.

Exchange Web service (EWS) chain FindItemType for itemItemclas & messageIsRead

High fellow coders.
I'm using the raw exchange web service, referenced in my SSIS script task.
My issue is that when I enumerate items in a mailbox or folder, Not only am I interested in only those items that have not been read, but I want to ignore all the system type messages. so I only want items, specifically messages, who's "itemclass" is "IPM.Note" nothing else.
Here is a definitive list of Item Types and Message classes
https://msdn.microsoft.com/en-us/library/office/ff861573.aspx
my code which works successfully for unread items in the inbox
'declare my find criteria, return only the IDs, from the inbox, for unread items
Dim reqFindUnreadMailInInbox As FindItemType = New FindItemType With _
{.Traversal = ItemQueryTraversalType.Shallow _
, .ItemShape = New ItemResponseShapeType With {.BaseShape = DefaultShapeNamesType.IdOnly} _
, .ParentFolderIds = New DistinguishedFolderIdType(0) {New DistinguishedFolderIdType With {.Id = DistinguishedFolderIdNameType.inbox}} _
, .Restriction = New RestrictionType With _
{.Item = New IsEqualToType With _
{.Item = New PathToUnindexedFieldType With {.FieldURI = UnindexedFieldURIType.messageIsRead} _
, .FieldURIOrConstant = New FieldURIOrConstantType With {.Item = New ConstantValueType With {.Value = "0"}} _
} _
} _
}
'go fetch the response from exchange
Dim resFindItemResponse As FindItemResponseType = esb.FindItem(reqFindUnreadMailInInbox)
Dim resFindFolderMessages As FindItemResponseMessageType = resFindItemResponse.ResponseMessages.Items(0)
Dim resFolderItems As ArrayOfRealItemsType = Nothing '= New ArrayOfRealItemsType
The problem I have is I want to add a restriction on the itemClass that is returned. But cannot figure out how to add a second Restriction to the request. This is what the restriction would look like if I changed my search to pull all items from the inbox regardless of read state but restricting only to itemClass IPM.Note (note the addition of the paged result)
Dim reqFindUnreadMailInInbox As FindItemType = New FindItemType With _
{.Item = New IndexedPageViewType With {.MaxEntriesReturnedSpecified = True, .MaxEntriesReturned = "100", .BasePoint = IndexBasePointType.Beginning, .Offset = 0} _
, .Traversal = ItemQueryTraversalType.Shallow _
, .ItemShape = New ItemResponseShapeType With {.BaseShape = DefaultShapeNamesType.IdOnly} _
, .ParentFolderIds = New DistinguishedFolderIdType(0) {New DistinguishedFolderIdType With {.Id = DistinguishedFolderIdNameType.inbox}} _
, .Restriction = New RestrictionType With _
{.Item = New IsEqualToType With _
{.Item = New PathToUnindexedFieldType With {.FieldURI = UnindexedFieldURIType.itemItemClass} _
, .FieldURIOrConstant = New FieldURIOrConstantType With {.Item = New ConstantValueType With {.Value = "IPM.Note"}} _
} _
} _
}
The next chunk of code checks for an error, and proceeds to enumerate the IDs and fetch the items in one call. If I debug the resGetitem after the response has returned, I can drill down and look at each items class by looking in the immediate window with this query
?directcast(directcast(resGetItem.ResponseMessages.Items(0),ItemInfoResponseMessageType).Items.Items(0),MessageType)
and I can see "REPORTS.IPM.Note.NDR". The question is how can I filter the initial call to restrict to only "IPM.Note"
'if there was an error bur out and report
If resFindFolderMessages.ResponseClass = ResponseClassType.[Error] Then
Throw New Exception(resFindFolderMessages.MessageText)
Else
TraceLog.AppendLine("Inbox found, ID pulled back")
If Not IsNothing(DirectCast(resFindFolderMessages.RootFolder.Item, ArrayOfRealItemsType).Items) Then
resFolderItems = resFindFolderMessages.RootFolder.Item
TraceLog.AppendLine(String.Format("found {0} unread mail - start processing", resFolderItems.Items.Count))
'So we have the array of ids for the emails, now fetch the emails themselves
Dim resItemIDs As ItemIdType() = Nothing
'collect the ids up
For x As Integer = 0 To resFolderItems.Items.Count - 1
If IsNothing(resItemIDs) Then ReDim resItemIDs(0) Else ReDim Preserve resItemIDs(resItemIDs.Length)
resItemIDs(x) = resFolderItems.Items(x).ItemId
Next
'go get the email messages
Dim resGetItem As GetItemResponseType = esb.GetItem(New GetItemType With { _
.ItemShape = New ItemResponseShapeType With {.BaseShape = DefaultShapeNamesType.AllProperties _
, .BodyType = BodyTypeResponseType.Text _
, .BodyTypeSpecified = True} _
, .ItemIds = resItemIDs})
'declare and fill up the message array that we are going to return
Dim resItemMessage As ItemType() = Nothing
For x As Integer = 0 To resGetItem.ResponseMessages.Items.Length - 1
If IsNothing(resItemMessage) Then ReDim resItemMessage(0) Else ReDim Preserve resItemMessage(resItemMessage.Length)
resItemMessage(x) = DirectCast(resGetItem.ResponseMessages.Items(x), ItemInfoResponseMessageType).Items.Items(0)
Next
'pass back the emails
Return resItemMessage
Else
TraceLog.AppendLine("no unread mail found closing out")
Return Nothing
End If
End If
========== UPDATE ============
With a nudge in the right direction from Glen Scales we have Success! EWS is a mine field of types and derived types.
'create the finditemtype and load the restrictions
'first only the unread messages
'secondly, only of type "IPM.Note" ie just emails
Dim reqFindUnreadMailInInbox As FindItemType = New FindItemType With _
{.Traversal = ItemQueryTraversalType.Shallow _
, .ItemShape = New ItemResponseShapeType With {.BaseShape = DefaultShapeNamesType.IdOnly} _
, .ParentFolderIds = New DistinguishedFolderIdType(0) {New DistinguishedFolderIdType With {.Id = DistinguishedFolderIdNameType.inbox}} _
, .Restriction = New RestrictionType With {.Item = New AndType With { _
.Items = New IsEqualToType() { _
New IsEqualToType With {.Item = New PathToUnindexedFieldType With { _
.FieldURI = UnindexedFieldURIType.messageIsRead} _
, .FieldURIOrConstant = New FieldURIOrConstantType With {.Item = New ConstantValueType With {.Value = "0"}} _
} _
, New IsEqualToType With {.Item = New PathToUnindexedFieldType With { _
.FieldURI = UnindexedFieldURIType.itemItemClass} _
, .FieldURIOrConstant = New FieldURIOrConstantType With {.Item = New ConstantValueType With {.Value = "IPM.Note"}} _
} _
}}}}
Thanks goes to Glen Scales!
You need to use the AndType https://msdn.microsoft.com/en-us/library/office/exchangewebservices.andtype(v=exchg.150).aspx
Then define and add two isEqual Restrictions to that eg
RestrictionType restriction = new RestrictionType();
AndType andType = new AndType();
andType.Items = new SearchExpressionType[] { IsEqual1,IsEqual2 };
restriction.Item = andType;
Cheers
Glen

cosign-api add reason to SOAP request

I am trying to add a reason to the soap request for a COSign SOAP signing.
Can anyone provide me with a VB or C# example of how to do this?
Thank you
I found the answer.
Below for anyone with the same problem
Dim Configs(1) As DSSSoapClient.ConfValueType
Dim Config As New DSSSoapClient.ConfValueType() With { _
.ConfValueID = DSSSoapClient.ConfIDEnum.Reason, _
.Item = "Hierdie is die Rede vir al my harseer"
}
Configs(1) = Config
' Build complete request object
Dim signRequest As New DSSSoapClient.SignRequest() With { _
.InputDocuments = New DSSSoapClient.RequestBaseTypeInputDocuments() With { _
.Items = New DSSSoapClient.DocumentType() {document} _
}, _
.OptionalInputs = New DSSSoapClient.RequestBaseTypeOptionalInputs() With { _
.SignatureType = signatureType, _
.ClaimedIdentity = claimedIdentity, _
.SAPISigFieldSettings = sigFieldSettings, _
.ReturnPDFTailOnly = True, _
.ConfigurationValues = Configs, _
.ReturnPDFTailOnlySpecified = True _
} _
}

How to use the vb equivalent of ++ for an index property in a Linq query projecting a new type

I'd normally do this in C# but since I've got to get this code in this particular assembly which is a vb.net one, I'm stuck.
Here's my linq query:
Dim i As Integer = 0
Dim oldAndCurrentIntersectionOnNames = From currentApplicant In currentApplicants _
Group Join oldApplicant In oldApplicants _
On _
New With {Key .FirstName = currentApplicant.FirstName, _
Key .LastName = currentApplicant.LastName} _
Equals _
New With {Key .FirstName = oldApplicant.FirstName, _
Key .LastName = oldApplicant.LastName} Into applicants = Group _
From applicant In applicants.DefaultIfEmpty(New ApplicantNameDetails()) _
Select New ApplicantNameDetails() With _
{ _
.Index = i+=1, _
.FirstName = CStr(IIf(Not currentApplicant.FirstName Is Nothing, currentApplicant.FirstName, Nothing)), _
.OldFirstName = CStr(IIf(Not applicant.FirstName Is Nothing, applicant.FirstName, Nothing)), _
.LastName = CStr(IIf(Not currentApplicant.LastName Is Nothing, currentApplicant.LastName, Nothing)), _
.OldLastName = CStr(IIf(Not applicant.LastName Is Nothing, applicant.LastName, Nothing)) _
}
You'll see the .Index = i+=1
This was my attempt to do what I'd quite happily do in C# (i.e. Index = i++) in VB. Unfortunately the VB compiler doesn't like that.
Has anybody got any suggestions as to how I'd do this in VB.
Thanks in advance
Essentially, you can’t. If you want the Linq query to get consecutive values, use a special (so-called “generator”) class that has an IncrementAndGet (or simply Next) method for your integer.
class IntegerGenerator
private state as integer = 0
public function Next() as integer
dim oldState = state
state += 1
return oldState
end function
end class
There is an overload of the Select method that lets you use the index of the item on the result collection. http://msdn.microsoft.com/en-us/library/bb534869.aspx
You could split your query in two parts to use it (untested)
Dim q = From currentApplicant In currentApplicants _
Group Join oldApplicant In oldApplicants On _
New With {Key.FirstName = currentApplicant.FirstName, _
Key.LastName = currentApplicant.LastName} _
Equals _
New With {Key.FirstName = oldApplicant.FirstName, _
Key.LastName = oldApplicant.LastName} Into applicants = Group _
From applicant In applicants.DefaultIfEmpty(New ApplicantNameDetails())
Dim oldAndCurrentIntersectionOnNames = _
q.Select(Function(x, i) New ApplicantNameDetails() With _
{ _
.Index = i, _
.FirstName = CStr(IIf(Not x.currentApplicant.FirstName Is Nothing, x.currentApplicant.FirstName, Nothing)), _
.OldFirstName = CStr(IIf(Not x.applicant.FirstName Is Nothing, x.applicant.FirstName, Nothing)), _
.LastName = CStr(IIf(Not x.currentApplicant.LastName Is Nothing, x.currentApplicant.LastName, Nothing)), _
.OldLastName = CStr(IIf(Not x.applicant.LastName Is Nothing, x.applicant.LastName, Nothing)) _
})

LINQ OrderBy sort Problem

I have a LINQ Query:
bikersList = (From c In ngBikersDataContext.Reg_Bikers _
Order By c.L_Name _
Select New Bikers() With { _
.BikerID = c.BikerID, _
.F_Name = c.F_Name, _
.M_Name = c.M_Name, _
.L_Name = c.L_Name, _
.MyID = c.MyID, _
.Site = c.Site.GetValueOrDefault, _
.bk_Building = c.bk_Building, _
.bk_City = c.bk_City, _
.bk_Zip = c.bk_Zip.GetValueOrDefault, _
.bk_Phone = c.bk_phone, _
.email = c.email, _
.DeptZone = c.DeptZone, _
.QuartID = c.QuartID.GetValueOrDefault, _
.BikerDays = c.BikerDays.GetValueOrDefault, _
.BikerMiles = c.BikerMiles.GetValueOrDefault, _
.BikerTime = c.BikerTime.GetValueOrDefault, _
.BKLockID = c.BKLockID.GetValueOrDefault, _
.bk_Start_DT = c.bk_Start_DT, _
.bk_End_DT = c.bk_End_DT, _
.bk_Quarter = c.bk_Quarter.GetValueOrDefault, _
.bk_Year = c.bk_Year.GetValueOrDefault, _
.bk_Comments = c.bk_Comments, _
.IsActive = c.IsActive.GetValueOrDefault _
}).ToList()
This works great and sorts on L_Name. But I am trying to allow the user to sort the gridview themselves. So I am passing in the SortExpression as a string. But I don't know how to incorperate the SortExpression into the LINQ Query.
I tried
Order By c. & SortExpression
But that did not work.
You should check out something called a Dynamic Query in Linq.
Using the LINQ Dynamic Query Library
Here's an article that talks about dynamic sorting with linq using a sortexpression string:
http://www.codeproject.com/KB/recipes/Generic_Sorting.aspx
Basically, you'll need to build the expression tree manually.
(this code is from the link above)
Public Function Sort(ByVal source As IEnumerable(Of T), _
ByVal sortBy As String, _
ByVal sortDirection As String) As IEnumerable(Of T)
Dim param = Expression.Parameter(GetType(T), "item")
Dim sortExpression = Expression.Lambda(Of Func(Of T, Object))_
(Expression.Convert(Expression.[Property](param, sortBy), _
GetType(Object)), param)
Select Case sortDirection.ToLower
Case "asc"
Return source.AsQueryable().OrderBy(sortExpression)
Case Else
Return source.AsQueryable().OrderByDescending(sortExpression)
End Select
End Function