diff --git a/IPython/utils/localinterfaces.py b/IPython/utils/localinterfaces.py
index 03b63dd..3e828f4 100644
--- a/IPython/utils/localinterfaces.py
+++ b/IPython/utils/localinterfaces.py
@@ -12,7 +12,7 @@ PUBLIC_IPS : A list of public IP addresses that point to this machine.
              Use these to tell remote clients where to find you.
 """
 #-----------------------------------------------------------------------------
-#  Copyright (C) 2010-2011  The IPython Development Team
+#  Copyright (C) 2010  The IPython Development Team
 #
 #  Distributed under the terms of the BSD License.  The full license is in
 #  the file COPYING, distributed as part of this software.
@@ -22,9 +22,13 @@ PUBLIC_IPS : A list of public IP addresses that point to this machine.
 # Imports
 #-----------------------------------------------------------------------------
 
+import os
 import socket
 
 from .data import uniq_stable
+from .process import get_output_error_code
+from .py3compat import bytes_to_str
+from .warn import warn
 
 #-----------------------------------------------------------------------------
 # Code
@@ -53,6 +57,84 @@ def _requires_ips(f):
         return f(*args, **kwargs)
     return ips_loaded
 
+# subprocess-parsing ip finders
+class NoIPAddresses(Exception):
+    pass
+
+def _populate_from_list(addrs):
+    """populate local and public IPs from flat list of all IPs"""
+    if not addrs:
+        raise NoIPAddresses
+    
+    global LOCALHOST
+    public_ips = []
+    local_ips = []
+    
+    for ip in addrs:
+        local_ips.append(ip)
+        if not ip.startswith('127.'):
+            public_ips.append(ip)
+        elif not LOCALHOST:
+            LOCALHOST = ip
+    
+    if not LOCALHOST:
+        LOCALHOST = '127.0.0.1'
+        local_ips.insert(0, LOCALHOST)
+        
+    local_ips.extend(['0.0.0.0', ''])
+    
+    LOCAL_IPS[:] = uniq_stable(local_ips)
+    PUBLIC_IPS[:] = uniq_stable(public_ips)
+
+def _load_ips_ifconfig():
+    """load ip addresses from `ifconfig` output (posix)"""
+    
+    out, err, rc = get_output_error_code('ifconfig')
+    if rc:
+        # no ifconfig, it's usually in /sbin and /sbin is not on everyone's PATH
+        out, err, rc = get_output_error_code('/sbin/ifconfig')
+    if rc:
+        raise IOError("no ifconfig: %s" % err)
+    
+    lines = bytes_to_str(out).splitlines()
+    addrs = []
+    for line in lines:
+        blocks = line.lower().split()
+        if blocks[0] == 'inet':
+            addrs.append(blocks[1])
+    _populate_from_list(addrs)
+
+
+def _load_ips_ip():
+    """load ip addresses from `ip addr` output (Linux)"""
+    out, err, rc = get_output_error_code('ip addr')
+    if rc:
+        raise IOError("no ip: %s" % err)
+    
+    lines = bytes_to_str(out).splitlines()
+    addrs = []
+    for line in lines:
+        blocks = line.lower().split()
+        if blocks[0] == 'inet':
+            addrs.append(blocks[1].split('/')[0])
+    _populate_from_list(addrs)
+
+
+def _load_ips_ipconfig():
+    """load ip addresses from `ipconfig` output (Windows)"""
+    out, err, rc = get_output_error_code('ipconfig')
+    if rc:
+        raise IOError("no ipconfig: %s" % err)
+    
+    lines = bytes_to_str(out).splitlines()
+    addrs = ['127.0.0.1']
+    for line in lines:
+        line = line.lower().split()
+        if line[:2] == ['ipv4', 'address']:
+            addrs.append(line.split()[-1])
+    _populate_from_list(addrs)
+
+
 def _load_ips_netifaces():
     """load ip addresses with netifaces"""
     import netifaces
@@ -81,6 +163,7 @@ def _load_ips_netifaces():
     LOCAL_IPS[:] = uniq_stable(local_ips)
     PUBLIC_IPS[:] = uniq_stable(public_ips)
 
+
 def _load_ips_gethostbyname():
     """load ip addresses with socket.gethostbyname_ex
     
@@ -104,7 +187,7 @@ def _load_ips_gethostbyname():
     finally:
         PUBLIC_IPS[:] = uniq_stable(PUBLIC_IPS)
         LOCAL_IPS.extend(PUBLIC_IPS)
-
+    
     # include all-interface aliases: 0.0.0.0 and ''
     LOCAL_IPS.extend(['0.0.0.0', ''])
 
@@ -125,17 +208,42 @@ def _load_ips():
     
     This function will only ever be called once.
     
-    It will use netifaces to do it quickly if available,
-    otherwise it will fallback on socket.gethostbyname_ex, which can be slow.
+    It will use netifaces to do it quickly if available.
+    Then it will fallback on parsing the output of ifconfig / ip addr / ipconfig, as appropriate.
+    Finally, it will fallback on socket.gethostbyname_ex, which can be slow.
     """
+    
     try:
+        # first priority, use netifaces
         try:
-            _load_ips_netifaces()
+            return _load_ips_netifaces()
         except ImportError:
-            _load_ips_gethostbyname()
-    except Exception:
+            pass
+        
+        # second priority, parse subprocess output (how reliable is this?)
+        
+        if os.name == 'nt':
+            try:
+                return _load_ips_ipconfig()
+            except (IOError, NoIPAddresses):
+                pass
+        else:
+            try:
+                return _load_ips_ifconfig()
+            except (IOError, NoIPAddresses):
+                pass
+            try:
+                return _load_ips_ip()
+            except (IOError, NoIPAddresses):
+                pass
+        
+        # lowest priority, use gethostbyname
+        
+        return _load_ips_gethostbyname()
+    except Exception as e:
         # unexpected error shouldn't crash, load dumb default values instead.
-        _load_ips_dumb()
+        warn("Unexpected error discovering local network interfaces: %s" % e)
+    _load_ips_dumb()
 
 
 @_requires_ips