zoukankan      html  css  js  c++  java
  • 内核arp请求

    Linux 内核 网络地址转换函数 in_aton、 in4_pton 和 in6_pton

    #ifndef _LINUX_INET_H
    #define _LINUX_INET_H
     
    #include <linux/types.h>
     
    /*
     * These mimic similar macros defined in user-space for inet_ntop(3).
     * See /usr/include/netinet/in.h .
     */
    #define INET_ADDRSTRLEN        (16)
    #define INET6_ADDRSTRLEN    (48)
     
    extern __be32 in_aton(const char *str);
    extern int in4_pton(const char *src, int srclen, u8 *dst, int delim, const char **end);
    extern int in6_pton(const char *src, int srclen, u8 *dst, int delim, const char **end);
    #endif    /* _LINUX_INET_H */
    /**
     * in4_pton - convert an IPv4 address from literal to binary representation
     * @src: the start of the IPv4 address string ,地址字符串
     * @srclen: the length of the string, -1 means strlen(src),字符串长度,可以填写-1
     * @dst: the binary (u8[4] array) representation of the IPv4 address,地址缓存
     * @delim: the delimiter of the IPv4 address in @src, -1 means no delimiter,分隔符
     * @end: A pointer to the end of the parsed string will be placed here,可以填写NULL
     *
     * Return one on success, return zero when any error occurs
     * and @end will point to the end of the parsed string.
     *
     * 成功返回1,出错返回0
     */
    int in4_pton(const char *src, int srclen, u8 *dst, int delim, const char **end);
     
    用例:
        __be32 saddr;
        ret = in4_pton("192.168.1.1", strlen("192.168.1.1"), &addr, -1, NULL);

    三个函数头文件都是<linux/inet.h>.,使用是只要包含该头文件就可以了。

    arp_send_dst(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
                 dst_hw, dev->dev_addr, NULL, dst);

    dev_hard_header

    dev->header_ops         = &eth_header_ops

    static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
                      unsigned short type,
                      const void *daddr, const void *saddr,
                      unsigned int len)
    {
        if (!dev->header_ops || !dev->header_ops->create)
            return 0;
    
        return dev->header_ops->create(skb, dev, type, daddr, saddr, len);
    }
    /**
     * eth_header - create the Ethernet header
     * @skb:    buffer to alter
     * @dev:    source device
     * @type:    Ethernet type field
     * @daddr: destination address (NULL leave destination address)
     * @saddr: source address (NULL use device source address)
     * @len:   packet length (<= skb->len)
     *
     *
     * Set the protocol type. For a packet of type ETH_P_802_3/2 we put the length
     * in here instead.
     */
    int eth_header(struct sk_buff *skb, struct net_device *dev,
               unsigned short type,
               const void *daddr, const void *saddr, unsigned int len)
    {
        struct ethhdr *eth = (struct ethhdr *)skb_push(skb, ETH_HLEN);
        if (type != ETH_P_802_3 && type != ETH_P_802_2)
            eth->h_proto = htons(type);
        else
            eth->h_proto = htons(len);
        /*
         *      Set the source hardware address.
         */
        if (!saddr)
            saddr = dev->dev_addr;
        memcpy(eth->h_source, saddr, ETH_ALEN);
        if (daddr) {
            memcpy(eth->h_dest, daddr, ETH_ALEN);
            return ETH_HLEN;
        }
        /*
         *      Anyway, the loopback-device should never use this function...
         */
        if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
            memset(eth->h_dest, 0, ETH_ALEN);
            return ETH_HLEN;
        }
        return -ETH_HLEN;
    }

    arp_create

    
         dev_kfree_skb_any(skb);
         //struct sk_buff *skb;
         __be32 src_addr, dst_addr;
         in4_pton("10.10.10.8", strlen(DEST_IP),(u8 *)&dst_addr, '\0', NULL);
         in4_pton("10.10.10.7", strlen(SRC_IP), (u8 *)&src_addr, '\0', NULL);
         skb = arp_create(ARPOP_REQUEST, ETH_P_ARP,  dst_addr, dev, src_addr,NULL, dev->dev_addr, NULL);
    start_xmit(skb,dev);
    /* Create and send an arp packet. */
    static void arp_send_dst(int type, int ptype, __be32 dest_ip,
                 struct net_device *dev, __be32 src_ip,
                 const unsigned char *dest_hw,
                 const unsigned char *src_hw,
                 const unsigned char *target_hw,
                 struct dst_entry *dst)
    {
        struct sk_buff *skb;
    
        /* arp on this interface. */
        if (dev->flags & IFF_NOARP)
            return;
    
        skb = arp_create(type, ptype, dest_ip, dev, src_ip,
                 dest_hw, src_hw, target_hw);
        if (!skb)
            return;
    
        skb_dst_set(skb, dst_clone(dst));
        arp_xmit(skb);
    }

    static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
    {
            skb->_skb_refdst = (unsigned long)dst;
    }
    我们常见的IP地址都是以点分十进制格式表示,例如“172.18.1.231”。而在程序中基本是以如下的结构表示一个IP:
    
    
    struct in_addr {
             __be32     s_addr; //其实就是一个32bit的数字
    };


       它和点分十进制格式的IP地址可以通过一组API实现相互转换:
    
    
    int inet_aton(const char *cp,struct in_addr *inp) 无效的地址cp则返回0;否则返回非0
    char *inet_ntoa(struct in_addr in) 将一个32位的IP地址转换成点分十进制字符串。
  • 相关阅读:
    树(三)——自平衡二叉树(AVL)
    树(二)——二叉树
    10. IDENTITY属性使用小结
    09. 约束与索引的联系
    08. 删除重复&海量数据
    07. 分页写法小结
    06. 父子节点(树)遍历写法小结
    01. SQL Server 如何读写数据
    05. 取SQL分组中的某几行数据
    04. 字符串合并与拆分写法小结
  • 原文地址:https://www.cnblogs.com/dream397/p/15598802.html
Copyright © 2011-2022 走看看