- </pre><pre code_snippet_id="495447" snippet_file_name="blog_20141024_1_7065081" name="code" class="html">/********************************** (C) COPYRIGHT *******************************/
- * File Name : get_gw.c
- * Author : skdkjzz
- * Date : 2014/08/07
- * Description : linux下获取网卡信息
- *********************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <asm/types.h>
- #include <netinet/ether.h>
- #include <netinet/in.h>
- #include <net/if.h>
- #include <stdio.h>
- #include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <linux/netlink.h>
- #include <linux/rtnetlink.h>
- #include <sys/types.h>
- #define JSOEPH_NET_RMSG_BUFSIZE 8192
- typedef struct route_info{
- u_int dstAddr;
- u_int srcAddr;
- u_int gateWay;
- u_int genmask;
- char ifName[IF_NAMESIZE];
- }JOSEPH_ROUTE_INFO;
- #ifdef JOSEPH_CAT_ENUM
- /* Routing message attributes */
- enum rtattr_type_t {
- RTA_UNSPEC,
- RTA_DST,
- RTA_SRC,
- RTA_IIF,
- RTA_OIF,
- RTA_GATEWAY,
- RTA_PRIORITY,
- RTA_PREFSRC,
- RTA_METRICS,
- RTA_MULTIPATH,
- RTA_PROTOINFO, /* no longer used */
- RTA_FLOW,
- RTA_CACHEINFO,
- RTA_SESSION, /* no longer used */
- RTA_MP_ALGO, /* no longer used */
- RTA_TABLE,
- RTA_MARK,
- __RTA_MAX
- };
- #endif
- int Joseph_ReadNlSock(int sockFd, char *bufPtr, int seqNum, int pId)
- {
- struct nlmsghdr *nlHdr;
- int readLen = 0, msgLen = 0;
- do
- {
- /* Recieve response from the kernel */
- if((readLen = recv(sockFd, bufPtr, JSOEPH_NET_RMSG_BUFSIZE - msgLen, 0)) < 0){
- printf("SOCK READ Error !\n");
- return -1;
- }
- nlHdr = (struct nlmsghdr *)bufPtr;
- /* Check if the header is valid */
- if((NLMSG_OK(nlHdr, readLen) == 0) || (nlHdr->nlmsg_type == NLMSG_ERROR))
- {
- printf("Error in recieved packet !\n");
- return -1;
- }
- /* Check if the its the last message */
- if(nlHdr->nlmsg_type == NLMSG_DONE)
- {
- break;
- }
- else
- {
- /* Else move the pointer to buffer appropriately */
- bufPtr += readLen;
- msgLen += readLen;
- }
- /* Check if its a multi part message */
- if((nlHdr->nlmsg_flags & NLM_F_MULTI) == 0)
- {
- /* return if its not */
- break;
- }
- } while((nlHdr->nlmsg_seq != seqNum) || (nlHdr->nlmsg_pid != pId));
- return msgLen;
- }
- /* For printing the routes. */
- void Joseph_PrintRoute(struct route_info *rtInfo,char *if_name_in)
- {
- char tempBuf[512];
- if(strcmp(rtInfo->ifName,if_name_in) == 0)
- {
- /* Print Destination address */
- if(rtInfo->dstAddr != 0)
- strcpy(tempBuf, (char *)inet_ntoa(rtInfo->dstAddr));
- else
- sprintf(tempBuf,"0.0.0.0\t");
- fprintf(stdout,"%s\t", tempBuf);
- /* Print Gateway address */
- if(rtInfo->gateWay != 0)
- strcpy(tempBuf, (char *)inet_ntoa(rtInfo->gateWay));
- else
- sprintf(tempBuf,"0.0.0.0\t");
- fprintf(stdout,"%s\t", tempBuf);
- /* Print Interface Name*/
- fprintf(stdout,"%s\t", rtInfo->ifName);
- /* Print genmask address */
- if(rtInfo->genmask != 0)
- strcpy(tempBuf, (char *)inet_ntoa(rtInfo->genmask));
- else
- sprintf(tempBuf,"0.0.0.0\t");
- fprintf(stdout,"%s\t", tempBuf);
- /* Print Source address */
- if(rtInfo->srcAddr != 0)
- strcpy(tempBuf, (char *)inet_ntoa(rtInfo->srcAddr));
- else
- sprintf(tempBuf,"0.0.0.0\t");
- fprintf(stdout,"%s\n", tempBuf);
- }
- }
- /* For parsing the route info returned */
- int Joseph_ParseRoutes(struct nlmsghdr *nlHdr, struct route_info *rtInfo,char *gateway,char *if_name_in)
- {
- struct rtmsg *rtMsg;
- struct rtattr *rtAttr;
- int rtLen;
- char *tempBuf = NULL;
- tempBuf = (char *)malloc(100);
- rtMsg = (struct rtmsg *)NLMSG_DATA(nlHdr);
- /* If the route is not for AF_INET or does not belong to main routing table then return. */
- if((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table != RT_TABLE_MAIN))
- {
- free(tempBuf);
- tempBuf = NULL;
- return -1;
- }
- /* get the rtattr field */
- rtAttr = (struct rtattr *)RTM_RTA(rtMsg);
- rtLen = RTM_PAYLOAD(nlHdr);
- for(;RTA_OK(rtAttr,rtLen);rtAttr = RTA_NEXT(rtAttr,rtLen))
- {
- switch(rtAttr->rta_type)
- {
- case RTA_OIF:
- if_indextoname(*(int *)RTA_DATA(rtAttr), rtInfo->ifName);
- break;
- case RTA_GATEWAY:
- rtInfo->gateWay = *(u_int *)RTA_DATA(rtAttr);
- break;
- case RTA_PREFSRC:
- rtInfo->srcAddr = *(u_int *)RTA_DATA(rtAttr);
- break;
- case RTA_DST:
- rtInfo->dstAddr = *(u_int *)RTA_DATA(rtAttr);
- break;
- }
- }
- //printf("%s\n", (char *)inet_ntoa(rtInfo->dstAddr));
- //ADDED BY BOB - ALSO COMMENTED Joseph_PrintRoute
- if (strstr((char *)inet_ntoa(rtInfo->dstAddr), "0.0.0.0"))
- {
- sprintf(gateway,"%s",(char *)inet_ntoa(rtInfo->gateWay));
- }
- Joseph_PrintRoute(rtInfo,if_name_in);
- free(tempBuf);
- tempBuf = NULL;
- return 0;
- }
- int Joseph_Get_Gateway(char *gateway,char *if_name)
- {
- struct nlmsghdr *nlMsg;
- struct rtmsg *rtMsg;
- struct route_info *rtInfo;
- char msgBuf[JSOEPH_NET_RMSG_BUFSIZE];
- int sock, len, msgSeq = 0;
- char buff[1024];
- if(strlen(if_name) == 0 || gateway == NULL)
- {
- return -1;
- }
- /* Create Socket */
- if((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0)
- {
- printf("Socket Creation Error !\n");
- return -1;
- }
- /* Initialize the buffer */
- memset(msgBuf, 0, JSOEPH_NET_RMSG_BUFSIZE);
- /* point the header and the msg structure pointers into the buffer */
- nlMsg = (struct nlmsghdr *)msgBuf;
- rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsg);
- /* Fill in the nlmsg header*/
- nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length of message.
- nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .
- nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; // The message is a request for dump.
- nlMsg->nlmsg_seq = msgSeq++; // Sequence of the message packet.
- nlMsg->nlmsg_pid = getpid(); // PID of process sending the request.
- /* Send the request */
- if(send(sock, nlMsg, nlMsg->nlmsg_len, 0) < 0)
- {
- printf("Write To Socket Failed...\n");
- close(sock);
- return -1;
- }
- /* Read the response */
- if((len = Joseph_ReadNlSock(sock, msgBuf, msgSeq, getpid())) < 0)
- {
- printf("Read From Socket Failed...\n");
- close(sock);
- return -1;
- }
- /* Parse and print the response */
- rtInfo = (struct route_info *)malloc(sizeof(struct route_info));
- /* THIS IS THE NETTSTAT -RL code I commented out the printing here and in parse routes */
- //fprintf(stdout, "Destination\tGateway\tInterface\tSource\n");
- for( ; NLMSG_OK(nlMsg,len); nlMsg = NLMSG_NEXT(nlMsg,len))
- {
- memset(rtInfo, 0, sizeof(struct route_info));
- Joseph_ParseRoutes(nlMsg,rtInfo,gateway,if_name);
- }
- free(rtInfo);
- rtInfo = NULL;
- close(sock);
- return 0;
- }
- int main(int argc,char *argv[])
- {
- int itertion = 0;
- char gateway[16]={0};
- int Qy_Ret = 0;
- if(argc != 2)
- {
- return -1;
- }
- while(itertion < 30)
- {
- Qy_Ret = Joseph_Get_Gateway(gateway,argv[1]);
- if(Qy_Ret <0)
- {
- return -1;
- }
- itertion++;
- printf("Gateway:%s\n", gateway);
- sleep(1);
- }
- return 0;
- }
- </span></span>
from:http://blog.csdn.net/skdkjzz/article/details/40427171