diff --git a/bin/efa b/bin/efa
index 6c1649fc53d03ff4fc35e5f7ecd48ec6f97e390a..3cbd03cce9657424f07e2e3f40a41dd3e845f12e 100755
--- a/bin/efa
+++ b/bin/efa
@@ -114,6 +114,29 @@ sub check_for_error {
 	return;
 }
 
+sub format_footpath {
+	my @parts = @_;
+	my $str   = q{};
+
+	for my $path_elem (@parts) {
+		my ( $type, $level ) = @{$path_elem};
+		if ( $level eq 'UP' ) {
+			$str .= ' ↗';
+		}
+		elsif ( $level eq 'DOWN' ) {
+			$str .= ' ↘';
+		}
+		elsif ( $level eq 'LEVEL' ) {
+			$str .= ' →';
+		}
+		else {
+			$str .= " [unhandled level, please report a bug : $level]";
+		}
+	}
+
+	return $str;
+}
+
 sub display_connection {
 	my ($c) = @_;
 
@@ -153,6 +176,14 @@ sub display_connection {
 	printf( "%-5s an  %s\n", $c->arrival_time, $c->arrival_stop_and_platform, );
 	print "\n";
 
+	if (    $opt->{'extended-info'}
+		and $c->footpath_duration
+		and $c->footpath_type ne 'IDEST' )
+	{
+		printf( "%5d min Umsteigedauer: %s\n\n",
+			$c->footpath_duration, format_footpath( $c->footpath_parts ) );
+	}
+
 	return;
 }
 
diff --git a/lib/Travel/Routing/DE/EFA.pm b/lib/Travel/Routing/DE/EFA.pm
index ec61caa08385fd1c5d8f715010b50c18b59cf93a..2ff9f6482e03ed2b98e38fe3bf34164b42f3c724 100644
--- a/lib/Travel/Routing/DE/EFA.pm
+++ b/lib/Travel/Routing/DE/EFA.pm
@@ -514,7 +514,10 @@ sub parse_xml_part {
 	  = XML::LibXML::XPathExpression->new('./itdDateTimeTarget/itdDate');
 	my $xp_stime
 	  = XML::LibXML::XPathExpression->new('./itdDateTimeTarget/itdTime');
-	my $xp_mot   = XML::LibXML::XPathExpression->new('./itdMeansOfTransport');
+	my $xp_mot = XML::LibXML::XPathExpression->new('./itdMeansOfTransport');
+	my $xp_fp  = XML::LibXML::XPathExpression->new('./itdFootPathInfo');
+	my $xp_fp_e
+	  = XML::LibXML::XPathExpression->new('./itdFootPathInfo/itdFootPathElem');
 	my $xp_delay = XML::LibXML::XPathExpression->new('./itdRBLControlled');
 	my $xp_info
 	  = XML::LibXML::XPathExpression->new('./itdInfoTextList/infoTextListElem');
@@ -557,11 +560,13 @@ sub parse_xml_part {
 		my $e_astime  = ( $e_arr->findnodes($xp_stime) )[0];
 		my $e_mot     = ( $e->findnodes($xp_mot) )[0];
 		my $e_delay   = ( $e->findnodes($xp_delay) )[0];
+		my $e_fp      = ( $e->findnodes($xp_fp) )[0];
 		my @e_info    = $e->findnodes($xp_info);
 		my @e_dmap_rm = $e_dep->findnodes($xp_mapitem_rm);
 		my @e_dmap_sm = $e_dep->findnodes($xp_mapitem_sm);
 		my @e_amap_rm = $e_arr->findnodes($xp_mapitem_rm);
 		my @e_amap_sm = $e_arr->findnodes($xp_mapitem_sm);
+		my @e_fp_e    = $e->findnodes($xp_fp_e);
 
 		# not all EFA services distinguish between scheduled and realtime
 		# data. Set sdate / stime to date / time when not provided.
@@ -608,6 +613,22 @@ sub parse_xml_part {
 			$hash->{$key} = decode( 'UTF-8', $hash->{$key} );
 		}
 
+		if ($e_fp) {
+
+			# Note that position=IDEST footpaths are coupled with a special
+			# "walking" connection, so their duration is already known and
+			# accounted for. However, we still save it here, since
+			# detecting and handling this is the API client's job (for now).
+			$hash->{footpath_type}     = $e_fp->getAttribute('position');
+			$hash->{footpath_duration} = $e_fp->getAttribute('duration');
+			for my $e (@e_fp_e) {
+				push(
+					@{ $hash->{footpath_parts} },
+					[ $e->getAttribute('type'), $e->getAttribute('level') ]
+				);
+			}
+		}
+
 		$hash->{departure_routemaps}   = \@dep_rms;
 		$hash->{departure_stationmaps} = \@dep_sms;
 		$hash->{arrival_routemaps}     = \@arr_rms;
diff --git a/lib/Travel/Routing/DE/EFA/Route/Part.pm b/lib/Travel/Routing/DE/EFA/Route/Part.pm
index 29d81fd848c4196a735dd8551279573ac9adff98..cc52f806c98c378b4c37923458715d273bc54a36 100644
--- a/lib/Travel/Routing/DE/EFA/Route/Part.pm
+++ b/lib/Travel/Routing/DE/EFA/Route/Part.pm
@@ -13,7 +13,9 @@ Travel::Routing::DE::EFA::Route::Part->mk_ro_accessors(
 	  arrival_date arrival_time arrival_sdate arrival_stime delay
 	  departure_platform
 	  departure_stop departure_date departure_time departure_sdate
-	  departure_stime train_destination train_line train_product
+	  departure_stime
+	  footpath_duration footpath_type
+	  train_destination train_line train_product
 	  )
 );
 
@@ -71,6 +73,15 @@ sub departure_stop_and_platform {
 	return $self->departure_stop;
 }
 
+sub footpath_parts {
+	my ($self) = @_;
+
+	if ( $self->{footpath_parts} ) {
+		return @{ $self->{footpath_parts} };
+	}
+	return;
+}
+
 sub extra {
 	my ($self) = @_;