设为首页 收藏本站
查看: 6355|回复: 0

[经验分享] windows下通过网卡远程开机

[复制链接]

尚未签到

发表于 2018-6-14 08:17:38 | 显示全部楼层 |阅读模式
Windows下远程开机



软件:netwaker



                        一、硬件设置

1.被控机的硬件需求

           实现网络开机,需要主板、网卡、电源3个设备支持。首先需要查看主板使用说明书,查看主板是否支持Wake-Up On Internal ModemWOM)或者Wake-up . LANWOL)技术,如果支持就说明主板支持远程开机。能否实现远程唤醒,其中最主要的一个部件就是支持WOL的网卡,远端被唤醒计算机的 WOL,而用于唤醒其他计算机的网卡则不必支持WOL。另外,当一台计算机中安装有多块网卡时,只须将其中的一块设置为可远程唤醒即可。除此以外,电脑必须安装有符合ATX 2.03标准的ATX电源,+5VStandby电流至少应在720mA以上。有的早期电源可能只设计到500mA,在进行网络开机时,某些耗电较大的网卡可能会无法启动。






2.CMOS设置




          首先需要进行CMOS和网卡设置,启动计算机,进入CMOS参数设置。选择电源管理设置“Power

Management Setup”菜单,将“Wake up . LAN”项和“Wake . PCI Card”项均设置为“Enable”,启用该计算机的远程唤醒功能。有些网卡需要通过跳线将“Wake-on-LAN”功能设置为“Enable”。

          WOL电缆的两端分别插入网卡和主板的3芯插座中,将网卡与计算机主板连接起来。如果主板支持PCI2.2标准,只要开启“Wake . PCI Card”功能就可以了,无须使用WOL电缆连接。然后启动计算机,安装网卡驱动程序并完成网卡的网络连接设置。



3.获取被控端网卡的MAC地址

         Windows 9X系统中,单击“开始→运行”,输入“winipcfg”命令。弹出“IP配置”窗口,在下拉列表中选择“PCI Fast Ethernet Adapter”,此时显示在“适配器地址”栏中的文字即为该网卡的MAC地址。

Windows 2000系统中,单击“开始→运行”命令,在“运行”对话框中输入“cmd”命令,单击“确定”按钮,打开命令提示符。在c:\>下输入“ipconfig /all”命令后出现的Physical Address就是MAC地址。 记下这个地址。关闭计算机。



二、远程开机

                完成以上工作后,在主控端电脑上运行 NetWaker,将被控端的MAC地址填在相应的栏目内,点击开机按钮,你就可以看到被控的主机开始启动了! c Packet的使用方法2008-02-12 20:36Magic Packet1.0软件的取得十分方便,你可以从轻松地从网上下载,其下载地址http: //www.amd.com/products/npd/software/pcnet_family/drivers/magicpacket.html,找到“Download PCnet Magic Packet Utility”一项,在其下面标有“Size 946,216 Date 01-26-99 Version 1.0”字样,下载后的文件名是magic_pkt.exe,文件大小为924KB,直接运行它就可以开始安装。该软件默认安装在C:\pcnet\ magic_pkt目录下,由于不会在程序项中或桌面上增加任何快捷方式,因此,要想运行该软件,用户必须自己到所安装的目录下执行magpac.exe,自己动手将该程序在桌面上建立一个快捷方式当然更方便了。

1.远程唤醒一台电脑:运行magpac.exe,其界面如图2-4所示。




        在“Magic Packets”菜单中单击“Power . .e Host(启动某一主机)命令,显示“Send a Magic Packet to .e Host(向主机发送唤醒数据包)对话框(如图所示)。在“Destination Ethernet Address(目标以太网地址)中输入欲唤醒电脑网卡的MAC地址,单击“Send(发送)按钮(如图2-5)。局域网上的远程电脑将自动启动。




2.远程唤醒多台电脑:

         在“Magic Packets”菜单中单击“Create a List Hosts(创建主机列表)命令,显示“Create a List of Hosts LAN(在局域网上创建主机列表)对话框(如图2-6所示)。在“Filename-Save List of” (保存列表的文件名)一栏中键入一个远程开机文件名,单击“OK”按钮,软件会自动开始搜索局域网中的电脑。搜索完会显示“Magic Packet Utility”(Magic Packet应用)窗口,这时,你需要利用“Edit(编辑)菜单中“Cut(剪切)命令,从该列表中删除那些不希望远程唤醒的电脑,而后在 File(文件)菜单中单击“Save(保存)命令保存这个远程启动文件。




      设置好远程启动文件后,如果要进行远程唤醒时,在“Magic Packets”菜单中单击“Group Power .(成组开机)命令,显示“Set Alarm for Groups(设置成组唤醒)对话框(如图2-7所示)。单击“Browse”按钮,找到你刚刚保存的远程启动文件并打开,然后单击“Add”和 OK”按钮,就可以实现一组电脑的远程启动了。在这里,我们还可以根据需要,为这组电脑设置启动时间,可分别选中相应日期的复选框并设置具体唤醒时间,这样就能够实现成组电脑的自动定时唤醒了。




      当然,我们在使用完远程电脑后,也应该像前面笔者所说的那样,让电脑在空闲一段时间后自动关机,延长了电脑寿命的同时,也能节省了不少电哦






Chapter1:远程唤醒的基本条件
Wake . LAN(WOL),俗称远程唤醒,是现在很多网卡都支持的功能。而远程唤醒的实现,主要是向目标主机发送特殊格式的数据包,是AMD公司制作的Magic Packet这套软件以生成网络唤醒所需要的特殊数据包,俗称魔术包(Magic Packet)。Magic Packet格式虽然只是AMD公司开发推广的技术,并非世界公认的标准,但是仍然受到很多网卡制造商的支持,因此 许多具有网络唤醒功能的网卡都能与之兼容。
Boeing、IBM、Cisco、United States Army、Canada Customs and Revenue Agency、Intel Corp、Compaq、Lucent、Microsoft Ltd、Dell Computer Corporation、Hewlett-Packard、Siemens、Walt Disney World Co.、Compuware Corp、AMD (Isn't that ironic)、Nortel Networks、Macromedia Inc.、British Telecommunications plc、eBay等等公司均在使用WOL技术。
要实现远程唤醒,还需要硬件的设置:
主板和网卡必须都支持远程唤醒功能。一般目前的主板都支持这个功能(2002年以后的板都有),支持的主板上通常都有一个专门的3芯插座,以便在关机时为网卡供电。但并非所有的网卡都支持该功能(特别是一些价格较便宜的低档网卡),要判断网卡是否支持远程唤醒功能的方法很简单,支持远程唤醒的网卡上都有一个3针的WOL接口和一条3芯的远程唤醒电缆,通过判断网卡是否带有WOL接口即可(有些较新的网卡可能没有WOL接口也能支持远程唤醒。这是因为现在流行的主板支持PCI2.2标准,而PCI 2.2标准不需要通过专门的WOL接口为网卡供电,允许主板直接通过PCI插槽向网卡提供Standby电源)。
1.硬件连接
网卡安装完毕后将远程唤醒电缆的一端插入到网卡的WOL接口上,另外一端与主板的3针WOL远程唤醒接口相连(该接口旁通常标有WOL_CON的字样,当然如果主板和网卡都支持PCI2.2标准则无须做这一步)。
需要说明的是,某些主板上已经集成了具有网络唤醒功能的网卡,只要开启“Wake . PCI Card”功能就可以了,没有什么三脚插座,更不需要专用的三芯连线。
2.CMOS设置
打开CMOS远程唤醒功能很简单,只要将CMOS设置中的“Power Management Setup”的“Wake Up . LAN”或“Resume by LAN”项设置为“Enable”或“On”即可。
ATX电源
必须要使用ATX电源,而且其+5V Standby电流必须比较大,根据Intel的建议,它需要在600mA以上。该电流的大小可以从电源外部标识中的+5VSB(或+5AUX,5VSB)栏里查到。(绝大部分的网卡在0.7A以下都可唤醒)
如果远程计算机最后一次关机的时候是属于非正常关机(突然断电或者关机时死机等),唤醒就有可能会失败。在Windows 2000/XP系统中如果在关闭计算机时使用休眠 ,也可能会造成唤醒失败。这是因为一些网卡需要复位一个标记,这只有在操作系统正常关闭的时候才会发生。
软件的实现方面,其实就是通过socket向目标的机器发送Magic Packet(魔术包),魔术包的格式,包含有连续6个字节的“FF”和连续重复16次的MAC地址。你可以在任何协议的数据包(如在TCP/IP、IPX包)中填上 "FFFFFFFFFFFF"+连续重复16次的MAC地址,就可利用该协议作出一个使用该协议的Magic Packet。只要NIC检测到数据包中任何地方有这样的片段,便会将计算机唤醒。
假设被控计算机的Mac地址为01:02:03:04:05:06 (6 bytes),那么那台机器的网卡在数据帧内发现以下的片断便会将计算机唤醒。


Code:

FFFFFFFFFFFF010203040506010203040506010203040506010203040506
010203040506010203040506010203040506010203040506010203040506
010203040506010203040506010203040506010203040506010203040506
010203040506010203040506

正是因为这个Magic Packet可以封装在任何协议的数据包中,可以在各种Router和switch之间传送,而不会影响Magic Packet唤醒的功能。也就是说,不管Magic Packet是来自于LAN还是WAN,只要网卡检测到Magic Packet就能唤醒。最常被使用的是UDP广播包,不需要端口号,只要知道被控计算机的MAC地址即可。
注:UDP广播分两种,一种是directed broadcast,比如你的网段是192.168.0.X,你就往192.168.0.255发就可以了。另一种是limited broadcast,广播地址是255.255.255.255
要了解更多请参见“Magic Packet? Technical Documentation”
http://www.amd.com.cn/chcn/ConnectivitySolutions/TechnicalResources/0,,50_2334_2481_2494,00.html
Chapter2:局域网远程唤醒
请你务必弄懂Chapter1中所讲解的东西再开始看Chapter2。
首先声明一点,在你机上安装任何远程控制软件的客户端都不可以实现远程唤醒,PCAnywhere、Remote Administrator之类的远程控制软件在关机的情况下根本不可能工作,手机短信实现远程唤醒也是天方夜谭。远程唤醒只能基于你的计算机的硬件去实现。
现在假设A、B两机位于同一个局域网中, 要用主控计算机A机远程唤醒被控计算机B。
那你只要在B机的CMOS设置(有人喜欢叫BIOS设置)中设置好两个地方:
1.开启“Wake . PCI Card”功能,没有这项的设置的话,那可能就要插远程唤醒电缆了;
这步的目的是“在关机时为网卡供电”
2.开启“Wake Up . LAN”或“Resume by LAN”功能;
这步的目的是“让主板接受网卡发送的唤醒信号”
设置好之后,就保存退出。
在A机你要下载局域网唤醒的小软件,下面我推荐两款给大家用吧。
PCnet Magic Packet Utility——AMD的产品,英文介面,需要安装才可以使用,功能比较强大
http://dl.pconline.com.cn/html_2/1/59/id=1885&pn=0.html
NetWaker for windows 简体中文版
http://www.j66.net/lbmagic/doc1.htm
下面以AMD的Magic Packet为例,在A机下载安装好。该软件默认安装在C:\pcnet\magic_pkt目录下,由于不会在程序项中或桌面上增加任何快捷方式,因此,要想运行该软件,用户必须自己到所安装的目录下执行magpac.exe,自己动手将该程序在桌面上建立一个快捷方式当然更方便了。
运行magpac.exe,在“Magic Packets”菜单中单击“Power . .e Host”(启动某一主机)命令,显示“Send a Magic Packet to .e Host”(向主机发送唤醒数据包)对话框(如图所示)。在“Destination Ethernet Address”(目标以太网地址)中输入B机的网卡MAC地址,单击“Send”(发送)按钮。B机将自动启动。
当然,Magic Packet还可以远程唤醒局域网内多台计算机,留给你自己去摸索吧。
下面我提供一个图文版Magic Packet的教程链接供大家学习吧:
http://www.codefans.com/ArticleView/Article_1174.html
Chapter3:广域网的远程唤醒
1、广域网中实现远程唤醒的话,其实也不比局域网远程唤醒难多少。被控计算机端只要增加一个能获取公网IP地址、能设置端口映射的设备(如路由器、防火墙)。
现在主流的宽带上网方式不外乎ADSL跟Cable(即视讯宽频、有线电视网络)两种,都可以使用宽带路由实现共享上网,下面简单讲下这两种上网方式下路由器怎样设置才能获取到公网IP地址。
ADSL分两种,一种是固定IP的ADSL,在路由器中选择固定IP地址上网方式,填上电信分配给你的公网IP地址即可;另外一种是动态IP的ADSL,在路由器中设置PPPoE拨号,填上你的用户名、密码,拨号成功后路由器就会自动获取一个公网IP地址;
Cable的话,只要在路由器设置“自动获取IP”上网方式,路由器就会自动获取一个公网IP地址;
正确设置好路由器之后,在路由器的连接状态那里可以直接查看其公网IP地址。
2、在路由器中设置允许“Subnet Directed Broadcasts(子网定向广播)”,并且设置端口映射,将路由器的某一端口映射到被控计算机的任意端口
3、只要路由器通电,主控计算机就能通过互联网向路由器发送Magic Packet,而路由器与被控计算机之间是通过网线连通的,所以可以很顺利地将Magic Packet发送到被控计算机的网卡。路由器实际上起到中间桥梁的作用。
附上能发送Magic Packet的网页Wake . Lan over the Internet
http://www.depicus.com/wake-on-lan/woli.aspx
Netmask是一个比较值得注意的地方,填错了的话,目标IP地址就会出错。
下面我通过一个例子简单讲述一下广域网远程唤醒的过程
假设主控计算机为A机,被控计算机为B机
B机的所在局域网环境如下:一条ADSL接在4口路由器R1上,R1的4 个口分别连接着S1,S2,S3,S4四台交换机。B机接在S3交换机的其中一个口。
R1拨号后自动获取到的IP为12.34.56.78,B机在局域网中的IP为192.168.1.167,MAC地址为BB:BB:BB:BB:BB:BB。
在R1设置端口映射条目如下:12.34.56.78:9——>192.168.1.255:168
这里192.168.1.255为192.168.1.167所在网络的定向广播地址。
为什么不直接映射到192.168.1.167呢?因为当B机关机后,192.168.1.167这个IP不再与R1通信,R1中关于192.168.1.167的ARP条目也会很快就消失,所有与192.168.1.167这个IP通信的数据包都会被丢弃。
1.A机向12.34.56.78(255.255.255.251)这个目标IP的9号端口发送一个包含FFFFFFFFFFFF和连续重复16次BBBBBBBBBBBB的Magic Packet的单播包,中间经过了N个路由,该单播包顺利进入R1;
2.当R1检测到该数据包端口号为9,根据端口映射条目将该数据包的目标IP及端口号修改为192.168.1.255:168,此时该包被R1识别成定向广播包,因为R1已设置成允许Subnet Directed Broadcasts,所以该包并没有被丢弃;
3.R1将这个广播包向4个口广播,S1,S2,S3,S4所连的所有端口都收到这个广播包,即便B机处于关机状态也会收到该广播包;
B机的网卡检测到广播包中含自己MAC地址信息的Magic Packet,就会被唤醒,而其它机收到之后只会将该数据包丢弃。
4.实际应用中不建议主控计算机通过IP地址去跟路由器通讯,因为一旦路由器重新获取IP地址,远程唤醒就会失效。只要路由器支持动态域名解析(DDNS)功能,可将路由设置成IP地址变更时自动向DDNS提供商重新注册IP地址,DDNS提供商将根据你的帐号对你申请的域名进行域名解析。设置成功后就可以通过固定的域名去与路由器通讯,唤醒与该路由器直连的计算机。
欲了解更多关于DDNS(动态域名解析服务)的信息可参见这里:
http://publish.it168.com/2005/0519/20050519002902.shtml?cChanNel=no&cPositi
Chapter4:
网络远程唤醒还可以使用调制解调器,只要主板支持Wake-Up . Internal Modem(WOM),那么电话能通的地方都能利用WOM来实现远程唤醒。普通的内置调制解调器是不能直接通过PCI插槽得到+5VSB待命电流的,我们需要用一条“WOM”连接线,插到内置调制解调器及主板的WOM的插槽内。若使用外置式调制解调器时则不存在这个问题,因为工作电压是由外置式调制解调器单独的电源变压器提供的。
确保主机和调制解调器的电源打开电话线已插好,在POWER MANAGEMENT SETUP里找modem ring resume或者POWER . BY RING项,将其设定为ON或者ENABLED。只要Modem处于开启状态,拿另一部电话拨打Modem所连接的电话号码就可以通过WOM实现远程唤醒了。使用WOM进行远程唤醒不用担心电话费的问题,因为Modem只要侦测到电话震铃不需要接听电话就可以启动机器(所以我们不用花一分钱就可以打国际长途去唤醒位于另一个国家中的计算机了)。
然后WOM有个弊端,所有电话打进来都会马上唤醒,而这通电话很可能不是你打进的。计算机开着自然就要耗电的啦,当然你可以设置计算机在空闲一段时间后自动关机,这样可以省下不少电费。但是如果整天有电话打进的话,估计被控计算机也命不久已。


/* ether-wake.c: Send a magic packet to wake up sleeping machines. */
static char version_msg[] =
"ether-wake.c: v1.09 11/12/2003 Donald Becker, http://www.scyld.com/";
static char brief_usage_msg[] =
"usage: ether-wake [-i <ifname>] [-p aa:bb:cc:dd[:ee:ff]] 00:11:22:33:44:55\n"
"   Use '-u' to see the complete set of options.\n";
static char usage_msg[] =
"usage: ether-wake [-i <ifname>] [-p aa:bb:cc:dd[:ee:ff]] 00:11:22:33:44:55\n"
"\n"
"This program generates and transmits a Wake-On-LAN (WOL)\n"
"\"Magic Packet\", used for restarting machines that have been\n"
"soft-powered-down (ACPI D3-warm state).\n"
"It currently generates the standard AMD Magic Packet format, with\n"
"an optional password appended.\n"
"\n"
"The single required parameter is the Ethernet MAC (station) address\n"
"of the machine to wake or a host ID with known NSS 'ethers' entry.\n"
"The MAC address may be found with the 'arp' program while the target\n"
"machine is awake.\n"
"\n"
"Options:\n"
"-bSend wake-up packet to the broadcast address.\n"
"-DIncrease the debug level.\n"
"-i ifnameUse interface IFNAME instead of the default 'eth0'.\n"
"-p <pw>Append the four or six byte password PW to the packet.\n"
"A password is .ly required for a few adapter types.\n"
"The password may be specified in ethernet hex format\n"
"or dotted decimal (Internet address)\n"
"-p 00:22:44:66:88:aa\n"
"-p 192.168.1.1\n";
/*
This program generates and transmits a Wake-On-LAN (WOL) "Magic Packet",
used for restarting machines that have been soft-powered-down
(ACPI D3-warm state).  It currently generates the standard AMD Magic Packet
format, with an optional password appended.
This software may be used and distributed according to the terms
of the GNU Public License, incorporated herein by reference.
Contact the author for use under other terms.
This source file was originally part of the network tricks package, and
is now distributed to support the Scyld Beowulf system.
Copyright 1999-2003 Donald Becker and Scyld Computing Corporation.
The author may be reached as becker@scyld, or C/O
Scyld Computing Corporation
914 Bay Ridge Road, Suite 220
Annapolis MD 21403
Notes: . some systems dropping root capability allows the process to be
dumped, traced or debugged.
If someone traces this program, they get control of a raw socket.
Linux handles this safely, but beware when porting this program.
An alternative to needing 'root' is using a UDP broadcast socket, however
doing so .ly works with adapters configured for unicast+broadcast Rx
filter.  That configuration consumes more power.
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#if 0/* .ly exists . some versions. */
#include <ioctls.h>
#endif
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <features.h>
#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
#include <netpacket/packet.h>
#include <net/ethernet.h>
#else
#include <asm/types.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#endif
#include <netdb.h>
#include <netinet/ether.h>
/* Grrr, no consistency between include versions.
Enable this if setsockopt() isn't declared with your library. */
#if 0
extern int setsockopt __P ((int __fd, int __level, int __optname,
__ptr_t __optval, int __optlen));
#else/* New, correct head files.  */
#include <sys/socket.h>
#endif
u_char outpack[1000];
int outpack_sz = 0;
int debug = 0;
u_char wol_passwd[6];
int wol_passwd_sz = 0;
static int opt_no_src_addr = 0, opt_broadcast = 0;
static int get_dest_addr(const char *arg, struct ether_addr *eaddr);
static int get_fill(unsigned char *pkt, struct ether_addr *eaddr);
static int get_wol_pw(const char *optarg);
int main(int argc, char *argv[])
{
char *ifname = "eth0";
int .e = 1;/* True, for socket options. */
int s;/* Raw socket */
int errflag = 0, verbose = 0, do_version = 0;
int perm_failure = 0;
int i, c, pktsize;
#if defined(PF_PACKET)
struct sockaddr_ll whereto;
#else
struct sockaddr whereto;/* who to wake up */
#endif
struct ether_addr eaddr;
while ((c = getopt(argc, argv, "bDi:p:uvV")) != -1)
switch (c) {
case 'b': opt_broadcast++;break;
case 'D': debug++;break;
case 'i': ifname = optarg;break;
case 'p': get_wol_pw(optarg); break;
case 'u': printf(usage_msg); return 0;
case 'v': verbose++;break;
case 'V': do_version++;break;
case '?':
errflag++;
}
if (verbose || do_version)
printf("%s\n", version_msg);
if (errflag) {
fprintf(stderr, brief_usage_msg);
return 3;
}
if (optind == argc) {
fprintf(stderr, "Specify the Ethernet address as 00:11:22:33:44:55.\n");
return 3;
}
/* Note: PF_INET, SOCK_DGRAM, IPPROTO_UDP would allow SIOCGIFHWADDR to
work as non-root, but we need SOCK_PACKET to specify the Ethernet
destination address. */
#if defined(PF_PACKET)
s = socket(PF_PACKET, SOCK_RAW, 0);
#else
s = socket(AF_INET, SOCK_PACKET, SOCK_PACKET);
#endif
if (s < 0) {
if (errno == EPERM)
fprintf(stderr, "ether-wake: This program must be run as root.\n");
else
perror("ether-wake: socket");
perm_failure++;
}
/* Don't revert if debugging allows a normal user to get the raw socket. */
setuid(getuid());
/* We look up the station address before reporting failure so that
errors may be reported even when run as a normal user.
*/
if (get_dest_addr(argv[optind], &eaddr) != 0)
return 3;
if (perm_failure && ! debug)
return 2;
pktsize = get_fill(outpack, &eaddr);
/* Fill in the source address, if possible.
The code to retrieve the local station address is Linux specific. */
if (! opt_no_src_addr) {
struct ifreq if_hwaddr;
unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data;
strcpy(if_hwaddr.ifr_name, ifname);
if (ioctl(s, SIOCGIFHWADDR, &if_hwaddr) < 0) {
fprintf(stderr, "SIOCGIFHWADDR . %s failed: %s\n", ifname,
strerror(errno));
/* Magic packets still work if our source address is bogus, but
we fail just to be anal. */
return 1;
}
memcpy(outpack+6, if_hwaddr.ifr_hwaddr.sa_data, 6);
if (verbose) {
printf("The hardware address (SIOCGIFHWADDR) of %s is type %d  "
"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", ifname,
if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1],
hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
}
}
if (wol_passwd_sz > 0) {
memcpy(outpack+pktsize, wol_passwd, wol_passwd_sz);
pktsize += wol_passwd_sz;
}
if (verbose > 1) {
printf("The final packet is: ");
for (i = 0; i < pktsize; i++)
printf(" %2.2x", outpack);
printf(".\n");
}
/* This is necessary for broadcasts to work */
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&one, sizeof(one)) < 0)
perror("setsockopt: SO_BROADCAST");
#if defined(PF_PACKET)
{
struct ifreq ifr;
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFINDEX, &ifr) == -1) {
fprintf(stderr, "SIOCGIFINDEX . %s failed: %s\n", ifname,
strerror(errno));
return 1;
}
memset(&whereto, 0, sizeof(whereto));
whereto.sll_family = AF_PACKET;
whereto.sll_ifindex = ifr.ifr_ifindex;
/* The manual page incorrectly claims the address must be filled.
We do so because the code may change to match the docs. */
whereto.sll_halen = ETH_ALEN;
memcpy(whereto.sll_addr, outpack, ETH_ALEN);
}
#else
whereto.sa_family = 0;
strcpy(whereto.sa_data, ifname);
#endif
if ((i = sendto(s, outpack, pktsize, 0, (struct sockaddr *)&whereto,
sizeof(whereto))) < 0)
perror("sendto");
else if (debug)
printf("Sendto worked ! %d.\n", i);
#ifdef USE_SEND
if (bind(s, (struct sockaddr *)&whereto, sizeof(whereto)) < 0)
perror("bind");
else if (send(s, outpack, 100, 0) < 0)
perror("send");
#endif
#ifdef USE_SENDMSG
{
struct msghdr msghdr = { 0,};
struct iovec iovector[1];
msghdr.msg_name = &whereto;
msghdr.msg_namelen = sizeof(whereto);
msghdr.msg_iov = iovector;
msghdr.msg_iovlen = 1;
iovector[0].iov_base = outpack;
iovector[0].iov_len = pktsize;
if ((i = sendmsg(s, &msghdr, 0)) < 0)
perror("sendmsg");
else if (debug)
printf("sendmsg worked, %d (%d).\n", i, errno);
}
#endif
return 0;
}
/* Convert the host ID string to a MAC address.
The string may be a
Host name
IP address string
MAC address string
*/
static int get_dest_addr(const char *hostid, struct ether_addr *eaddr)
{
struct ether_addr *eap;
eap = ether_aton(hostid);
if (eap) {
*eaddr = *eap;
if (debug)
fprintf(stderr, "The target station address is %s.\n",
ether_ntoa(eaddr));
} else if (ether_hostton(hostid, eaddr) == 0) {
if (debug)
fprintf(stderr, "Station address for hostname %s is %s.\n",
hostid, ether_ntoa(eaddr));
} else {
(void)fprintf(stderr,
"ether-wake: The Magic Packet host address must be "
"specified as\n"
"  - a station address, 00:11:22:33:44:55, or\n"
"  - a hostname with a known 'ethers' entry.\n");
return -1;
}
return 0;
}
static int get_fill(unsigned char *pkt, struct ether_addr *eaddr)
{
int offset, i;
unsigned char *station_addr = eaddr->ether_addr_octet;
if (opt_broadcast)
memset(pkt+0, 0xff, 6);
else
memcpy(pkt, station_addr, 6);
memcpy(pkt+6, station_addr, 6);
pkt[12] = 0x08;/* Or 0x0806 for ARP, 0x8035 for RARP */
pkt[13] = 0x42;
offset = 14;
memset(pkt+offset, 0xff, 6);
offset += 6;
for (i = 0; i < 16; i++) {
memcpy(pkt+offset, station_addr, 6);
offset += 6;
}
if (debug) {
fprintf(stderr, "Packet is ");
for (i = 0; i < offset; i++)
fprintf(stderr, " %2.2x", pkt);
fprintf(stderr, ".\n");
}
return offset;
}
static int get_wol_pw(const char *optarg)
{
int passwd[6];
int byte_cnt;
int i;
byte_cnt = sscanf(optarg, "%2x:%2x:%2x:%2x:%2x:%2x",
&passwd[0], &passwd[1], &passwd[2],
&passwd[3], &passwd[4], &passwd[5]);
if (byte_cnt < 4)
byte_cnt = sscanf(optarg, "%d.%d.%d.%d",
&passwd[0], &passwd[1], &passwd[2], &passwd[3]);
if (byte_cnt < 4) {
fprintf(stderr, "Unable to read the Wake-On-LAN password.\n");
return 0;
}
printf(" The Magic packet password is %2.2x %2.2x %2.2x %2.2x (%d).\n",
passwd[0], passwd[1], passwd[2], passwd[3], byte_cnt);
for (i = 0; i < byte_cnt; i++)
wol_passwd = passwd;
return wol_passwd_sz = byte_cnt;
}
#if 0
{
to = (struct sockaddr_in *)&whereto;
to->sin_family = AF_INET;
if (inet_aton(target, &to->sin_addr)) {
hostname = target;
}
memset (&sa, 0, sizeof sa);
sa.sa_family = AF_INET;
strncpy (sa.sa_data, interface, sizeof sa.sa_data);
sendto (sock, buf, bufix + len, 0, &sa, sizeof sa);
strncpy (sa.sa_data, interface, sizeof sa.sa_data);
#if 1
sendto (sock, buf, bufix + len, 0, &sa, sizeof sa);
#else
bind (sock, &sa, sizeof sa);
connect();
send (sock, buf, bufix + len, 0);
#endif
}
#endif
/*
* Local variables:
*  compile-command: "gcc -O -Wall -o ether-wake ether-wake.c"
*  c-indent-level: 4
*  c-basic-offset: 4
*  c-indent-level: 4
*  tab-width: 4
* End:
*/

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-523491-1-1.html 上篇帖子: 55个经典开源Windows工具 下篇帖子: windows系统垃圾清理shell
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表