/[Intel-AMT]/trunk/lib/Intel/AMT/SOAP.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/lib/Intel/AMT/SOAP.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations)
Sat Aug 8 15:07:39 2009 UTC (14 years, 11 months ago) by dpavlin
File size: 10360 byte(s)
based on amttool from amtterm 1.2 from http://dl.bytesex.org/releases/amtterm/
1 package Intel::AMT::SOAP;
2
3 # based on amttool from amtterm 1.2 from http://dl.bytesex.org/releases/amtterm/
4
5 use strict;
6 use warnings;
7 use SOAP::Lite;
8 #use SOAP::Lite +trace => 'all';
9
10 my $amt_host = $ENV{'AMT_HOST'};
11 my $amt_port = "16992";
12 $main::amt_user = "admin";
13 $main::amt_pass = $ENV{'AMT_PASSWORD'};
14 my $amt_debug = 0;
15 $amt_debug = $ENV{'AMT_DEBUG'} if defined($ENV{'AMT_DEBUG'});
16
17 my $amt_version;
18
19 #############################################################################
20 # data
21
22 my @ps = ("S0", "S1", "S2", "S3", "S4", "S5 (soft-off)", "S4/S5", "Off");
23 my %rcc = (
24 "reset" => "16",
25 "powerup" => "17",
26 "powerdown" => "18",
27 "powercycle" => "19",
28 );
29
30 my %rccs = (
31 "nop" => "0",
32 "pxe" => "1",
33 "hd" => "2",
34 "hdsafe" => "3",
35 "diag" => "4",
36 "cd" => "5",
37 );
38 my %rccs_oem = (
39 "bios" => 0xc1,
40 );
41
42 # incomplete list
43 my %pt_status = (
44 0x0 => "success",
45 0x1 => "internal error",
46 0x3 => "invalid pt_mode",
47 0xc => "invalid name",
48 0xf => "invalid byte_count",
49 0x10 => "not permitted",
50 0x17 => "max limit_reached",
51 0x18 => "invalid auth_type",
52 0x1a => "invalid dhcp_mode",
53 0x1b => "invalid ip_address",
54 0x1c => "invalid domain_name",
55 0x20 => "invalid provisioning_state",
56 0x22 => "invalid time",
57 0x23 => "invalid index",
58 0x24 => "invalid parameter",
59 0x25 => "invalid netmask",
60 0x26 => "flash write_limit_exceeded",
61 0x800 => "network if_error_base",
62 0x801 => "unsupported oem_number",
63 0x802 => "unsupported boot_option",
64 0x803 => "invalid command",
65 0x804 => "invalid special_command",
66 0x805 => "invalid handle",
67 0x806 => "invalid password",
68 0x807 => "invalid realm",
69 0x808 => "storage acl_entry_in_use",
70 0x809 => "data missing",
71 0x80a => "duplicate",
72 0x80b => "eventlog frozen",
73 0x80c => "pki missing_keys",
74 0x80d => "pki generating_keys",
75 0x80e => "invalid key",
76 0x80f => "invalid cert",
77 0x810 => "cert key_not_match",
78 0x811 => "max kerb_domain_reached",
79 0x812 => "unsupported",
80 0x813 => "invalid priority",
81 0x814 => "not found",
82 0x815 => "invalid credentials",
83 0x816 => "invalid passphrase",
84 0x818 => "no association",
85 );
86
87
88 #############################################################################
89 # soap setup
90
91 my ($nas, $sas, $rcs);
92
93 sub SOAP::Transport::HTTP::Client::get_basic_credentials {
94 return $main::amt_user => $main::amt_pass;
95 }
96
97 sub soap_init() {
98 my $proxybase = "http://$amt_host:$amt_port";
99 my $schemabase = "http://schemas.intel.com/platform/client";
100
101 $nas = SOAP::Lite->new(
102 proxy => "$proxybase/NetworkAdministrationService",
103 default_ns => "$schemabase/NetworkAdministration/2004/01");
104 $sas = SOAP::Lite->new(
105 proxy => "$proxybase/SecurityAdministrationService",
106 default_ns => "$schemabase/SecurityAdministration/2004/01");
107 $rcs = SOAP::Lite->new(
108 proxy => "$proxybase/RemoteControlService",
109 default_ns => "$schemabase/RemoteControl/2004/01");
110
111 $nas->autotype(0);
112 $sas->autotype(0);
113 $rcs->autotype(0);
114
115 $amt_version = $sas->GetCoreVersion()->paramsout;
116 }
117
118
119 #############################################################################
120 # functions
121
122 sub usage() {
123 print STDERR <<EOF;
124
125 This utility can talk to Intel AMT managed machines.
126
127 usage: amttool <hostname> [ <command> ] [ <arg(s)> ]
128 commands:
129 info - print some machine info (default).
130 reset - reset machine.
131 powerup - turn on machine.
132 powerdown - turn off machine.
133 powercycle - powercycle machine.
134
135 AMT 2.5+ only:
136 netinfo - print network config.
137 netconf <args> - configure network (check manpage).
138
139 Password is passed via AMT_PASSWORD environment variable.
140
141 EOF
142 }
143
144 sub print_result($) {
145 my $ret = shift;
146 my $rc = $ret->result;
147 my $msg;
148
149 if (!defined($rc)) {
150 $msg = "soap failure";
151 } elsif (!defined($pt_status{$rc})) {
152 $msg = sprintf("unknown pt_status code: 0x%x", $rc);
153 } else {
154 $msg = "pt_status: " . $pt_status{$rc};
155 }
156 printf "result: %s\n", $msg;
157 }
158
159 sub print_paramsout($) {
160 my $ret = shift;
161 my @paramsout = $ret->paramsout;
162 print "params: " . join(", ", @paramsout) . "\n";
163 }
164
165 sub print_hash {
166 my $hash = shift;
167 my $in = shift;
168 my $wi = shift;
169
170 foreach my $item (sort keys %{$hash}) {
171 if (ref($hash->{$item}) eq "HASH") {
172 # printf "%*s%s\n", $in, "", $item;
173 next;
174 }
175 printf "%*s%-*s%s\n", $in, "", $wi, $item, $hash->{$item};
176 }
177 }
178
179 sub print_hash_ipv4 {
180 my $hash = shift;
181 my $in = shift;
182 my $wi = shift;
183
184 foreach my $item (sort keys %{$hash}) {
185 my $addr = sprintf("%d.%d.%d.%d",
186 $hash->{$item} / 256 / 256 / 256,
187 $hash->{$item} / 256 / 256 % 256,
188 $hash->{$item} / 256 % 256,
189 $hash->{$item} % 256);
190 printf "%*s%-*s%s\n", $in, "", $wi, $item, $addr;
191 }
192 }
193
194 sub do_soap {
195 my $soap = shift;
196 my $name = shift;
197 my @args = @_;
198 my $method;
199
200 $method = SOAP::Data->name($name)
201 ->attr( { xmlns => $soap->ns } );
202
203 if ($amt_debug) {
204 print "-- \n";
205 open XML, "| xmllint --format -";
206 print XML $soap->serializer->envelope(method => $method, @_);
207 close XML;
208 print "-- \n";
209 }
210
211 my $ret = $soap->call($method, @args);
212 print_result($ret);
213 return $ret;
214 }
215
216 sub check_amt_version {
217 my $major = shift;
218 my $minor = shift;
219
220 $amt_version =~ m/^(\d+).(\d+)/;
221 return if $1 > $major;
222 return if $1 == $major && $2 >= $minor;
223 die "version mismatch (need >= $major.$minor, have $amt_version)";
224 }
225
226 sub print_general_info() {
227 printf "### AMT info on machine '%s' ###\n", $amt_host;
228
229 printf "AMT version: %s\n", $amt_version;
230
231 my $hostname = $nas->GetHostName()->paramsout;
232 my $domainname = $nas->GetDomainName()->paramsout;
233 printf "Hostname: %s.%s\n", $hostname, $domainname;
234
235 my $powerstate = $rcs->GetSystemPowerState()->paramsout;
236 printf "Powerstate: %s\n", $ps [ $powerstate & 0x0f ];
237 }
238
239 sub print_remote_info() {
240 my @rccaps = $rcs->GetRemoteControlCapabilities()->paramsout;
241 printf "Remote Control Capabilities:\n";
242 printf " IanaOemNumber %x\n", $rccaps[0];
243 printf " OemDefinedCapabilities %s%s%s%s%s\n",
244 $rccaps[1] & 0x01 ? "IDER " : "",
245 $rccaps[1] & 0x02 ? "SOL " : "",
246 $rccaps[1] & 0x04 ? "BiosReflash " : "",
247 $rccaps[1] & 0x08 ? "BiosSetup " : "",
248 $rccaps[1] & 0x10 ? "BiosPause " : "";
249
250 printf " SpecialCommandsSupported %s%s%s%s%s\n",
251 $rccaps[2] & 0x0100 ? "PXE-boot " : "",
252 $rccaps[2] & 0x0200 ? "HD-boot " : "",
253 $rccaps[2] & 0x0400 ? "HD-boot-safemode " : "",
254 $rccaps[2] & 0x0800 ? "diag-boot " : "",
255 $rccaps[2] & 0x1000 ? "cd-boot " : "";
256
257 printf " SystemCapabilitiesSupported %s%s%s%s\n",
258 $rccaps[3] & 0x01 ? "powercycle " : "",
259 $rccaps[3] & 0x02 ? "powerdown " : "",
260 $rccaps[3] & 0x03 ? "powerup " : "",
261 $rccaps[3] & 0x04 ? "reset " : "";
262
263 printf " SystemFirmwareCapabilities %x\n", $rccaps[4];
264 }
265
266 sub print_network_info() {
267 my $ret;
268
269 $ret = $nas->EnumerateInterfaces();
270 my @if = $ret->paramsout;
271 foreach my $if (@if) {
272 printf "Network Interface %s:\n", $if;
273 my $arg = SOAP::Data->name('InterfaceHandle' => $if);
274 $ret = $nas->GetInterfaceSettings($arg);
275 my $desc = $ret->paramsout;
276 print_hash($ret->paramsout, 4, 32);
277 print_hash_ipv4($ret->paramsout->{'IPv4Parameters'}, 8, 28);
278 }
279 }
280
281 sub remote_control($$) {
282 my $command = shift;
283 my $special = shift;
284 my @args;
285
286 my $hostname = $nas->GetHostName()->paramsout;
287 my $domainname = $nas->GetDomainName()->paramsout;
288 printf "host %s.%s, %s [y/N] ? ", $hostname, $domainname, $command;
289 my $reply = <>;
290 if ($reply =~ m/^(y|yes)$/i) {
291 printf "execute: %s\n", $command;
292 push (@args, SOAP::Data->name('Command' => $rcc{$command}));
293 push (@args, SOAP::Data->name('IanaOemNumber' => 343));
294 if (defined($special) && defined($rccs{$special})) {
295 push (@args, SOAP::Data->name('SpecialCommand'
296 => $rccs{$special} ));
297 }
298 if (defined($special) && defined($rccs_oem{$special})) {
299 push (@args, SOAP::Data->name('OEMparameters' => 1 ));
300 push (@args, SOAP::Data->name('SpecialCommand'
301 => $rccs_oem{$special} ));
302 }
303 do_soap($rcs, "RemoteControl", @args);
304 } else {
305 printf "canceled\n";
306 }
307 }
308
309 sub ipv4_addr($$) {
310 my $name = shift;
311 my $ipv4 = shift;
312
313 $ipv4 =~ m/(\d+).(\d+).(\d+).(\d+)/ or die "parse ipv4 address: $ipv4";
314 my $num = $1 * 256 * 256 * 256 +
315 $2 * 256 * 246 +
316 $3 * 256 +
317 $4;
318 printf STDERR "ipv4 %-24s: %-16s -> %d\n", $name, $ipv4, $num
319 if $amt_debug;
320 return SOAP::Data->name($name => $num);
321 }
322
323 sub configure_network {
324 my $if = shift;
325 my $link = shift;
326 my $ip = shift;
327 my $mask = shift;
328 my $gw = shift;
329 my $dns1 = shift;
330 my $dns2 = shift;
331
332 my $mode;
333 my @ifdesc;
334 my @ipv4;
335
336 my $method;
337 my @args;
338
339 # build argument structs ...
340 die "no interface" if !defined($if);
341 die "no linkpolicy" if !defined($link);
342 if (defined($ip)) {
343 $mode = "SEPARATE_MAC_ADDRESS";
344 die "no ip mask" if !defined($mask);
345 die "no default gw" if !defined($gw);
346 $dns1 = $gw if !defined($dns1);
347 $dns2 = "0.0.0.0" if !defined($dns2);
348 push (@ipv4, ipv4_addr("LocalAddress", $ip));
349 push (@ipv4, ipv4_addr("SubnetMask", $mask));
350 push (@ipv4, ipv4_addr("DefaultGatewayAddress", $gw));
351 push (@ipv4, ipv4_addr("PrimaryDnsAddress", $dns1));
352 push (@ipv4, ipv4_addr("SecondaryDnsAddress", $dns2));
353 } else {
354 $mode = "SHARED_MAC_ADDRESS";
355 # no ip info -- use DHCP
356 }
357
358 push (@ifdesc, SOAP::Data->name("InterfaceMode" => $mode));
359 push (@ifdesc, SOAP::Data->name("LinkPolicy" => $link));
360 push (@ifdesc, SOAP::Data->name("IPv4Parameters" =>
361 \SOAP::Data->value(@ipv4)))
362 if @ipv4;
363
364 push (@args, SOAP::Data->name("InterfaceHandle" => $if));
365 push (@args, SOAP::Data->name("InterfaceDescriptor" =>
366 \SOAP::Data->value(@ifdesc)));
367
368 # perform call
369 do_soap($nas, "SetInterfaceSettings", @args);
370 }
371
372
373 sub command {
374 my ($amt_command,$amt_arg) = @_;
375
376 soap_init;
377
378 if ($amt_command eq "info") {
379 print_general_info;
380 print_remote_info;
381 } elsif ($amt_command eq "netinfo") {
382 check_amt_version(2,5);
383 print_network_info;
384 } elsif ($amt_command eq "netconf") {
385 check_amt_version(2,5);
386 configure_network(@ARGV);
387 } elsif ($amt_command =~ m/^(reset|powerup|powerdown|powercycle)$/) {
388 remote_control($amt_command, $amt_arg);
389 } else {
390 print "unknown command: $amt_command\n";
391 }
392
393 }
394
395 warn 'loaded';
396
397 1;

  ViewVC Help
Powered by ViewVC 1.1.26