Chinaunix首页 | 论坛 | 博客
  • 博客访问: 313683
  • 博文数量: 66
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 509
  • 用 户 组: 普通用户
  • 注册时间: 2015-04-29 13:56
文章分类
文章存档

2018年(2)

2017年(6)

2016年(34)

2015年(24)

我的朋友

分类: LINUX

2016-01-22 09:01:30

一个常见的应用场景就是,某个设备插上网线的时候,设备会去自动申请IP(如果设备没有IP)
那就需要应用层能够捕获硬件Link up-down事件,link up-down最先获取到事件的是 驱动层。
在/driver/net/phy.c里面会有 phy_print_status函数,netif_msg_link/netif_msg_ifup/netif_msg_ifdown也可以获取网口up-down 状态。

应用层要做到获取up-down信息,可以有2种做法:
1. 是查询,应用层不停的查询网卡状态,发现up的时候,就去申请IP
2. 中断通知,驱动发现网口up-down的时候,中断通知应用层

第一种做法主要是通过检查 ifconfig结果里面的RUNNING关键字来做到的
eth0      Link encap:Ethernet  HWaddr 00:22:A2:00:10:11
          inet addr:192.168.2.1  Bcast:192.168.2.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1415 errors:0 dropped:0 overruns:0 frame:0
          TX packets:120 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:100515 (98.1 KiB)  TX bytes:9401 (9.1 KiB)
          Interrupt:106

当网口是up的时候,会有RUNNING,down的时候,则没有, 源码如下:

#include
#include
#include
#include
#include

char *net_detect(char* net_name)
{
        int skfd = 0;
        struct ifreq ifr;


        skfd = socket(AF_INET, SOCK_DGRAM, 0);
        if(skfd < 0) {
                printf("%s:%d Open socket error!\n", __FILE__, __LINE__);
                return NULL;
        }


        strcpy(ifr.ifr_name, net_name);


        if(ioctl(skfd, SIOCGIFFLAGS, &ifr) <0 ) {
                printf("%s:%d IOCTL error!\n", __FILE__, __LINE__);
                printf("Maybe ethernet inferface %s is not valid!", ifr.ifr_name);
                close(skfd);
                return NULL;
        }


        if(ifr.ifr_flags & IFF_RUNNING) {
                return "UP";
        } else {
                return "DOWN";
        }
}
int main()
{
        printf("%s\n",net_detect("eth0"));
        return 0;
}

第二种做法,通过内核给应用层发signal信号(类似中断,sigint等),应用层收到后再做响应处理
首先用request_irq申请一个中断,然后用fasync_helper/kill_fasync把中断和驱动关联起来,应用层
在通过fcntl(iFd, F_SETOWN, getpid()) 将本进程和驱动关联,再通过fcntl(iFd, F_SETFL, iOFlags | FASYNC);
设置FASYNC flag,这样当驱动收到中断时候,就能及时通知应用层。

第一种做法,优点是实现都在应用层,但是实时性会差些,同时使用时候不能ifdown掉某个Interface
第二种做法,优点是实时性高,通用性好,缺点是增加了内核开销
阅读(14621) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~