Analysis of Network Programming instances based on ARM Embedded Linux

Source: Internet
Author: User

 **************************************** **************************************** **************************************** ***
Author: EasyWave time: 2013.01.19

Category: Linux application instance source code Declaration: reprinted, please keep the link

NOTE: If any error occurs, please correct it. These are my Learning Log articles ......

**************************************** **************************************** **************************************** ***

During this period, I learned about the USB tonet driver and used IOCTL to set the MAC address and check the connection status of the NIC. Therefore, I learned about network programming from the network. generally, the interaction between Linux network programs and the kernel is achieved through ioctl. ioctl interacts with the network protocol stack to obtain information about network interfaces, the ing property of the NIC device and the network interface configuration. you can also view, modify, and delete ARP high-speed cache information. Therefore, let's take a look at the specific implementation of the ioctl function.
Function Format:

# Include <sys/ioctl. h>

Int ioctl (int d, int request ,...);

Category

Request

Description

Data Type

Set

Connect

Port

SIOCATMARK

SIOCSPGRP

SIOCGPGRP

Whether it is in the out-of-band mark

Set the process ID or process group ID of the Set Interface

Obtain the process ID or group ID of the Set interface.

Int

Int

Int

Text

Parts

FIONBIN

FIOASYNC

FIONREAD

FIOSETOWN

FIOGETOWN

Set/clear non-blocking I/O flag

Set/clear signal-driven asynchronous I/O flag

Obtain the number of bytes in the receiving cache.

Set the process ID or group ID of the file.

Obtain the process ID or group ID of the file.

Int

Int

Int

Int

Int

Connect

Port

SIOCGIFCONF

SIOCSIFADDR

SIOCGIFADDR

SIOCSIFFLAGS

SIOCGIFFLAGS

SIOCSIFDSTADDR

SIOCGIFDSTADDR

SIOCGIFBRDADDR

SIOCSIFBRDADDR

SIOCGIFNETMASK

SIOCSIFNETMASK

SIOCGIFMETRIC

SIOCSIFMETRIC

SIOCGIFMTU

SIOCxxx

Retrieve the list of all interfaces

Set the interface address

Obtain the interface address

Set interface flag

Get interface flag

Set point-to-point address

Get point-to-point address

Get broadcast address

Set broadcast address

Obtain Subnet Mask

Set Subnet Mask

Obtain the measure of an interface

Set the measure of the interface

Obtain the MTU Interface

(A lot more depends on the implementation of the system)

Struct ifconf

Struct ifreq

Struct ifreq

Struct ifreq

Struct ifreq

Struct ifreq

Struct ifreq

Struct ifreq

Struct ifreq

Struct ifreq

Struct ifreq

Struct ifreq

Struct ifreq

Struct ifreq

ARP

SIOCSARP

SIOCGARP

SIOCDARP

Create/modify ARP table items

Obtain ARP table items

Delete ARP table items

Struct arpreq

Struct arpreq

Struct arpreq

Road

By

SIOCADDRT

SIOCDELRT

Add path

Delete path

Struct rtentry

Struct rtentry

   

 

 

Related Data Structure:

1): Network Interface request structure ifreq

Struct ifreq {# define IFHWADDRLEN 6 // six-byte hardware address, that is, MAC union {char ifrn_name [IFNAMESIZ]; // network interface name} ifr_ifrn; union {struct sockaddr ifru_addr; // local IP address struct sockaddr ifru_dstaddr; // target IP address struct sockaddr ifru_broadaddr; // broadcast IP address struct sockaddr ifru_netmask; // local subnet mask address struct sockaddr ifru_hwaddr; // local MAC address short ifru_flags; // Network Interface flag int ifru_ivalue; // different request meanings have different struct ifmap ifru_map; // NIC address ing int ifru_mtu; // maximum transmission unit char ifru_slave [IFNAMSIZ]; // placeholder char ifru_newname [IFNAMSIZE]; // new name void _ user * ifru_data; // user data struct if_settings ifru_settings; // device Protocol Settings} ifr_ifru;} # define ifr_name ifr_ifrn.ifrn_name; // interface name # define ifr_hwaddr restart; // MAC # define ifr_addr restart; // local IP # define ifr_dstaddr restart; // target IP # define ifr_broadaddr ifr_ifru.broadaddr; // broadcast IP # define ifr_netmask mask; // subnet mask # define ifr_flags mask; // flag # define ifr_metric ifr_ifru.ifru_ivalue; // interface degree # define ifr_mtu degree; // maximum transmission unit # define ifr_map ifr_ifru.ifru_map; // device address ing # define ifr_slave degree; // sub-device # define ifr_data ifr_ifru.ifru_data; // interface use # define ifr_ifrindex setting; // network interface number # define ifr_qlen serial; // transmission unit length # define ifr_newname setting; // new name # define ifr_seeting ifr_ifru.ifru_settings; // device Protocol Settings

2): ifmap

Struct ifmap {// The ing attribute unsigned long mem_start of the NIC device; // The start address unsigned long mem_end; // The end address unsigned short base_addr; // The base address unsigned char irq; // interrupt number unsigned char dma; // DMA unsigned char port; // port}

3): network configuration interface ifconf

Struct ifconf {// the network configuration struct is a buffer zone int ifc_len; // the size of the buffer zone ifr_buf union {char _ user * ifcu_buf; // display the dashboard pointer struct ifreq _ user * ifcu_req; // point to ifreq pointer} ifc_ifcu;}; # define ifc_buf ifc_ifcu.ifcu_buf; // The buffer address # define ifc_req accept; // ifc_req address

4): ARP high-speed cache operation arpreq

Struct arpreq {struct sockaddr arp_pa; // Protocol address struct sockaddr arp_ha; // hardware address int arp_flags; // mark struct sockaddr arp_netmask; // The subnet mask of the Protocol address char arp_dev [16]; // query the name of the network interface}

ARP high-speed cache operations, including IP address and hardware address ing tables. commands for operating ARP high-speed cache: SIOCDARP, SIOCGARP, and SIOCSARP are respectively used to delete a record of ARP high-speed cache, obtain a record of ARP high-speed cache and modify a record of ARP high-speed cache

Related example [the following is an excerpt from the Network: it has been verified on the machine]:

# Include <sys/types. h> # include <stdio. h> # include <stdlib. h> # include <unistd. h> # include <sys/ioctl. h> # include <sys/socket. h> # include <netdb. h> # include <string. h> # include <fcntl. h> # include <net/if. h> int main (int argc, char * argv []) {int s, sv6; int err; s = socket (AF_INET, SOCK_DGRAM, 0); if (s <0) {perror ("socket error"); return-1;} struct ifreq ifr; ifr. ifr_ifindex = 2; // obtain the name of the 2nd Network Interfaces Err = ioctl (s, SIOCGIFNAME, & ifr); if (err) {perror ("index error");} else {printf ("the % dst interface is: % s \ n ", ifr. ifr_ifindex, ifr. ifr_name);} memcpy (ifr. ifr_name, "eth0", 5); err = ioctl (s, SIOCGIFFLAGS, & ifr); if (! Err) {printf ("SIOCGIFFLAGS: % d \ n", ifr. ifr_flags);} err = ioctl (s, SIOCGIFMTU, & ifr); if (! Err) {printf ("SIOCGIFMTU: % d \ n", ifr. ifr_mtu);} err = ioctl (s, SIOCGIFHWADDR, & ifr); if (! Err) {unsigned char * hw = ifr. ifr_hwaddr.sa_data; printf ("SIOCGIFHWADDR: % 02x: % 02x: % 02x: % 02x: % 02x: % 02x \ n", hw [0], hw [1], hw [2], hw [3], hw [4], hw [5]);} err = ioctl (s, SIOCGIFMAP, & ifr); if (! Err) {printf ("SIOCGIFMAP, mem_start: % d, mem_end: % d, base_addr: % d, ifr_map: % d, dma: % d, port: % d \ n ", ifr. ifr_map.mem_start, ifr. ifr_map.mem_end, ifr. ifr_map.base_addr, ifr. ifr_map.irq, ifr. ifr_map.dma, ifr. ifr_map.port);} err = ioctl (s, SIOCGIFINDEX, & ifr); if (! Err) {printf ("SIOCGIFINDEX: % d \ n", ifr. ifr_ifindex);} err = ioctl (s, SIOCGIFTXQLEN, & ifr); if (! Err) {printf ("SIOCGIFTXQLEN: % d \ n", ifr. ifr_qlen);} struct sockaddr_in * sin = (struct sockaddr_in *) & ifr. ifr_addr; // stores the binary IP char ip Address [16]; // character array, which stores the string memset (ip, 0, 16); err = ioctl (s, SIOCGIFADDR, & ifr); if (! Err) {inet_ntop (AF_INET, & sin-> sin_addr.s_addr, ip, 16); // Save the converted string to the ip array. The second parameter is the binary IP pointer to be converted, the third parameter is the buffer where the IP address is converted. The last parameter is the buffer length printf ("SIOCGIFADDR: % s \ n", ip);} err = ioctl (s, SIOCGIFDSTADDR, & ifr); if (! Err) {inet_ntop (AF_INET, & sin-> sin_addr.s_addr, ip, 16); printf ("SIOCGIFDSTADDR: % s \ n", ip);} err = ioctl (s, SIOCGIFNETMASK, & ifr); if (! Err) {inet_ntop (AF_INET, & sin-> sin_addr.s_addr, ip, 16); printf ("SIOCGIFNETMASK: % s \ n", ip);} memset (& ifr, 0, sizeof (ifr); memcpy (ifr. ifr_name, "eth0", 5); ioctl (s, SIOCGIFBRDADDR, & ifr); struct sockaddr_in * broadcast = (struct sockaddr_in *) & ifr. ifr_broadaddr; inet_ntop (AF_INET, & broadcast-> sin_addr.s_addr, ip, 16); // inet_ntop converts a binary IP address to a decimal string printf ("broadcast ip: % s \ n ", ip); close (s );}

Example 2: [after the code is modified, it has been verified on the machine] Set and obtain the MAC address

#include <stdio.h>#include <string.h>#include <errno.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <net/if.h>typedef unsigned char u8#define LOGD(...) do {printf(__VA_ARGS__); printf("\n");} while(0)int set_mac(u8* addr, int len);int get_mac(u8* addr, int len);int main(int argc, char*argv[]){    int ret = 0;    u8 addr[6] = {0x00, 0x00, 0x00, 0x61, 0x20, 0x58};    ret = set_mac(addr, 6);    if (ret < 0)    {        LOGD("set_mac() error");        return 0;    }    LOGD("set_mac() done");    ret = get_mac(addr, 6);    if (ret < 0)    {        LOGD("get_mac() error");        return 0;    }    LOGD("get_mac() done");    char buf[32] = {0};    snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x",        addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);    LOGD("%s", buf);    return 0;}int set_mac(u8* addr, int len){    int s;    int ret;    struct ifreq ifr;        if (len < 6)    {        LOGD("set_mac(), invalid length");        return -1;    }    s = socket(PF_INET, SOCK_DGRAM, 0);    if (s < 0)    {        LOGD("socket() error: %s", strerror(errno));        return -1;    }    strcpy(ifr.ifr_ifrn.ifrn_name, "eth0");    ifr.ifr_ifru.ifru_hwaddr.sa_family = 1;    memcpy(ifr.ifr_ifru.ifru_hwaddr.sa_data, addr, 6);    ret = ioctl(s, SIOCSIFHWADDR, &ifr);    if (ret != 0)    {        LOGD("ioctl(SIOCSIFHWADDR) error: %d(%s)", errno, strerror(errno));        return -1;    }    return 0;}int get_mac(u8* addr, int len){    int s;    int ret;    struct ifreq ifr;    if (len < 6)    {        LOGD("get_mac(), invalid length");        return -1;    }    s = socket(PF_INET, SOCK_DGRAM, 0);    if (s < 0)    {        LOGD("socket() error: %s", strerror(errno));        return -1;    }    strcpy(ifr.ifr_ifrn.ifrn_name, "eth0");    ret = ioctl(s, SIOCGIFHWADDR, &ifr);    if (ret != 0)    {        LOGD("ioctl(SIOCSIFHWADDR) error: %s", strerror(errno));        return -1;    }    memcpy(addr, ifr.ifr_ifru.ifru_hwaddr.sa_data, 6);    return 0;}

Instance 3: Nic connection status [verified on the computer after modification]

#include  <stdio.h>#include  <stdlib.h>#include  <string.h>#include  <fcntl.h>#include  <errno.h>#include  <sys/ioctl.h>#include  <sys/types.h>#include  <sys/socket.h>#include  <linux/if.h>typedef unsigned short u16;typedef unsigned int u32;typedef unsigned char u8;typedef unsigned long longu64#include  <linux/sockios.h>#include  <linux/ethtool.h>int get_netlink_status(const char *if_name);int main(int argc, char* argv[]){    if(argc != 2)     {        fprintf(stderr, "usage: %s <ethname>.\n", argv[0]);        return -1;    }    if(getuid() != 0)    {        fprintf(stderr, "Netlink Status Check Need Root User.\n");        return 1;    }        printf("Net link status: %s.\n", get_netlink_status(argv[1])==1?"up":"down");    return 0;}// if_name like "ra0", "eth0". Notice: call this function// return value:// -1 -- error , details can check errno// 1 -- interface link up// 0 -- interface link down.int get_netlink_status(const char *if_name){    int skfd;    struct ifreq ifr;    struct ethtool_value edata;    edata.cmd = ETHTOOL_GLINK;    edata.data = 0;    memset(&ifr, 0, sizeof(ifr));    strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name) - 1);    ifr.ifr_data = (char *) &edata;    if (( skfd = socket( AF_INET, SOCK_DGRAM, 0 )) == 0)        return -1;    if(ioctl( skfd, SIOCETHTOOL, &ifr ) == -1)    {        close(skfd);        return -1;    }    close(skfd);    return edata.data;}

Refer to the network programming code written by the predecessors on the network. After you verify and debug the code by yourself, you will be posted on the blog. Thank you for sharing your knowledge on the network ....

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.