티스토리 뷰

원본 : 

https://www.joinc.co.kr/w/Site/system_programing/proc/NetState

 

netstate 정보 얻어오기

st 상태 (ESTABLISHED, TIME_WAIT, FIN_WAIT ...)

www.joinc.co.kr

#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
#include <pwd.h>
const char *TCPFILE = "/proc/net/tcp";
const char *FORMAT ="%s%s%s%s%s%s%s%s%s%s";
static char states[16][20] = { "UNKNOWN" ,"ESTABLISHED", "SYN_SENT", "SYN_RECV", "FIN_WAIT1", "FIN_WAIT2", "TIME_WAIT", "CLOSE", 
"CLOSE_WAIT", "LAST_ACK", "LISTEN", "CLOSING", "MAX_STATES"};
struct netinfo
{
  FILE *tcpfp;
  char localaddr[24];
  char localport[16];
  char remaddr[24];
  char remport[16];
  char stat[16];
  int  txq;
  int  rxq;
  int   uid;
  int  idx;
  char uname[24];
};
typedef struct netinfo TCPINFO;
TCPINFO *nsopen()
{
  TCPINFO *ltcpinfo;
  if(access(TCPFILE,F_OK) !=0)
  {
    perror("ACCESS Error");
    return (TCPINFO *)NULL; 
  }
  ltcpinfo = (TCPINFO *)malloc(sizeof(*ltcpinfo)); 
  memset((void *)ltcpinfo, 0x00, sizeof(*ltcpinfo));
  ltcpinfo->tcpfp = NULL;
  ltcpinfo->tcpfp = fopen(TCPFILE, "r");
  if (ltcpinfo == NULL)
  {
    perror("ACCESS Error");
    free(ltcpinfo);
    return (TCPINFO *)NULL;
  }
  ltcpinfo->uid = -1;
  ltcpinfo->idx = 0;
  return ltcpinfo;
}
void nsclose(TCPINFO *tf)
{
  if (tf->tcpfp == NULL)
    fclose(tf->tcpfp);
  free(tf);
}
char *getuname(char *uname, int uid, int size)
{
  struct passwd *pass_info = NULL;
  while((pass_info = getpwent()) != NULL)
  {
    if (pass_info->pw_uid == uid)
    {
      strncpy(uname, pass_info->pw_name, size);
      return uname;
    }
  }
  return (char *)NULL;
}
TCPINFO *nsread(TCPINFO *info)
{
  char buf[256];
  char *tr;
  char null[16];
  char localaddr[24];
  char remaddr[24];
  char st[4];
  char trxqueue[20];
  char uid[8];
  char uname[36] = {0x00,};
  int  fnum;
  int  snum;
  struct in_addr in;
  char *addr;
  if (info->idx == 0)
  {
    if (fgets(buf, 256, info->tcpfp) == NULL)
    {
      return (TCPINFO *)NULL;
    }
    info->idx=1;
  }
  if (fgets(buf, 256, info->tcpfp) == NULL)
    return (TCPINFO *)NULL;
  // sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
  // 0: 0100007F:A56F 00000000:0000 0A 00000000:00000000 00:00000000 00000000   105        0 10282 1 c34a1c00 3000 0 0 2 -1
  sscanf(buf,"%s %s %s %s %s %s %s %s %s %s", 
                  null,      // sl : 미 사용 
                  localaddr, // local_address 
                  remaddr,   // rem_address
                  st,        // status
                  trxqueue,  // tx_queue & rx_queue
                  null,      // tr & tm->when : 미 사용
                  null,      // retrnsmt : 미사용
                  uid,       // uid
                  null,      // timeout : 미사용
                  null);     // inde : 미사용
  // get localaddr
  sscanf(localaddr, "%x%[:]%x", &fnum, null, &snum);
  in.s_addr = fnum;
  addr = inet_ntoa(in);
  sprintf(info->localaddr, "%s", addr); 
  sprintf(info->localport, "%d", snum); 
  // get remaddr
  sscanf(remaddr, "%x%[:]%x", &fnum, null, &snum);
  in.s_addr = fnum;
  addr = inet_ntoa(in);
  sprintf(info->remaddr, "%s", addr); 
  sprintf(info->remport, "%d", snum); 
  // Status
  sscanf(st, "%x", &fnum);
  sprintf(info->stat,"%s", states[fnum]);
  // User Infomation
  if (getuname(uname, atoi(uid), 32) == NULL)
  {
    sprintf(info->uname,"%s", "");
  }
  else
    sprintf(info->uname,"%s", uname);
  info->uid = atoi(uid);
  return info; 
}
int main(int argc, char **argv)
{
  TCPINFO *tf;
  tf = nsopen();
  while (nsread(tf) != (TCPINFO *)NULL)
  {
    printf("%s:%s ---> %s:%s\t%s\t%s\n", tf->localaddr, tf->localport, 
                    tf->remaddr, tf->remport, tf->stat, tf->uname);
  }
  nsclose(tf);
}

 

실행결과 :

# ./mynetstat
127.0.0.1:37382 ---> 0.0.0.0:0  CLOSING hplip
127.0.0.1:34641 ---> 0.0.0.0:0  CLOSING
127.0.0.1:631 ---> 0.0.0.0:0    CLOSING
203.229.213.133:39600 ---> 207.46.27.62:1863    SYN_SENT
203.229.213.133:33609 ---> 203.229.213.91:22    SYN_SENT
203.229.213.133:44665 ---> 65.54.228.33:1863    SYN_SENT
203.229.213.133:45402 ---> 211.117.61.247:6667  SYN_SENT
203.229.213.133:50398 ---> 207.46.26.112:1863   SYN_SENT
203.229.213.133:37614 ---> 207.46.26.162:1863   SYN_SENT
203.229.213.133:48312 ---> 207.46.111.89:1863   SYN_SENT
127.0.0.1:43480 ---> 127.0.0.1:34641    SYN_SENT
127.0.0.1:34641 ---> 127.0.0.1:43480    SYN_SENT

 

cf. netstat 명령어는 /proc/net/tcp를 파싱함. session이 많을수록 자원 소모량이 커 OS CPU사용율에 큰 영향을 미침(몇몇core 100%full 초래). 따라서 ss명령어로 대체를 권고

 

https://computingforgeeks.com/netstat-vs-ss-usage-guide-linux/

 

netstat vs ss usage guide on Linux | ComputingForGeeks

Welcome to netstat vs ss usage guide on Linux which tries to teach you usage of netstat and ss commands using examples. We'll start off this guide by

computingforgeeks.com

 

'IA > System Admin' 카테고리의 다른 글

Datastore Overhead requirements  (0) 2022.07.03
[storage] Erasure Coding vs. RAID  (0) 2022.07.02
Solaris10HardeningCheck  (0) 2019.04.02
shell script/modify text file_특정라인의 대체  (0) 2019.04.02
[tip] 명령어 빈도(linux계열)  (0) 2019.03.18
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/10   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함