- 论坛徽章:
- 11
|
回复 1# superwujc
自解- # vi show_interface_ip_address_ioctl.c
复制代码
- #include <stdio.h>
- #include <net/if.h>
- #include <sys/ioctl.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <string.h>
- #include <stdlib.h>
- int main(int argc, char *argv[])
- {
- if (argc != 2) {
- fprintf(stderr, "Usage: %s [network interface name]\n", argv[0]);
- exit(EXIT_FAILURE);
- }
- int sfd;
- struct ifreq ifr;
- char ipaddr[INET_ADDRSTRLEN] = {'\0'};
- sfd = socket(AF_INET, SOCK_DGRAM, 0);
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_addr.sa_family = AF_INET;
- strncpy(ifr.ifr_name, argv[1], IFNAMSIZ-1);
- ioctl(sfd, SIOCGIFADDR, &ifr);
- inet_ntop(AF_INET, &(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr), ipaddr, INET_ADDRSTRLEN);
- printf("Interface %s : %s\n", argv[1], ipaddr);
-
- close(sfd);
- exit(EXIT_SUCCESS);
- }
复制代码- # gcc show_interface_ip_address_ioctl.c -o show_interface_ip_address_ioctl -g
复制代码- # gdb -q show_interface_ip_address_ioctl
复制代码
- Reading symbols from /code/ifopt/show_interface_ip_address_ioctl...done.
- (gdb) #
- (gdb)
- (gdb) set args eth0
- (gdb) #
- (gdb)
- (gdb)
- (gdb) break main
- Breakpoint 1 at 0x400754: file show_interface_ip_address_ioctl.c, line 14.
- (gdb) #
- (gdb)
- (gdb)
- (gdb) run
- Starting program: /code/ifopt/show_interface_ip_address_ioctl eth0
- Breakpoint 1, main (argc=2, argv=0x7fffffffe528)
- at show_interface_ip_address_ioctl.c:14
- 14 if (argc != 2) {
- (gdb) #
- (gdb)
- (gdb)
- (gdb) n 6
- 29 ioctl(sfd, SIOCGIFADDR, &ifr);
- (gdb) n
- 30 inet_ntop(AF_INET, &(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr), ipaddr, INET_ADDRSTRLEN);
- (gdb) #
- (gdb)
- (gdb)
- (gdb) # struct ifreq的地址
- (gdb) p &ifr
- $1 = (struct ifreq *) 0x7fffffffe400
- (gdb) #
- (gdb)
- (gdb)
- (gdb)
- (gdb) # 网卡名称
- (gdb) p ifr.ifr_ifrn.ifrn_name
- $2 = "eth0", '\000' <repeats 11 times>
- (gdb) #
- (gdb)
- (gdb)
- (gdb) # 网卡名称所在的地址
- (gdb) p &(ifr.ifr_ifrn.ifrn_name)
- $3 = (char (*)[16]) 0x7fffffffe400
- (gdb) #
- (gdb)
- (gdb)
- (gdb) # 通用套接字地址结构struct sockaddr的地址
- (gdb) p &(ifr.ifr_ifru.ifru_addr)
- $4 = (struct sockaddr *) 0x7fffffffe410
- (gdb) #
- (gdb)
- (gdb)
- (gdb) # ipv4套接字地址结构struct sockaddr_in中,协议族字段的地址
- (gdb) p &(((struct sockaddr_in *)&(ifr.ifr_ifru.ifru_addr))->sin_family)
- $5 = (sa_family_t *) 0x7fffffffe410
- (gdb) #
- (gdb)
- (gdb)
- (gdb) # ipv4套接字地址结构中,ipv4地址字段的地址
- (gdb) p &(((struct sockaddr_in *)&(ifr.ifr_ifru.ifru_addr))->sin_addr)
- $6 = (struct in_addr *) 0x7fffffffe414
- (gdb) #
- (gdb)
- (gdb)
- (gdb) p &((&(((struct sockaddr_in *)&(ifr.ifr_ifru.ifru_addr))->sin_addr))->s_addr)
- $7 = (in_addr_t *) 0x7fffffffe414
- (gdb)
复制代码 调用ioctl(SIOCGIFADDR)后,ip地址返回到struct ifreq中,地址为0x7fffffffe400,其中,网卡名称的16字节地址范围0x7fffffffe400 ~ 0x7fffffffe40F
随后为通用套接字地址结构,转换为ipv4套接字地址结构后,协议字段占据自0x7fffffffe410开始的4字节,而保存ipv4地址的struct in_addr自0x7fffffffe414开始,与struct ifreq的0x7fffffffe400偏移为0x14字节,即10进制的20字节 |
|