[squeak-dev] NetNameResolver/ifconfig/interfaces

Levente Uzonyi leves at elte.hu
Sat Mar 13 23:14:07 UTC 2010


On Sat, 13 Mar 2010, Alexander Lazarević wrote:

> Isn't http://bugs.squeak.org/view.php?id=7392 just about this?

It seems to be. There seem to be no way to get the list of interfaces or 
the interface of a local ip address.


Levente

>
> Alex
>
> On Sat, Mar 13, 2010 at 23:52, Levente Uzonyi <leves at elte.hu> wrote:
>> On Sat, 13 Mar 2010, John M McIntosh wrote:
>>
>>> Ok, well I spent the evening looking into this. It's unclear if reverting
>>> the new/old socket stuff in Pharo is a good idea,
>>> or if we just adjust things a bit in the name lookup that would solve
>>> things. There are two questions to resolve
>>>
>>> (1) Do we want to return an IPV4 address from the network lookup? or an
>>> IPV6 address?
>>> (2) What do we do when we have 2 or more active IP interfaces on the
>>> machine, prompt for which one to use? Pick one at random, use the first or
>>> last one?
>>
>> What about creating a new primitive which would return a list with ip
>> address - interface pairs. The list would contain all ip addresses so we can
>> solve the problem in smalltalk. If we later find that the initial solution
>> was wrong, we can change it without touching the vm code.
>>
>>
>> Levente
>>
>>>
>>> If the community can decide what to do, then we can propose a solution.
>>>
>>> So how it works.
>>>
>>> NetNameResolver localHostAddress
>>>
>>> fe80::21c:42ff:fe00:9%en5(otter-2.local),0(0)
>>>
>>> Gah... what's that?
>>>
>>> Well the interface is:
>>>
>>> en5: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu
>>> 1500
>>>        inet6 fe80::21c:42ff:fe00:9%en5 prefixlen 64 scopeid 0x8
>>>        inet 10.37.129.2 netmask 0xffffff00 broadcast 10.37.129.255
>>>        ether 00:1c:42:00:00:09
>>>        media: autoselect status: active
>>>        supported media: autoselect
>>>
>>> Thus it's giving me an IPV6 address.
>>>
>>> The chore is more complicated that one would care to see. I see Microsoft
>>> had a hand in defining the spec.
>>>
>>> So it first asks the gethostname for the name of the host.  As an example
>>> my macbook pro has
>>> Otter-2.local
>>>
>>> which is what
>>> [otter-2:~] johnmci% hostname
>>> Otter-2.local
>>>
>>> That's a bonjour assigned name since if I do
>>> [otter-2:~] johnmci% nslookup Otter-2.local
>>> Server:         192.168.1.7
>>> Address:        192.168.1.7#53
>>>
>>> ** server can't find Otter-2.local: NXDOMAIN
>>>
>>>
>>> Then we are off to:
>>>
>>> getnameinfo
>>>
>>> which returns a chain of  IPV4 and IPV6  address that Otter-2.local would
>>> resolve to.
>>> In this case there are six address, broken in to IPV6 and IPV4
>>>
>>> fe80::21c:42ff:fe00:8%en4(otter-2.local),0(0)-inet6-stream-tcp
>>> fe80::21c:42ff:fe00:9%en5(otter-2.local),0(0)-inet6-stream-tcp
>>> fe80::21b:63ff:fe02:d2db%en1(otter-2.local),0(0)-inet6-stream-tcp
>>> 10.211.55.2(10.211.55.2),0(0)-inet4-stream-tcp
>>> 10.37.129.2(10.37.129.2),0(0)-inet4-stream-tcp
>>> 192.168.1.141(192.168.1.141),0(0)-inet4-stream-tcp
>>>
>>> So looks kinda random, but it's not. It's defined by Microsoft & committee
>>> etc. in
>>> http://www.faqs.org/rfcs/rfc3484.html
>>>
>>> The objective is to sort the list into some order. I must say you can't
>>> actually tell from reading the docs, and things over
>>> the past decade have changed. So I refer to some cheat sheets that *might*
>>> be correct.
>>>
>>> Now the macbook pro in this case uses 192.168.1.141 as the assigned tcp/ip
>>> address from our internal DHCP server.
>>> The 10.211.55.2  is a parallels shared network adaptor and
>>> 10.37.129.2 is the parallels host-only network adaptor.
>>>
>>> All three interfaces show as active, and if you consider the 'ifconfig -a'
>>>  below you would be hard pressed to determine which interface is the one
>>> facing the
>>> company intranet.
>>>
>>>
>>> [otter-2:~] johnmci% ifconfig -a
>>> lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
>>>        inet6 ::1 prefixlen 128
>>>        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
>>>        inet 127.0.0.1 netmask 0xff000000
>>> gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
>>> stf0: flags=0<> mtu 1280
>>> en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
>>>        ether 00:17:f2:d9:57:35
>>>        media: autoselect status: inactive
>>>        supported media: autoselect 10baseT/UTP <half-duplex> 10baseT/UTP
>>> <full-duplex> 10baseT/UTP <full-duplex,hw-loopback> 10baseT/UTP
>>> <full-duplex,flow-control> 100baseTX <half-duplex> 100baseTX <full-duplex>
>>> 100baseTX <full-duplex,hw-loopback> 100baseTX <full-duplex,flow-control>
>>> 1000baseT <full-duplex> 1000baseT <full-duplex,hw-loopback> 1000baseT
>>> <full-duplex,flow-control> none
>>> fw0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 2030
>>>        lladdr 00:19:e3:ff:fe:93:92:7c
>>>        media: autoselect <full-duplex> status: inactive
>>>        supported media: autoselect <full-duplex>
>>> en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
>>>        inet6 fe80::21b:63ff:fe02:d2db%en1 prefixlen 64 scopeid 0x6
>>>        inet 192.168.1.141 netmask 0xffffff00 broadcast 192.168.1.255
>>>        ether 00:1b:63:02:d2:db
>>>        media: autoselect status: active
>>>        supported media: autoselect
>>> en4: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu
>>> 1500
>>>        inet6 fe80::21c:42ff:fe00:8%en4 prefixlen 64 scopeid 0x7
>>>        inet 10.211.55.2 netmask 0xffffff00 broadcast 10.211.55.255
>>>        ether 00:1c:42:00:00:08
>>>        media: autoselect status: active
>>>        supported media: autoselect
>>> en5: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu
>>> 1500
>>>        inet6 fe80::21c:42ff:fe00:9%en5 prefixlen 64 scopeid 0x8
>>>        inet 10.37.129.2 netmask 0xffffff00 broadcast 10.37.129.255
>>>        ether 00:1c:42:00:00:09
>>>        media: autoselect status: active
>>>        supported media: autoselect
>>>
>>>
>>> Where en0 is ethernet jack, fw0 is firewire, en1 is wireless, en4 & en5
>>> are virtual.
>>>
>>> Now the bias from the committee is
>>>
>>> precedence  ::1/128       50
>>> precedence  ::/0          40
>>> precedence  2002::/16     30
>>> precedence ::/96          20
>>> precedence ::ffff:0:0/96  10
>>> scopev4 ::ffff:169.254.0.0/112  2
>>> scopev4 ::ffff:127.0.0.0/104    2
>>> scopev4 ::ffff:10.0.0.0/104     5
>>> scopev4 ::ffff:172.16.0.0/108   5
>>> scopev4 ::ffff:192.168.0.0/112  5
>>> scopev4 ::ffff:0.0.0.0/96       14
>>>
>>> This means of course the 10.0.0.0 address sorts before the 192.168.0.0
>>> address. How helpful.
>>>
>>> So how do we know *which* is the proper address to use? Well no idea!
>>>
>>> However let's see what the API does.
>>>
>>> NetNameResolver class>> addressesForName: hostName
>>>        | adresses |
>>>        adresses := SocketAddressInformation
>>>                forHost: hostName
>>>                service: ''
>>>                flags: 0
>>>                addressFamily:  0
>>>                socketType: SocketAddressInformation socketTypeStream
>>>                protocol: SocketAddressInformation protocolTCP.
>>>        ^adresses
>>>
>>>
>>> Now I can make it return just IPV4 address by doing:
>>>
>>> NetNameResolver class>> addressesForName: hostName
>>>        | adresses |
>>>        adresses := SocketAddressInformation
>>>                forHost: hostName
>>>                service: ''
>>>                flags: 0
>>>                addressFamily:  SocketAddressInformation addressFamilyINET4
>>>                socketType: SocketAddressInformation socketTypeStream
>>>                protocol: SocketAddressInformation protocolTCP.
>>>        ^adresses
>>>
>>> which then NetNameResolver localHostAddress gives:
>>> 10.37.129.2(10.37.129.2),0(0)
>>>
>>> I can also supply a service number string  say SSH  '22'
>>> that give back
>>> 10.37.129.2(10.37.129.2),22(ssh)
>>> since ssh is binding on all interfaces that's valid.
>>>
>>> Technically the getnameinfo gives back three address but again the code
>>> below grabs the first one which according to the rfc3484 is more likely to
>>> be the correct answer.
>>>
>>> addressForName: hostName
>>>        "NetNameResolver addressForName: 'impara.de' "
>>>        "NetNameResolver addressForName: 'localhost' "
>>>        "NetNameResolver addressForName: '127.0.0.1' "
>>>        | addresses |
>>>        self useOldNetwork
>>>                ifTrue: [^self oldAddressForName: hostName].
>>>        addresses := self addressesForName: hostName.
>>>        ^addresses
>>>                ifEmpty: [nil]
>>>                ifNotEmpty: [addresses first socketAddress]
>>>
>>> But grabbing the first one doesn't meet people's expectations of
>>> correctness, however we just don't have enough information to decide *what*
>>> is correct.
>>>
>>> Now some people say OH let's return the en0 one because that is correct?
>>> Really how do you know?
>>> On my computer en0 is ethernet, but since I'm using wireless then en1 is
>>> the correct one.
>>>
>>> Obviously I could look in the list of IPV6 address find the LOWEST en#
>>> value, then grab the IPV4 entry.  This would assume I check for the fact
>>> that the IPV6
>>> interface has an IPV4 address and the sort order for the IPV6 is the same
>>> as for the IPV4.
>>>
>>> Gee that sounds ok?
>>>
>>> Well it's not, when for example I tether my MacBook Pro to my iPhone and
>>> abuse my privilege to move data over the cellular carrier, ah sorry you USA
>>> ATT folks,
>>> then the interface is:
>>>
>>> en6: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
>>>        inet6 fe80::226:8ff:fe72:5aa%en6 prefixlen 64 scopeid 0x9
>>>        inet 192.168.20.2 netmask 0xffffff00 broadcast 192.168.20.255
>>>        ether 00:26:08:72:05:aa
>>>        media: 10baseT/UTP status: active
>>>        supported media: 10baseT/UTP
>>>
>>>
>>> which fails the test that the lowest active en# is the one we want to use.
>>>
>>> 10.37.129.2(10.37.129.2),0(0)-inet4-stream-tcp
>>> 10.211.55.2(10.211.55.2),0(0)-inet4-stream-tcp
>>> 192.168.20.2(192.168.20.2),0(0)-inet4-stream-tcp)
>>>
>>>
>>> So the question is what would the community like to see happen. Well other
>>> than hide under a rock and see if the problem goes away...
>>>
>>>
>>> On 2010-03-12, at 8:41 AM, Chris Cunnington wrote:
>>>
>>>> How is NetNameResolver choosing the interface to return an IP address
>>>> from?
>>>>
>>>> In Cobalt this is a problem. You need the right address to connect to
>>>> other spaces. Cobalt won't let you enter it by hand, so you are at the mercy
>>>> of its guessing the correct interface.
>>>>
>>>> NetNameResolver localAddressString
>>>>
>>>> executed in Workspace produces the IP from my fw0 interface, which is
>>>> useless. I need it to look at ppp0.
>>>>
>>>> Can it be told which interface to look at?
>>>> How does it choose?
>>>>
>>>> Chris
>>>>
>>>
>>> --
>>>
>>> ===========================================================================
>>> John M. McIntosh <johnmci at smalltalkconsulting.com>   Twitter:
>>>  squeaker68882
>>> Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
>>>
>>> ===========================================================================
>>>
>>>
>>>
>>>
>>>
>>
>>
>
>


More information about the Squeak-dev mailing list