I am setting up a peer 2 peer network and i cant find if my 2 subnets will both have a network and broadcast?
x.x.x.0 and x.x.x.127 will be my first subnet's broadcast/network.
x.x.x.128 and x.x.x.255 will be the second subnet broadcast/network addresses.
or is it just x.x.x.0 and x.x.x.255 that are the broadcast/network addresses?
This is defined by the subnetmask, which is why you normally write IP addresses as:
192.168.1.24/24
This means the network address is 192.168.1.0 and the broadcast address 192.168.1.255. The network part of the is /24 bits, and host id is 8 bits. For the broadcast address you always set all the host id bits to 1 (8 bits set to one = 255), and for the network address you set it to 0.
Both subnet's will have the broadcast/network ip's so there will be -4 ip in the total amount of valip ip addresses in the entire subnet.
Related
I want to capture some network traffic with the filter like "src x.x.x.x and dst x.x.x.x".
Ususally it works, but it doesn't work when the network traffic is encapsulated by protocls like Gre or Vxlan.
For example, the Gre encapsulate a message like this:
Ethernet II, Src: VMware_91:f6:ad (00:0c:29:91:f6:ad), Dst: VMware_dc:c7:71 (00:0c:29:dc:c7:71)
Internet Protocol Version 4, Src: 10.75.2.161, Dst: 10.75.2.140
Generic Routing Encapsulation (Transparent Ethernet bridging)
Ethernet II, Src: Micro-St_e3:51:57 (4c:cc:6a:e3:51:57), Dst: VMware_91:f6:ad (00:0c:29:91:f6:ad)
Internet Protocol Version 4, Src: 10.75.2.11, Dst: 10.75.2.160
So what should I do to capture those inner traffic?
I use "src 10.75.2.160" to capture but it tcpdump captured nothing.
tcpdump -i eth0 "src 10.75.2.11"
It doesn't work.
I use "ip[54:4]" to capture, it works, but my leader tell me it's not accurate.
So what else can I try?
I don't know how accurate your leader wants the filter, but if we can make a few assumptions about the outer IP and GRE headers, then the filter isn't too complicated. So here are the 2 assumptions:
The outer IP header is a standard 20 bytes. If this isn't the case or can't be relied upon, then everywhere I use 20 in the filter will need to be replaced with the IP header length calculation, which is (ip[0] & 0x0f) * 4.
The GRE header is a standard size of 4 bytes. If options are present and you can guarantee that all GRE headers are exactly the same size, then you can substitute 4 for the actual GRE header length, but if GRE options could vary, then it should still be possible to specify a capture filter that works with any size GRE header, but it will be much more complicated and hard to follow. I leave that as an exercise for the reader.
With those assumptions out of the way, here's a filter that would be the equivalent of "src 10.75.2.11" but for the inner source IP address of a IP/GRE/IP packet:
(ip proto 47) && (ip[20 + 2:2] = 0x0800) && (ip[20 + 4 + 12:4] = 0x0a4b0x0b)
Explanation:
ip proto 47: This captures only IP/GRE packets as GRE is assigned protocol number 47.
ip[20 + 2:2] = 0x0800: Since 0x0800 is the assigned Ethertype for IPv4, this captures only GRE packets where the Protocol Type field is IP, so only IP/GRE/IP packets. (NOTE: RFC 1701 states, "The Protocol Type field contains the protocol type of the payload packet. In general, the value will be the Ethernet protocol type field for the packet.")
ip[20 + 4 + 12:4] = 0x0a4b020b: This captures only the IP/GRE/IP packets where the source IP address field of the inner IP header is 10.75.2.11. (NOTE: To get 0x0a4b020b from 10.75.2.11, you just need to convert each decimal octet to hexadecimal and combine them into a single 4 byte value.)
To verify the resulting BPF code, you can run tcpdump with the -d option to check that the filter meets your expectations, for example:
tcpdump -i eth0 "(ip proto 47) && (ip[20 + 2:2] = 0x0800) && (ip[20 + 4 + 12:4] = 0x0a4b020b)"
You should see output of the following form:
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 9
(002) ldb [23]
(003) jeq #0x2f jt 4 jf 9
(004) ldh [36]
(005) jeq #0x800 jt 6 jf 9
(006) ld [50]
(007) jeq #0xa4b020b jt 8 jf 9
(008) ret #262144
(009) ret #0
If you're not familiar with BPF code, then I would suggest further reading elsewhere, as providing a BPF tutorial here is beyond the scope of this answer.
Finally, if you need to filter for the source IP address whether it's in the outer IP header or the inner IP header, then you can basically just combine the 2 filters, i.e.:
"(ip src 10.75.2.11) || ((ip proto 47) && (ip[20 + 2:2] = 0x0800) && (ip[20 + 4 + 12:4] = 0x0a4b020b))"
When you want to bind to port in C you have to use htons(port) to convert the port from host byte order to network byte order. This happens because the port number is copied directly to the TCP packets, so they have to match on little-endian and big-endian machines.
Consider the following example in C:
int port = 5000;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
Notice the use of htons. Now, if you run netstat -anp --tcp (on Linux) you'll see that 0.0.0.0:5000 is being listened. It looks like the port number uses host endianness.
Now, a question arises: if port number is host-endian in URL, does this mean that a big-endian client can't use http://a.b.c.d:5000 URL to connect to a little-endian server listening on 0.0.0.0:5000?
No, you're almost certainly misapplying the rules at the wrong abstraction level.
The local browser, in all likelihood, will grab the :5000 string off the end of the URL and use that to create the integer 5000 in host format. It will then pass that to htons as part of constructing the session, in exactly the same way your code snippet does.
And, voila, the structures contain the correct network order.
I trying to use mosquitto broker for an IoT application. I have a embedded hardware, actually not much documented/exampled on the internet. I've succesfully implemented an TCP client on this hardware, and now i can send/listen messages throught any port i want via TCP and i listen via netcat. But when i tried to connect mosquitto, it doesn't accept the literal language. I digged on the internet. The broker take messages like shown below, but even this one not working.
I can not found any documentation. I even tried to watch Wireshark packages, and i can not find any pattern. Any help will appreciated.
$ echo -en "\x10\x0d\x00\x04MQTT\x04\x00\x00\x00\x00\x01a" |nc localhost 1883|hd
00000000 20 02 01 00 | ...|
00000004
Had a similar usecase like you and this is how I managed to decode this message and create my own connect request.
echo -en "\x10\x0d\x00\x04MQTT\x04\x00\x00\x00\x00\x01a" |nc localhost 1883
The above message is broken down as follows:
nc localhost 1883, opens a tcp socket to the mqtt port 1883 (to the broker (on localhost) listening to port 1883)
\x10\x0d\x00\x04MQTT\x04\x00\x00\x00\x00\x01a is the connect packet sent to the socket that was opened. This connect packet can be broken down as follows:
\x10: MQTT connect packet (Constitutes the control field with the 1st 4 bits representing the command type "0001" and the 2nd 4 bits the control flag.
\x0d: Remaining length: is the total length of both the variable header and the payload. This needs to be set after the whole payload is complete.
*Variable header = Protocol Name + Protocol level + Connect Flag byte + Keep Alive
Payload = ClientId, username, password, e.t.c, each entry is provided in the format lengthOfEntry + Entry e.g for a clientId and username and password, this gives: lengthOfClientId + ClientId + lengthOfUsername + Username + lengthOfPassword + Password. *Note: the length is always provided as two bytes.
\x00\x04MQTT: Represents the protocol name "MQTT". The first two bytes 0x00 and 0x04 are the protocol length and MQTT is then the protocol. These give a total of 6 bytes.
\x04: is the protocol level. From MQTT specification, the value of the Protocol Level field for the version 3.1.1 of the protocol is 4 (0x04)
\0x00: is the connect flag byte. each byte is represented as follows:
UsernameFlag|PasswordFlag|Will Retain|Will|QoS|Will Flag|CleanSession|Reserved. 0x00 means none of the flags are set and persistent sessions will be used. Hence the payload doesn't require a username or password as will be seen in the payload bytes.
\0x00\0x00: two bytes that represent the keepAlive time. In this case 0 is provided which means that the server is not required to disconnect the client on grounds of inactivity. keepalive mechanism is turned off
The next bytes are already the payload. Since the connect flag was set such that no username or password is required, then we only have to provide the client id. In the above example the clientid is "a". This is of length 1 byte.
\0x00\0x01: represents the length of the clientId. since we have the character "a" as the clientId we have just the length 1. The length is always given in 16bit (2 bytes).
a: the clientId.
If we count all the bytes, we come up to a total of 13 bytes which gives us our remaining le0gnth as 0x0d.
If you need to add a username and password, set the connect flag accordingly 0b11000000 = 0xC0. The username and password are added to the payload right after the clientId in the order lengthofClientId, clientId, lengthOfUSername, Username, LengthofPassword, Password. The reminaining length needs to be adjusted to reflect this.
Tip: The variable header has a fixed number of bytes of 10. The payload length always depends on the data provided. the length of each element is always 2 bytes. so for the above case, we have a clientid of 1 byte and the length which take 2 bytes to give a total of 10 + 2 + 1 = 13.
I hope this helps you out and answers your question.
Useful links:
https://openlabpro.com/guide/mqtt-packet-format/
http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718024
So there are several sites that will calculate your link-local ipv6 address for you, like this one right here.
Nevertheless, it does not give any useful into as to how this address is calculated nor what the input parameters are. So what is the procedure(or algorithm)to compute a link local ipv6 address if one knows ones ipv4 address, subnet mask, and gateway address? I'm doing a project with SCTP sockets that uses ISATAP network tunneling and the LL ipv6 address is used in constructing the ISATAP address.
Appendix A of RFC 4291 describes the method for computing a modified EUI-64 from a MAC address. Once you have the modified EUI-64, you just put it in the lower 64 bits of the address and put fe80:: in the top 64 bits.
Basically you flip the 7th bit of the MAC address, and pack its first 24 bits (including the flipped bit), then fffe, then the lower 24 bits of the MAC address, resulting in 64 bits total.
That being said, your question is how to derive the link local address from the IPv4 address and subnet mask. That, you can't do. The IPv4 address and subnet mask (if indeed there is one – IPv6 does not require that IPv4 be running at all on the same interface) has nothing to do with the IPv6 address and the two aren't related in any way. The IPv4 gateway address (again, if there is one) is even less relevant.
The link-local address can be based on the MAC address per RFC 4862 or randomly generated as per RFC 4941.
Normally this should be limited to global scope, but some systems extend this privacy extension implementation to link-local scope. Follow this question on serverfault for discussion of the topic.
The previous answers failed to note that there is a defined procedure for generating a link local IPv6 address from an IPv4 address when using ISATAP, and there is a different process for generating a link local IPv6 address from a MAC address. The two things are unrelated.
For ISATAP, the 32-bit IPv4 address is prepended wit the 96 bits of either fe80::200:5efe or fe80::200:5efe to get the 128-bit IPv6 link-local address.
For MAC to IPv6, the 48-bit MAC address is split in half, 16 bits are inserted in the middle, those bits being ff:fe, then it is prepended by the 64-bit link-local prefix fe80::, and finally the 7th bit in the 5th IPv6 segment is flipped, to get the 128-bit IPv6 link-local address.
The following code provides examples showing how to use the The IPAddress library to do the conversions in either Java or Go. Disclaimer: I am the project manager of those libraries.
These examples also help to visualize the conversions described above.
Go:
func convertToIsatap(ipv4Str string, isGlobal bool) string {
ipv4Address := ipaddr.NewIPAddressString(ipv4Str).GetAddress().ToIPv4()
zero := &ipaddr.IPv6AddressSegment{}
segments := make([]*ipaddr.IPv6AddressSegment, ipaddr.IPv6SegmentCount)
segments[1], segments[2], segments[3], segments[4] = zero, zero, zero, zero
segments[0] = ipaddr.NewIPv6Segment(0xfe80)
segments[5] = ipaddr.NewIPv6Segment(0x5efe)
if isGlobal {
segments[4] = ipaddr.NewIPv6Segment(0x200)
}
ipv6Address, _ := ipv4Address.GetIPv6Address(ipaddr.NewIPv6Section(segments))
return ipv6Address.String()
}
func convertToLinkLocalIPv6(macAddr string) string {
macAddress := ipaddr.NewMACAddressString(macAddr).GetAddress()
ipv6LinkLocal, _ := macAddress.ToLinkLocalIPv6()
return ipv6LinkLocal.String()
}
fmt.Println("1.2.3.4 becomes ISATAP " +
convertToIsatap("1.2.3.4", true))
fmt.Println("aa:bb:cc:11:22:33 becomes " +
convertToLinkLocalIPv6("aa:bb:cc:11:22:33"))
Java:
static String convertToIsatap(String ipv4Str, boolean isGlobal) {
IPv4Address ipv4Address = new IPAddressString(ipv4Str).getAddress().toIPv4();
IPv6AddressSegment zeroSeg = new IPv6AddressSegment(0);
IPv6AddressSegment segments[] =
new IPv6AddressSegment[IPv6Address.SEGMENT_COUNT - 2];
segments[1] = segments[2] = segments[3] = segments[4] = zeroSeg;
segments[0] = new IPv6AddressSegment(0xfe80);
segments[5] = new IPv6AddressSegment(0x5efe);
if(isGlobal) {
segments[4] = new IPv6AddressSegment(0x200);
}
return ipv4Address.getIPv6Address(
new IPv6AddressSection(segments)).toString();
}
static String convertToLinkLocalIPv6(String macStr) {
MACAddress macAddress = new MACAddressString(macStr).getAddress();
return macAddress.toLinkLocalIPv6().toString();
}
System.out.println("1.2.3.4 becomes ISATAP " +
convertToIsatap("1.2.3.4", true));
System.out.println("aa:bb:cc:11:22:33 becomes " +
convertToLinkLocalIPv6("aa:bb:cc:11:22:33"));
The output is the same for both examples:
1.2.3.4 becomes ISATAP fe80::200:5efe:102:304
aa:bb:cc:11:22:33 becomes fe80::a8bb:ccff:fe11:2233
More of a theoretical question. Yes, I know those types of questions are frowned upon here. But suppose APIs like MaxMind GeoIP's didn't exist, and you wanted to build a service that translated IP addresses to the city it's in. What would you do? How would you go about solving that problem?
Use the whois database to find out who the IP is allocated to.
Use DNS to do a reverse lookup on the IP address.
Use traceroute to guess the location based on the routers leading up to the host
As an example, lets look at stackoverflow.com (64.34.119.12)
$ whois 64.34.119.12 | egrep "(OrgName)|(City)|(State)|(Country)"
OrgName: Peer 1 Network Inc.
City: New York
StateProv: NY
Country: US
whois shows us that they're probably in NY, NY.
$ host 64.34.119.12
12.119.34.64.in-addr.arpa domain name pointer stackoverflow.com.
Reverse DNS (PTR record) doesn't help here. However, a lot of ISPs do have region specific reverse DNS entries that can help with this process (especially for dynamically assigned hosts). As an example:
$ host 24.25.195.1
1.195.25.24.in-addr.arpa domain name pointer sndgca-dns-cac-01.san.rr.com.
This host is obviously identified and located by it's PTR record: a Time Warner (Road Runner) caching DNS server in San Diego, CA.
Now, back to the stackoverflow.com locating process:
$ traceroute stackoverflow.com
traceroute to stackoverflow.com (64.34.119.12), 64 hops max, 40 byte packets
ms
(... removed the first few hops ...)
8 ae-6-6.ebr1.Chicago1.Level3.net (4.69.140.189) 30.9 ms 28.855 ms 25.183 ms
9 ae-2-2.ebr2.NewYork2.Level3.net (4.69.132.66) 54.373 ms 54.197 ms 48.171 ms
10 ae-6-6.ebr2.NewYork1.Level3.net (4.69.141.21) 48.250 ms 50.712 ms 51.293 ms
11 ae-62-62.csw1.NewYork1.Level3.net (4.69.148.34) 59.493 ms ae-82-82.csw3.NewYork1.Level3.net (4.69.148.42) 51.694 ms ae-62-62.csw1.NewYork1.Level3.net (4.69.148.34) 58.315 ms
12 ae-3-89.edge1.NewYork1.Level3.net (4.68.16.142) 51.529 ms ae-2-79.edge1.NewYork1.Level3.net (4.68.16.78) 50.77 ms ae-3-89.edge1.NewYork1.Level3.net (4.68.16.142) 50.567 ms
13 10ge-te-1-1.nyc-75bre-dis-2.peer1.net (216.187.115.77) 50.776 ms 51.193 ms 56.166 ms
14 gig2-0.nyc-gsr-b.peer1.net (216.187.123.5) 54.994 ms 58.813 ms 51.794 ms
15 gwny01.stackoverflow.com (64.34.41.58) 54.121 ms 52.65 ms 54.166 ms
16 * * *
(... remaining time outs removed ...)
The traceroute output confirms our suspicion that stackoverflow.com is hosted in NY, NY.
That's one way to tackle geolocation without an API.
Im really guessing here but this may work.
IP ranges are assigned by IANA to regional providers. There are five of them. In turn each regional provider assign IP ranges to end users and internet service provides.
If you can get/buy the information from the regional providers and their ISP clients you are in business.