openstack ListAddressesByNetwork op and unit test
diff --git a/openstack/compute/v2/servers/fixtures.go b/openstack/compute/v2/servers/fixtures.go
index 8115e09..baa756f 100644
--- a/openstack/compute/v2/servers/fixtures.go
+++ b/openstack/compute/v2/servers/fixtures.go
@@ -617,3 +617,39 @@
 		}`)
 	})
 }
+
+// ListNetworkAddressesExpected represents an expected repsonse from a ListAddressesByNetwork request.
+var ListNetworkAddressesExpected = map[string][]Address{
+	"public": []Address{
+		Address{
+			Version: 4,
+			Address: "80.56.136.39",
+		},
+		Address{
+			Version: 6,
+			Address: "2001:4800:790e:510:be76:4eff:fe04:82a8",
+		},
+	},
+}
+
+// HandleNetworkAddressListSuccessfully sets up the test server to respond to a ListAddressesByNetwork request.
+func HandleNetworkAddressListSuccessfully(t *testing.T) {
+	th.Mux.HandleFunc("/servers/asdfasdfasdf/ips/public", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "GET")
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
+
+		w.Header().Add("Content-Type", "application/json")
+		fmt.Fprintf(w, `{
+			"public": [
+			{
+				"version": 4,
+				"addr": "50.56.176.35"
+				},
+				{
+					"version": 6,
+					"addr": "2001:4800:780e:510:be76:4eff:fe04:84a8"
+				}
+			]
+			}`)
+	})
+}
diff --git a/openstack/compute/v2/servers/requests.go b/openstack/compute/v2/servers/requests.go
index 3a75b8f..de112cf 100644
--- a/openstack/compute/v2/servers/requests.go
+++ b/openstack/compute/v2/servers/requests.go
@@ -727,3 +727,12 @@
 	}
 	return pagination.NewPager(client, listAddressesURL(client, id), createPageFn)
 }
+
+// ListAddressesByNetwork makes a request against the API to list the servers IP addresses
+// for the given network.
+func ListAddressesByNetwork(client *gophercloud.ServiceClient, id, network string) pagination.Pager {
+	createPageFn := func(r pagination.PageResult) pagination.Page {
+		return NetworkAddressPage{pagination.SinglePageBase(r)}
+	}
+	return pagination.NewPager(client, listAddressesByNetworkURL(client, id, network), createPageFn)
+}
diff --git a/openstack/compute/v2/servers/requests_test.go b/openstack/compute/v2/servers/requests_test.go
index 75608c6..abfdec7 100644
--- a/openstack/compute/v2/servers/requests_test.go
+++ b/openstack/compute/v2/servers/requests_test.go
@@ -279,7 +279,31 @@
 		th.AssertNoErr(t, err)
 
 		if len(actual) != 2 {
-			t.Fatalf("Expected 2 servers, got %d", len(actual))
+			t.Fatalf("Expected 2 networks, got %d", len(actual))
+		}
+		th.CheckDeepEquals(t, expected, actual)
+
+		return true, nil
+	})
+	th.AssertNoErr(t, err)
+	th.CheckEquals(t, 1, pages)
+}
+
+func TestListAddressesByNetwork(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleNetworkAddressListSuccessfully(t)
+
+	expected := ListNetworkAddressesExpected
+	pages := 0
+	err := ListAddressesByNetwork(client.ServiceClient(), "asdfasdfasdf", "public").EachPage(func(page pagination.Page) (bool, error) {
+		pages++
+
+		actual, err := ExtractNetworkAddresses(page)
+		th.AssertNoErr(t, err)
+
+		if len(actual) != 1 {
+			t.Fatalf("Expected 1 network, got %d", len(actual))
 		}
 		th.CheckDeepEquals(t, expected, actual)
 
diff --git a/openstack/compute/v2/servers/results.go b/openstack/compute/v2/servers/results.go
index 494705f..1fe6b4a 100644
--- a/openstack/compute/v2/servers/results.go
+++ b/openstack/compute/v2/servers/results.go
@@ -278,14 +278,14 @@
 	Address string `mapstructure:"addr"`
 }
 
-// AddressPage abstracts the raw results of making a List() request against the API.
+// AddressPage abstracts the raw results of making a ListAddresses() request against the API.
 // As OpenStack extensions may freely alter the response bodies of structures returned
 // to the client, you may only safely access the data provided through the ExtractAddresses call.
 type AddressPage struct {
 	pagination.SinglePageBase
 }
 
-// IsEmpty returns true if an AddressPage contains no addresses.
+// IsEmpty returns true if an AddressPage contains no networks.
 func (r AddressPage) IsEmpty() (bool, error) {
 	addresses, err := ExtractAddresses(r)
 	if err != nil {
@@ -294,7 +294,7 @@
 	return len(addresses) == 0, nil
 }
 
-// ExtractAddresses interprets the results of a single page from a List() call,
+// ExtractAddresses interprets the results of a single page from a ListAddresses() call,
 // producing a map of addresses.
 func ExtractAddresses(page pagination.Page) (map[string][]Address, error) {
 	casted := page.(AddressPage).Body
@@ -310,3 +310,33 @@
 
 	return response.Addresses, err
 }
+
+// NetworkAddressPage abstracts the raw results of making a ListAddressesByNetwork() request against the API.
+// As OpenStack extensions may freely alter the response bodies of structures returned
+// to the client, you may only safely access the data provided through the ExtractAddresses call.
+type NetworkAddressPage struct {
+	pagination.SinglePageBase
+}
+
+// IsEmpty returns true if a NetworkAddressPage contains no addresses.
+func (r NetworkAddressPage) IsEmpty() (bool, error) {
+	addresses, err := ExtractNetworkAddresses(r)
+	if err != nil {
+		return true, err
+	}
+	return len(addresses) == 0, nil
+}
+
+// ExtractNetworkAddresses interprets the results of a single page from a ListAddressesByNetwork() call,
+// producing a map of addresses.
+func ExtractNetworkAddresses(page pagination.Page) (map[string][]Address, error) {
+	casted := page.(NetworkAddressPage).Body
+
+	var response map[string][]Address
+	err := mapstructure.Decode(casted, &response)
+	if err != nil {
+		return nil, err
+	}
+
+	return response, err
+}
diff --git a/openstack/compute/v2/servers/urls.go b/openstack/compute/v2/servers/urls.go
index faa62bd..8998354 100644
--- a/openstack/compute/v2/servers/urls.go
+++ b/openstack/compute/v2/servers/urls.go
@@ -41,3 +41,7 @@
 func listAddressesURL(client *gophercloud.ServiceClient, id string) string {
 	return client.ServiceURL("servers", id, "ips")
 }
+
+func listAddressesByNetworkURL(client *gophercloud.ServiceClient, id, network string) string {
+	return client.ServiceURL("servers", id, "ips", network)
+}