版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
By ·-22. -22.1主机的配 22.2被主机的配 -22.3实例测 -33. Ntonol-43.1几个重要的数据结构·-43.1.1structconsole-43.1.2structnetpoll·······························-53.1.3·····························-5-3.1.4····························-6-3.2实现分析·--3.2.1Netconsole初始化·······························-7-3.2.2具体运行实现··--网络的方式传送到另一台主机上。这样,就可以实现某台机子的kernelpanic信息这里使用的是netcat的方式进行监视的。安装好netcat后,执行s命令:#netcat-l-p3000030000块的依赖,以及在加载时必须配置相关的端口,IPs执行命令如下:#modprobenetconsolenetconsole=6666@25/eth7,30000@20/00:0C:29:E2:87:E8–30000@20/00:0C:29:E2:87:E8:三个位段分别是,远端端口,远端IP地址及远端机子的MAC地址。也就是我们在2.1节中指定的端口30000,以及其IP地址和MAC world模块,看看我们的printk信息是怎样被发送到主机上去的。1 #include#include#include6staticint{return11static {15 47$(RM)*.o*.mod.c*.ko##insmodnetconsole:networkloggingstartedoWorldnetconsole:networkloggingstartedoWorldGoodbye核的地址等。下面,我们开始来分析内核源码的netconsole的实现。Theinterfaceforaconsole,oranyotherdevicethatwantstoconsolemessages(printerIfaconsoledriverismarkedCON_BOOTthenitwillbeauto-whenthefirstrealconsoleis Thisisforearly-printk#define #defineCON_CONSDEV (2)/*Lastonthecommandline*/#defineCON_ENABLED #define #define (16)/*Safetocallwhencpuisofflinestruct{charvoid(*write)(structconsole*,constchar*,unsigned);int(*read)(structconsole*,char*,unsigned);structtty_driver*(*device)(structconsole*,int*);void(*unblank)(void);int(*setup)(structconsole*,char*); intcflag; console构,并实现其信息捕捉函数,即write函数。structnetpoll{structnet_device*dev;指向实际的网卡chardev_name[16],*name;//名字void*rx_hook)(structnetpoll*,intchar*,int钩子函数,这里并没有用到void(*drop)(structsk_buff*skb);//函数netconsole实现的一个关键数据结构。net_device成员指向了实际的网卡,我们正是通dmesg信息,因此就必须通过实际的网卡来发送数据。实际上,这个structnet_device{Thisisthefirstfieldofthe"visible"partofthis(i.e.asseenbyusersinthe"Space.c" Itisthethe /*devicenamehashchain*/structhlist_node #ifdefCONFIG_NETPOLL#ifdef (*poll_controller)(structnet_device*dev);/*bridgestuffstruct #ifdef/*thiswillgetinitializedateachinterfacetypeinitroutine*/structdivert_blk /*class/net/nameentry*/structclass_deviceclass_dev;/*spaceforoptionalstatisticsandwirelesssysfsgroups*/structattribute_group net_device结构包含了一个网络设备相关的所有信息,这里并没有全部列出其成员,其中用粉红色标记出来的,正是和netpoll相关的结构。从这里我们可以看到,如果要支持netconsolenetpollnetpollCONFIG_NETPOLL和CONFIG_NET_POLL_CONTROLLER这两个选项。structnetpoll_info{;//inttries;//如果发送失败,指定了发送信息的次数intrx_flags;spinlock_tstructnetpoll*rx_np;/*netpollthatregisteredanrx_hook*/structsk_buff_headarp_tx;/*listofarprequeststoreplyto*/staticcharconfig[256];//定义模块加载时指定参数选项的bufmodule_param_string(netconsoleconfig,256,0定义模块参数 consolestructconsole。因此,我们/*netconsolemoduleinitialization*/staticintinit_netconsole(void){/*Theconfigisthemoduleparameter,whichcontainsthecaptureoptions);printk("netconsole:notconfigured,aborting\n");return0;}/*Setupthenetpollcaptureoperations//指定了netpollreturn-/*registernetconsolethatcangettheprintkinfo*/register_console(&netconsole);//netconsoleprintk(KERN_INFO"netconsole:networkloggingstarted\n");return0;}/*Initializetheconsolecapture...*/staticstructconsolenetconsole={.name=.flags=CON_ENABLED|staticintconfiguredstaticintoption_setup(char{/*parsetheconsolecaptureoptions*/configured=!netpoll_parse_options(&np,opt);return1;}staticstructnetpollnp=//.remote_mac={0xff,0xff,0xff,0xff,0xff,0xff},//默认的机MAC地址,实际上intnetpoll_setup(structnetpoll{structnet_device*ndev=NULL;structin_device*in_dev;unsignedlongflags;if(np->dev_name)/*findthenetworkinterfacecardndev=dev_get_by_name(np->dev_name);if(!ndev){printk(KERN_ERR"%s:%sdoesn'texist,aborting.\n",np->name,np->dev_name);return-}np->devndev;npnpinfo=kmalloc(sizeof(*npinfo),GFP_KERNEL);if(!npinfo)gotonpinfo->rx_flags=npinfo->poll_owner=-1;//暂时无npinfo->triesMAX_RETRIES设定如果发送失败的话,重复的最大次数}npinfo=ndev-if(!ndev->poll_controller){//netdevpoll_controller,否则将不能支持printk(KERN_ERR"%s:%sdoesn'tsupportpolling,aborting.\n",np->name,np->dev_name);goto}ifnetif_running(ndev检查网卡是否启动unsignedlongatmost,atleast;printk(KERN_INFO"%s:device%snotupyet,forcingit\n",np->name,np->dev_name);if(dev_change_flags(ndev,ndev->flags|IFF_UP)<{printk(KERN_ERR"%s:failedtoopen%s\n",np->name,np->dev_name);gotorelease;}atleast=jiffies+HZ/10;atmost=jiffies+while(!netif_carrier_ok(ndev)){{"%s:timeoutwaitingforcarrier\n",}}/*Ifcarrierappearstocomeupinstantly,wetrustitandpausesothatwedon'tpumpallqueuedconsolemessagesintotheif(time_before(jiffies,{printk(KERN_NOTICE"%s:carrierdetect"untrustworthy,waiting4seconds\n",}}/*initializethelocalmac,thatwhyweneednotsetthelocalmacfortheoptions这里要进行本地mac地址的初始化。if(is_zero_ether_addr(np->local_mac)&&ndev->dev_addr)memcpy(np->local_mac,ndev->dev_addr,6);in_dev if(!in_dev||!in_dev-{printk(KERN_ERR"%s:noIPaddressfor%s,aborting\n",np->name,np->dev_name);goto}np->local_ip=ntohl(in_dev->ifa_list->ifa_local);printk(KERN_INFO"%s:localIP%d.%d.%d.%d\n",np->name,HIPQUAD(np->local_ip));}if(np->rx_hook)spin_lock_irqsave(&npinfo->rx_lock,flags);npinfo->rx_flags|=NETPOLL_RX_ENABLED;npinfo->rx_np=np;spin_unlock_irqrestore(&npinfo->rx_lock,flags);}/*filluptheskbqueue*//*lastthingtodoislinkittothenetdevicestructure*/ndev->npinfo=npinfo;/*avoidracingwithNAPIreadingnpinfo*/returnif(!ndev->npinfo) np->dev=NULL;return-1;}netconsolewrite函数的初始化,正是这个函数实现了对终端信息的捕捉。下面,我们就来分析一下write_msg()staticvoidwrite_msg(structconsole*con,constchar*msg,unsignedint{intfrag,left;unsignedlongflags;iffor(left=len;left;)/*thetransport msgshouldNOTlargerthanMAX_PRINT_CHUNK*/frag=min(left,MAX_PRINT_CHUNK);netpoll_send_udp(&np,msg,frag);/*sendthemsg*/msg+=frag;left-=}}voidnetpoll_send_udp(structnetpoll*np,constchar*msg,intlen){inttotal_len,eth_len,ip_len,udp_len;structsk_buff*skb;structudphdr*udph;structiphdr*iph;structethhdr*eth;udp_len=len+ip_len=eth_len=udp_len+total_len=eth_len+ETH_HLEN+skb=find_skb(np,total_len,total_len-len);if(!skb)memcpy(skb->data,msg,len);skb->len+=len;udph=(structudphdr*)skb_push(skb,sizeof(*udph));udph->source=htons(np->local_port);udph->dest=htons(np->remote_port);udph->len=htons(udp_len);udph->check=iph=(structiphdr*)skb_push(skb,/*iph->version=4;iph->ihl=5;*/put_unaligned(0x45,(unsignedchar*)iph); =0; =0; = =0;put_unaligned(htonl(np->local_ip),&(iph->saddr));put_unaligned(htonl(np->remote_ip),&(iph->daddr)); =ip_fast_csum((unsignedchar*)iph,iph-eth=(structethhdr*)skb_push(skb,eth->h_proto=htons(ETH_P_IP);memcpy(eth->h_dest,np->remote_mac,6);skb->dev=np->dev;}这个函数看起来并不复杂,主要是对一些控制信息的设置,最后调用了来发送数据。接下来看看netpoll_send_skp()是怎样实现的:staticvoidnetpoll_send_skb(structnetpoll*np,structsk_buff*skb){intif(!np||!np->dev||!netif_running(np->dev)){ }npinfo=np->dev-/*avoidrecursion/*forourowncpu我们
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 江苏省江阴市璜土中学高中地理 4.1区域农业发展-以我国东北地区为例教案2 新人教版必修3
- 2024-2025学年高中历史下学期第13周 罗斯福新政教学设计
- 2024六年级语文下册 第六单元 古诗词诵读 5 江上渔者教学设计+教案+素材 新人教版
- 2024-2025学年上海市浦东新区七年级上英语期中试卷(含答案和音频)
- 一年级数学第一学期沪教版- 期末试卷 1
- 西南林业大学《材料力学》2022-2023学年第一学期期末试卷
- 西京学院《现代教育技术及应用》2022-2023学年第一学期期末试卷
- 西京学院《矩阵论》2021-2022学年第一学期期末试卷
- 西京学院《基础工程与地基处理》2022-2023学年第一学期期末试卷
- 西京学院《护理教育学》2023-2024学年第一学期期末试卷
- 民间借贷利息计算表
- 2024江苏省铁路集团限公司春季招聘24人高频500题难、易错点模拟试题附带答案详解
- 沪科版(2024)八年级全一册物理第一学期期中学业质量测试卷 2套(含答案)
- Q GDW 10115-2022 110kV~1000kV架空输电线路施工及验收规范
- 2023《住院患者身体约束的护理》团体标准解读PPT
- 核心素养导向下初中数学课堂作业多元化设计
- 愚公移山英文 -中国故事英文版课件
- 国开经济学(本)1-14章练习试题及答案
- 小学数学教学“数学好玩”探析
- 画法几何及机械制图(第六版)1-1
- 控制溢流和井漏失返处理
评论
0/150
提交评论