diff --git a/master/canopen.c b/master/canopen.c
index 718c652c1410f3e4ab44ba87934a7579e21331d8..e062cdcfb4fcd1708ab969564eec3baf32f66c44 100644
--- a/master/canopen.c
+++ b/master/canopen.c
@@ -171,6 +171,23 @@ void ec_sdo_clear(struct kobject *kobj /**< SDO's kobject */)
 
 /*****************************************************************************/
 
+ec_sdo_entry_t *ec_sdo_get_entry(
+        ec_sdo_t *sdo,
+        uint8_t subindex
+        )
+{
+    ec_sdo_entry_t *entry;
+
+    list_for_each_entry(entry, &sdo->entries, list) {
+        if (entry->subindex != subindex) continue;
+        return entry;
+    }
+
+    return NULL;
+}
+
+/*****************************************************************************/
+
 ssize_t ec_sdo_info(ec_sdo_t *sdo, /**< SDO */
                     char *buffer /**< target buffer */
                     )
diff --git a/master/canopen.h b/master/canopen.h
index 43e18eac1664ccf692b2e9d947d0b396d2521b44..d218ba8bc7377ac03526cf46806aa832ac1eae30 100644
--- a/master/canopen.h
+++ b/master/canopen.h
@@ -53,7 +53,7 @@
    CANopen SDO.
 */
 
-typedef struct
+struct ec_sdo
 {
     struct kobject kobj; /**< kobject */
     struct list_head list; /**< list item */
@@ -63,8 +63,7 @@ typedef struct
     char *name; /**< SDO name */
     uint8_t subindices; /**< subindices */
     struct list_head entries; /**< entry list */
-}
-ec_sdo_t;
+};
 
 /*****************************************************************************/
 
@@ -120,6 +119,7 @@ ec_sdo_request_t;
 
 int ec_sdo_init(ec_sdo_t *, uint16_t, ec_slave_t *);
 void ec_sdo_destroy(ec_sdo_t *);
+ec_sdo_entry_t *ec_sdo_get_entry(ec_sdo_t *, uint8_t);
 
 int ec_sdo_entry_init(ec_sdo_entry_t *, uint8_t, ec_sdo_t *);
 void ec_sdo_entry_destroy(ec_sdo_entry_t *);
diff --git a/master/globals.h b/master/globals.h
index 338c886253bbd0cf1484c1b9a0387799d1e31c37..00044b72a7d1a2e146a2795bac1b7fedc4213a71 100644
--- a/master/globals.h
+++ b/master/globals.h
@@ -201,4 +201,8 @@ ec_request_state_t;
 
 /*****************************************************************************/
 
+typedef struct ec_sdo ec_sdo_t;
+
+/*****************************************************************************/
+
 #endif
diff --git a/master/slave.c b/master/slave.c
index 1c4070113c898499f713a57ba45e5efdded23ec2..4141518546d011f241d63c56e115fdb494de2368 100644
--- a/master/slave.c
+++ b/master/slave.c
@@ -1270,6 +1270,28 @@ void ec_slave_sdo_dict_info(const ec_slave_t *slave, /**< EtherCAT slave */
     *entry_count = entries;
 }
 
+/*****************************************************************************/
+
+/**
+ * Get an SDO from the dictionary.
+ * \returns The desired SDO, of NULL.
+ */
+
+ec_sdo_t *ec_slave_get_sdo(
+        ec_slave_t *slave /**< EtherCAT slave */,
+        uint16_t index /**< SDO index */
+        )
+{
+    ec_sdo_t *sdo;
+
+    list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
+        if (sdo->index != index) continue;
+        return sdo;
+    }
+
+    return NULL;
+}
+
 /******************************************************************************
  *  Realtime interface
  *****************************************************************************/
diff --git a/master/slave.h b/master/slave.h
index c70797648f85003b951874ca6803666c04d2c034..395622e795d3721235111bfdf323eeaec32d44e6 100644
--- a/master/slave.h
+++ b/master/slave.h
@@ -205,6 +205,7 @@ ec_sync_t *ec_slave_get_pdo_sync(ec_slave_t *, ec_direction_t);
 int ec_slave_validate(const ec_slave_t *, uint32_t, uint32_t);
 void ec_slave_sdo_dict_info(const ec_slave_t *,
         unsigned int *, unsigned int *);
+ec_sdo_t *ec_slave_get_sdo(ec_slave_t *, uint16_t);
 
 /*****************************************************************************/