gonzui


Format: Advanced Search

t2ex/t2ex_source/kernel/sysmain/src/network_sample/route.cbare sourcepermlink (0.02 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T2EX Software Package
    4:  *
    5:  *    Copyright 2012 by Ken Sakamura.
    6:  *    This software is distributed under the latest version of T-License 2.x.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2012/12/12.
   10:  *    Modified by T-Engine Forum at 2014/07/31.
   11:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/04.
   12:  *
   13:  *----------------------------------------------------------------------
   14:  */
   15: /*
   16:  * This software package is available for use, modification, 
   17:  * and redistribution in accordance with the terms of the attached 
   18:  * T-License 2.x.
   19:  * If you want to redistribute the source code, you need to attach 
   20:  * the T-License 2.x document.
   21:  * There's no obligation to publish the content, and no obligation 
   22:  * to disclose it to the TRON Forum if you have modified the 
   23:  * software package.
   24:  * You can also distribute the modified source code. In this case, 
   25:  * please register the modification to T-Kernel traceability service.
   26:  * People can know the history of modifications by the service, 
   27:  * and can be sure that the version you have inherited some 
   28:  * modification of a particular version or not.
   29:  *
   30:  *    http://trace.tron.org/tk/?lang=en
   31:  *    http://trace.tron.org/tk/?lang=ja
   32:  *
   33:  * As per the provisions of the T-License 2.x, TRON Forum ensures that 
   34:  * the portion of the software that is copyrighted by Ken Sakamura or 
   35:  * the TRON Forum does not infringe the copyrights of a third party.
   36:  * However, it does not make any warranty other than this.
   37:  * DISCLAIMER: TRON Forum and Ken Sakamura shall not be held
   38:  * responsible for any consequences or damages caused directly or
   39:  * indirectly by the use of this software package.
   40:  *
   41:  * The source codes in bsd_source.tar.gz in this software package are 
   42:  * derived from NetBSD or OpenBSD and not covered under T-License 2.x.
   43:  * They need to be changed or redistributed according to the 
   44:  * representation of each source header.
   45:  */
   46: 
   47: /*
   48:  *      @(#)route.c
   49:  *
   50:  */
   51: 
   52: #include <tk/tkernel.h>
   53: 
   54: #include <t2ex/socket.h>
   55: 
   56: #include <stdio.h>
   57: #include <strings.h>
   58: 
   59: #include "util.h"
   60: 
   61: static void route_cmd(int cmd, in_addr_t dest, in_addr_t gate, in_addr_t mask, int index, int direct)
   62: {
   63:         int i = 0;
   64:         int sock;
   65:         int re;
   66:         struct {
   67:                 struct rt_msghdr rtm;
   68:                 struct sockaddr_in addr[3];
   69:         } buf;
   70: 
   71:         bzero(&buf, sizeof buf);
   72:         buf.rtm.rtm_version = RTM_VERSION;
   73:         buf.rtm.rtm_type    = cmd;
   74:         buf.rtm.rtm_index   = index;
   75:         buf.rtm.rtm_flags   = RTF_STATIC;
   76:         if ( direct ) {
   77:                 buf.rtm.rtm_flags |= RTF_HOST;
   78:         } else {
   79:                 buf.rtm.rtm_flags |= RTF_GATEWAY;
   80:         }
   81:         buf.rtm.rtm_addrs   = RTA_DST | RTA_NETMASK;
   82:         if ( gate != 0 ) {
   83:                 buf.rtm.rtm_addrs |= RTA_GATEWAY;
   84:         }
   85:         buf.rtm.rtm_inits   = RTV_HOPCOUNT;
   86:         buf.rtm.rtm_rmx.rmx_hopcount = 1;
   87:         buf.rtm.rtm_seq            = 1;
   88: 
   89:         buf.addr[i].sin_len = sizeof(struct sockaddr_in);
   90:         buf.addr[i].sin_family = AF_INET;
   91:         buf.addr[i].sin_addr.s_addr = dest;
   92:         i++;
   93: 
   94:         if ( gate != 0 ) {
   95:                 buf.addr[i].sin_len = sizeof(struct sockaddr_in);
   96:                 buf.addr[i].sin_family = AF_INET;
   97:                 buf.addr[i].sin_addr.s_addr = gate;
   98:                 i++;
   99:         }
  100: 
  101:         buf.addr[i].sin_len = sizeof(struct sockaddr_in);
  102:         buf.addr[i].sin_family = AF_INET;
  103:         buf.addr[i].sin_addr.s_addr = mask;
  104:         i++;
  105: 
  106:         buf.rtm.rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr) * i;
  107: 
  108:         sock = so_socket(AF_ROUTE, SOCK_RAW, 0);
  109:         DEBUG_PRINT(("route_add: so_socket = %d(%d, %d)\n", sock, MERCD(sock), SERCD(sock)));
  110:         so_shutdown(sock, SHUT_RD);
  111:         re = so_write(sock, &buf, buf.rtm.rtm_msglen);
  112:         DEBUG_PRINT(("route_add: so_write = %d(%d, %d)\n", re, MERCD(re), SERCD(re)));
  113:         so_close(sock);
  114: }
  115: 
  116: void route_change(in_addr_t dest, in_addr_t gate, in_addr_t mask, int index, int direct)
  117: {
  118:         route_cmd(RTM_CHANGE, dest, gate, mask, index, direct);
  119: }
  120: 
  121: void route_delete(in_addr_t dest, in_addr_t mask, int index, int direct)
  122: {
  123:         route_cmd(RTM_DELETE, dest, 0, mask, index, direct);
  124: }
  125: 
  126: void route_add(in_addr_t dest, in_addr_t gate, in_addr_t mask, int index, int direct)
  127: {
  128:         route_cmd(RTM_ADD, dest, gate, mask, index, direct);
  129: }
  130: 
  131: #define ROUNDUP(a) \
  132:         ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
  133: 
  134: static void get_rtaddrs(int addrs, struct sockaddr* sa, struct sockaddr** rti_info)
  135: {
  136:         int i;
  137: 
  138:     for (i = 0; i < RTAX_MAX; i++) {
  139:                 if ( addrs & (1 << i) ) {
  140:                         rti_info[i] = sa;
  141:                         sa = (struct sockaddr*)((char*)sa + ROUNDUP(sa->sa_len));
  142:                 } else {
  143:                         rti_info[i] = NULL;
  144:                 }
  145:     }
  146: }
  147: 
  148: static void np_rtentry(struct rt_msghdr* rtm)
  149: {
  150:     char ifname[IFNAMSIZ + 1];
  151:     struct sockaddr *rti_info[RTAX_MAX];
  152:     struct sockaddr_in* dest = NULL;
  153:     struct sockaddr_in* mask = NULL;
  154:         struct sockaddr* sa;
  155:     char flags[33];
  156:     char* bp = flags;
  157:     char rbuf[18];
  158:         char workbuf[20];
  159:         int len;
  160: 
  161:         sa = (struct sockaddr*)(rtm + 1);
  162:     if (sa->sa_family != AF_INET)
  163:         return;
  164: 
  165:     if (rtm->rtm_flags & RTF_UP)
  166:         *bp++ = 'U';
  167:     if (rtm->rtm_flags & RTF_GATEWAY)
  168:                 *bp++ = 'G';
  169:     if (rtm->rtm_flags & RTF_HOST)
  170:                 *bp++ = 'H';
  171:     if (rtm->rtm_flags & RTF_STATIC)
  172:                 *bp++ = 'S';
  173:     if (bp == flags)
  174:                 return;
  175:     *bp = '\0';
  176: 
  177:     get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
  178: 
  179:     if ((rtm->rtm_addrs & RTA_DST) &&
  180:                     rti_info[RTAX_DST]->sa_family == AF_INET) {
  181:                 dest = (struct sockaddr_in*)rti_info[RTAX_DST];
  182:     }
  183: 
  184:     if ((rtm->rtm_addrs & RTA_NETMASK) &&
  185:             rti_info[RTAX_NETMASK]->sa_len != 0) {
  186:         mask = (struct sockaddr_in*)rti_info[RTAX_NETMASK];
  187:     }
  188: 
  189:         memset(workbuf, 0, sizeof(workbuf));
  190:     if (rtm->rtm_addrs & RTA_GATEWAY) {
  191:                 len = so_getnameinfo(rti_info[RTAX_GATEWAY], rti_info[RTAX_GATEWAY]->sa_len,
  192:                                                          workbuf, sizeof(workbuf), NULL, 0, NI_NUMERICHOST, NULL);
  193:                 if (len < 0) {
  194:                         strcpy(workbuf, "invalid");
  195:                 }
  196:     }
  197: 
  198:     so_ifindextoname(rtm->rtm_index, ifname);
  199: 
  200:     printf("%-16s ", dest != NULL ? inet_ntop(AF_INET, &dest->sin_addr, rbuf, sizeof(rbuf)) : "-");
  201:     printf("%-16s ", mask != NULL ? inet_ntop(AF_INET, &mask->sin_addr, rbuf, sizeof(rbuf)) : "-");
  202:     printf("%-18s ", workbuf[0] != '\0' ? workbuf : "-");
  203:     printf(" %-8s ", flags);
  204:     printf(" %-6s ", ifname);
  205:     printf(" %d ", rtm->rtm_index);
  206: 
  207:     printf("\n");
  208: }
  209: 
  210: void dump_rtlist(void)
  211: {
  212:         union {
  213:                 struct rt_msghdr      rt;
  214:                 char  buf[4096];
  215:         } rtbuf;
  216:         struct rt_msghdr* rtm;
  217:         ER er;
  218: 
  219:         printf("Destination      Netmask          Gateway             Flags     Interface\n");
  220:         er = so_rtlist(AF_INET, NET_RT_DUMP, 0, &rtbuf, sizeof(rtbuf) );
  221:         DEBUG_PRINT(("dump_rtlist: so_rtlist = %d(%d, %d)\n", er, MERCD(er), SERCD(er)));
  222:         for(rtm = &rtbuf.rt; rtm->rtm_msglen != 0; rtm = (struct rt_msghdr *)((void*)rtm + rtm->rtm_msglen) ) {
  223:                 np_rtentry(rtm);
  224:         }
  225: }
  226: