Real-Time Measurement and Control

cancel
Showing results for 
Search instead for 
Did you mean: 

cRIO MAC Address

I am using a cRIO in a project that requires security on the compiled code due to intellectual property concerns.  My solution was to have my LabVIEW code "ping" itself using the "RT Ping Controllers.vi" function using only my own IP.  I get my own IP using the "String to IP" primitive on the TCP palette with the string input unwired.  This works great.  I check the returned MAC value against a constant that is compiled into the executable, and if it doesn't match I tell the user to get bent.  So if someone copies the program to another cRIO, the MAC address will be different and the code won't work.

The problem is when the user boots up the cRIO with the ethernet unplugged, like he did this morning.  My code fails in this case.   Apparently, I can't get my own MAC address when the ethernet cable is unplugged.  Grrrr.

I have 2 theories on why this might be, but does anyone know for sure what's going on and/or how to get around it?  Any other way to get my own MAC address on RT?

Theory 1:  The RT operating system decides to be "smart" when booting up and detects that the ethernet cable isn't plugged in and so doesn't load the ethernet device driver to save memory, so there is no MAC address until the system is rebooted.

Theory 2:  When LabVIEW starts after the OS boots, the LabVIEW RT sockets driver doesn't bind to the "ethernet adapter" since it's not plugged into the network, so either the "String to IP" primitive or the "RT Ping Controllers.vi" function fails (don't know which and can't check it).  This binding failure is similiar to what happens under Windows if you plug in a network card on a laptop while LabVIEW is running (you'll never be able to use the new ethernet adapter until you restart LabVIEW because LabVIEW already instanced sockets without being bound to the new adapter and it only instances the sockets driver on startup).

Unfortunately, I can't test these scenarios due to the cRIO being deployed at the customer site across the country.  I just need a reliable way of reading the MAC address (or the cRIO's serial number would work also) that isn't dependant on something the customer will/won't do or the current network state.

Anyone have any ideas/solutions/theories?
0 Kudos
Message 1 of 8
(6,696 Views)

Hi Walter,

Yes, the RT Ping Controllers.vi will not return the MAC address if you don't have any thing connected to the ethernet port. So one work-around is to have an ethernet jack connected to it with a small amount of ethernet cable and then connecting the transmit wire to the receive wire. This is similar to serial loop back testing where the transmit and receive pins are shorted.

If this does not work for you then I recommend you create a service request online and call National Instruments directly to see if there may be other options available depending on your specific situation. Thanks and have a great day!

Regards,
Prashanth

0 Kudos
Message 2 of 8
(6,670 Views)
Walter,

I can think on another two ideas that may help you workaround this problem. I know they are not acceptable for many cases, but just wanted to throw them out. First one is pretty dumb, but I think in some situations it is a valid option.

1. Require the end user to have the ethernet cable connected so the TCP/IP stack comes up properly. If you can't detect the MAC address, then you get your app to do as if the MAC address didn't match.

2. Use the serial number of one or more C Series modules instead of the MAC address for the controller. Here you have the disadvantage that the end user will not be able to swap modules if something goes wrong with one of them. You can do this as a back up plan in case you can't get the MAC address.

Another thing to try, is to assign an static IP to the controller to see if the behavior is the same (can't read the MAC address). I think it is worth a shot.

Hope this helps (although I'm realistic that it won't for a lot of cases).

JMota
0 Kudos
Message 3 of 8
(6,663 Views)
The cRIO is running unattended in a very challenging physical environment.  One workaround we've already discovered is to simply plug the cRIO into a hub, and plug the hub into the ethernet that goes out to the shock-isolated hardened PC.  The problem is finding a hub that will actually survive in the necessary environment.  Maybe we can fit an 'industrial' hub into the special enclosure for the PC.  The unit is subject to continuous repeated shock and high temperature.  Large capacitors and other large electronic components frequently get torn off their circuit boards after a while.  This is the only reason we are using the cRIO anyway.  It's little more than a really expensive ethernet remoted DAQ card the way we are using it.  The hardened PC has no slots and uses a special shock proof solid state "hard drive" that is ridiculously expensive.

The cable loopback solution isn't viable due to human intervention being required.

The cRIO is already on a fixed IP (as is the 'PC' it's connected to).  I've been unable to determine from my customer why the cRIO won't boot properly when connected via crossover cable to the host PC when the cRIO is rebooted and the host PC isn't.  It apparently will boot properly if connected via a hub.  The connection with the crossover is working fine, as long as it's booted connected to the hub, then the crossover cable connected to the PC directly after my code does it's startup check.  We know this because the application talks to the host PC just fine over the crossover cable.  It just can't boot with it.  That doesn't make any sense to me, but I'm not with the hardware and telephone tech support is rather limited.

I thought of using the serial number of a module, but rejected it for exactly the reason, what if a module fails and needs to be replaced?  Then I have to recompile the code for them.  I guess that is based on the assumption that it's more likely for a module to fail than the cRIO itself.  I assume the analog modules would fail first in the event of a power spike on one of the inputs.  Maybe thats a bad assumption and I should just use a module serial number.

It sure would be nice to be able to read the cRIO's serial number.  I can see it using MAX, so there must be a software way of reading the number.  I guess I could call NI and ask them for programmatic access to the cRIO's serial number.  What do you think the odds of them giving me such a function call in a short period of time?  Would anyone else like to have access to the serial number?  If a bunch of people ask for it, maybe they would consider it.
0 Kudos
Message 4 of 8
(6,653 Views)
Sometimes the Serial Number is the last 3 digits of the MAC address of the default ethernet device on the controller, sometimes not - depends on what manufacturing sets the serial number to (usually the last 3 digits of the MAC address is "unique enough").  However, since that's not always the case, I don't have a good methodology for pulling the serial number from the controller easily.
 
However, I DO have a really sly means of giving you the MAC address of the ethernet controller on a cRIO device - cRIO devices generally only have one ethernet device on them, making this "workaround" really easy to use.  In LabVIEW RT 8.0 and above, LabVIEW RT generates an ini file every time the controller boots up - you can find it in:
 
 \NI-RT\SYSTEM\ETHERNET\netconf.ini
 
This INI file lists the MAC addresses of every ethernet device in the system (since LabVIEW RT 8.0+ can handle multiple ethernet controllers) and provides the MAC address of the primary ethernet device (the one that can get a DHCP address - LabVIEW RT can only handle one DHCP-enabled device at a time, a limitation of the RTOS it uses).  If you parse this file correctly, you can "lift" the MAC address of the ethernet device in the system with the greatest of ease. 
 
Realize this only works for LabVIEW RT 8.0 and above, and is subject to being deprecated in future versions of LabVIEW RT (though I can guarantee it will work in all LabVIEW RT 8.x versions).
 
-Danny
 
0 Kudos
Message 5 of 8
(6,646 Views)

Oh, sorry, I also meant to reply to your "theories" about what the RT controller does when there is no ethernet plugged in.

1.  If the Ethernet device is configured in DHCP mode (the "Obtain IP address from DHCP server" radio button in MAX is selected), if there's no ethernet cable plugged in then LVRT loads the ethernet driver and attempts to contact the DHCP server for an IP address.  Using an exponential backoff, the controller tries around 6-7 times to get a DHCP address and then reboots itself, trying again.  After the 3rd reboot the device starts up in Safe Mode with a static IP address usually configured to 0.0.0.0.

2.  If the Ethernet device is configured in Static IP mode (the "Edit the IP settings" in MAX is selected) then the device is immediately brought up with the specified IP address and is ready to rock and roll.  However, you cannot send ethernet traffic until a cable is plugged in - you're in essence sending a message out into the ether that is eventually routed back to you.  There isn't a "loopback" mode you can set, so you cannot get a "ping" to work unless you do the cable loopback trick previously specified (at least not by hitting your IP address as reported, I *think* you can ALWAYS use 127.0.0.1 as an IP address to reference yourself).

So, in your situation where the device is connected to a "dead" host PC via a loopback cable, check to make sure you're not in DHCP mode.  In Static IP mode you should be able to make your cRIO controller fire up no matter what you're plugged up to (or not plugged into, rather).  If this is not the case, I'd be interested in hearing what controller model you've got and the version of the DLLs found in the ETHERNET directory mentioned in my last post in this same thread...

-Danny

Message Edited by texasdiaz on 07-28-2006 02:29 PM

Message 6 of 8
(6,637 Views)
Excellent!  Hopefully, reading the .ini file will solve the problem.  Thank you!  I think I'll have to hunt around some in those .ini files and see what other goodies are available to be read.

From your explaination of the ethernet controller in static IP mode, I'm a bit confused still on why the system wouldn't work.

If the cRIO is set to static IP and is physically plugged into a hub that has nothing else connected to it, the cRIO boots fine and finds it's own MAC address fine.  If the cRIO is unplugged from the hub and a cross-over cable used to connect it directly to another PC (which also has a static IP), it can't find it's own MAC address after it is rebooted.

I'm wondering now if maybe it's the "string to IP" primitive that is giving me an invalid IP when the cable isn't connected.  Using the loopback IP might also fix the problem then.  I've got some things to try now... thanks!!!
0 Kudos
Message 7 of 8
(6,625 Views)
I wouldn't think of the controller as not being able to get its MAC address - when the ethernet drivers load on a cRIO (or any RT controller, really) the MAC address is read off the onboard EEPROM on the ethernet chip, and that MAC address is reported to the RTOS (PharLap in this case).  This happens whether the ethernet chip is plugged in or not. 
 
I think the problem you're running into is whether or not there's a way to send a packet back to yourself (I think the localhost address of 127.0.0.1 will solve your problem).  Depending on what kind of hub/switch/router you're connected to, the packet you send may be broadcast back to you from the hub/switch/router whereas it's not being broadcast back to you otherwise.  I can only make a guess to this regard, but this is the best I can come up with at the time being. 
 
Good luck, lemme know if any of this helps!
 
-Danny
0 Kudos
Message 8 of 8
(6,620 Views)