⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bgp_output.c

📁 同时支持IPv4和IPv6的BGP协议实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 1998 WIDE Project. * All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include "include.h"#include "bgp.h"#include "router.h"#include "task.h"#include "rt_table.h"#include "aspath.h"#include "bgp_var.h"#include "in6.h"#include "ripng.h"#define BGP_LOG_SEND(type, len) IFLOG(LOG_BGPOUTPUT) \          do { syslog(LOG_DEBUG,\		   "BGP+ SEND %s+%d -> %s+%d",\		   ip6str2(&bnp->rp_myaddr),\		   ntohs(bnp->rp_myaddr.sin6_port),\		   bgp_peerstr(bnp),\		   ntohs(bnp->rp_addr.sin6_port));\	      syslog(LOG_DEBUG,\		     "BGP+ SEND message type %d (%s) length %d",\		     (type), bgp_msgstr[(type)], (len));\	  } while (0)/* *   bgp_send_open() */intbgp_send_open(struct rpcb *bnp){  int i;  u_int16_t      netasnum, nethldtim;  struct bgphdr *bh;  task          *tsk;  extern byte       outpkt[];  extern char      *bgp_msgstr[];  extern u_int16_t  my_as_number, bgpHoldtime;  extern u_int32_t  bgpIdentifier;  extern fd_set     fdmask;  extern task      *taskhead;  memset(outpkt, 0, BGPMAXPACKETSIZE);  bh = (struct bgphdr *)outpkt;  /** fixed-size header **/  /* Marker (16-octet to be all 1) */  memset(bh->bh_marker, 0xff, BGP_HEADER_MARKER_LEN);  /* Type   (1-octet) */  bh->bh_type = BGP_OPEN;  i = BGP_HEADER_LEN;  /***  Open Message Format  ***/  /* Version (1-octet)    */  outpkt[i++] = BGP_VERSION_4;  /* My Autonomous System (2-octet) */  netasnum = htons(my_as_number);  memcpy(&outpkt[i], &netasnum, 2);  i += 2;  /* Hold Time            (2-octet) */  nethldtim = htons(bgpHoldtime);  memcpy(&outpkt[i], &nethldtim, 2);  i += 2;  /* BGP Identifier       (4-octet) */  memcpy(&outpkt[i], &bgpIdentifier, 4);  /* net-order (jinmei) */  i += 4;  /* Optional Parameters  (length is specified by "Opt Parm Len") */  /* Opt Parm Len         (1-octet) */  i++;  /* NO authentification is supported. */  /* again, total msg Length (2-octet) field in the header */  bh->bh_length = htons(i);  /****  send OPEN message  ****/  if ((write(bnp->rp_socket, outpkt, i)) != i) {    syslog(LOG_ERR, "<bgp_send_open>: write failed");    bgp_cease(bnp);    return NULL;  }  bgp_update_stat(bnp, BGPS_OPENSENT);  BGP_LOG_SEND(BGP_OPEN, i);  /***   OpenSent   ***/  bnp->rp_state = BGPSTATE_OPENSENT;  IFLOG(LOG_BGPSTATE)    syslog(LOG_DEBUG, "<%s>: BGP state shift[%s] peer: %s", __FUNCTION__,	   bgp_statestr[bnp->rp_state], bgp_peerstr(bnp));  FD_SET(bnp->rp_socket, &fdmask);  /* open-sent Socket (to the global) */  MALLOC(tsk, task);  if (taskhead) {    insque(tsk, taskhead);  /* will be sorted later by task_timer_update() */  } else {    tsk->tsk_next = tsk;    tsk->tsk_prev = tsk;    taskhead      = tsk;  }  tsk->tsk_bgp         = bnp;  tsk->tsk_timename    = BGP_HOLD_TIMER;  bnp->rp_hold_timer = tsk; /* was originally set to a large value */  tsk->tsk_timefull.tv_sec  = bgpHoldtime;  tsk->tsk_timefull.tv_usec = 0;  /*  Hold timer ON. */   task_timer_update(tsk);  return NULL;}/* *   bgp_send_notification() */intbgp_send_notification(bnp, errcode, subcode, len, data)     struct rpcb *bnp;     byte errcode;     byte subcode;     int len;     byte *data;{  int            i;     /* bytes to send */  int            wlen;  struct bgphdr *bh;  extern byte      outpkt[];  extern char *bgp_errstr[];  extern char *bgp_hdrerrstr[];  extern char *bgp_opnerrstr[];  extern char *bgp_upderrstr[];  extern char *bgp_msgstr[];  memset(outpkt, 0, BGPMAXPACKETSIZE);  bh = (struct bgphdr *)outpkt;  /** fixed-size header **/  /* Marker (16-octet to be all 1) */  memset(bh->bh_marker, 0xff, BGP_HEADER_MARKER_LEN);  /* Type   (1-octet) */  bh->bh_type = BGP_NOTIFY;  i = BGP_HEADER_LEN;  /***  NOTIFICATION Message Format ***/  /*   Error Code, Sub Code  */  outpkt[i++] = errcode;  outpkt[i++] = subcode;  memcpy(&outpkt[i], data, len);  i += len;  /* again, total msg Length (2-octet) field in the header */  bh->bh_length = htons(i);  /****   send  NOTIFICATION  message   ****/   if ((wlen = write(bnp->rp_socket, outpkt, i)) != i)    syslog(LOG_ERR, "%s: write to %s (%s AS %d) failed: %s", __FUNCTION__,	   bgp_peerstr(bnp),	   ((bnp->rp_mode & BGPO_IGP) ? "Internal" : "External"),	   (int)bnp->rp_as, strerror(errno));  else    syslog(LOG_NOTICE,	   "NOTIFICATION sent to %s (%s AS %d): code %d (%s) data %s",	   bgp_peerstr(bnp),	   ((bnp->rp_mode & BGPO_IGP) ? "Internal" : "External"),	   (int)bnp->rp_as,	   errcode,	   bgp_errstr[errcode],	   bgp_errdatastr(data, len));  switch (errcode) { /* code */  case BGP_ERR_HEADER:    if (subcode <= BGP_ERRHDR_TYPE)      syslog(LOG_NOTICE, "\t subcode (%d) %s",	     subcode, bgp_hdrerrstr[subcode]);    break;  case BGP_ERR_OPEN:    if (subcode <= BGP_ERROPN_BADHOLDTIME)      syslog(LOG_NOTICE, "\t subcode (%d) %s",	     subcode, bgp_opnerrstr[subcode]);    break;  case BGP_ERR_UPDATE:    if (subcode <= BGP_ERRUPD_ASPATH)      syslog(LOG_NOTICE, "\t subcode (%d) %s",	     subcode, bgp_upderrstr[subcode]);    break;  default:    break;  }  bgp_update_stat(bnp, BGPS_NOTIFYSENT);  BGP_LOG_SEND(BGP_NOTIFY, i);  bnp->rp_state = BGPSTATE_IDLE;  IFLOG(LOG_BGPSTATE)    syslog(LOG_NOTICE, "<%s>: BGP state shift[%s] peer: %s", __FUNCTION__,	   bgp_statestr[bnp->rp_state], bgp_peerstr(bnp));  return NULL;    /* End of bgp_send_notification() */}/* *   bgp_send_keepalive() */intbgp_send_keepalive(struct rpcb *bnp){  struct bgphdr *bh;  extern byte       outpkt[];  extern char      *bgp_msgstr[];  memset(outpkt,   0, BGPMAXPACKETSIZE);  bh = (struct bgphdr *)outpkt;    /** fixed-size header **/  /* Marker (16-octet to be all 1) */  memset(bh->bh_marker, 0xff, BGP_HEADER_MARKER_LEN);  /* Type   (1-octet) */  bh->bh_type = BGP_KEEPALIVE;  /* again, total msg Length (2-octet) field in the header */  bh->bh_length = htons(BGP_HEADER_LEN);#if 0  /*   * XXX: we have to introduce a jitter here, but usleep   * is not appropriate...   */  usleep(BGP_ADV_DELAY);   /* <---- important !! */#endif   /****  send KEEPALIVE message  ****/  if ((write(bnp->rp_socket, outpkt, BGP_HEADER_LEN)) != BGP_HEADER_LEN) {    dperror("<bgp_send_keepalive>: write failed");    syslog(LOG_ERR, "<bgp_send_keepalive>: write failed");    bgp_cease(bnp);    return NULL;  }  bgp_update_stat(bnp, BGPS_KEEPALIVESENT);  BGP_LOG_SEND(BGP_KEEPALIVE, BGP_HEADER_LEN);  /*  KeepAlive Timer ON. */  task_timer_update(bnp->rp_keepalive_timer);  return NULL;}#define BGP_LOG_ATTR  IFLOG(LOG_BGPOUTPUT) { syslog(LOG_DEBUG,\			 "BGP+ SEND flags 0x%x code %s(%d):\\",\			 outpkt[i-2],\			 pa_typestr[outpkt[i-1]],\			 outpkt[i-1]); }/* * *   bgp_send_update() *       RETURN VALUES: last rte */struct rt_entry *bgp_send_update(bnp, rte, headrte)     struct rpcb     *bnp;     struct rt_entry *rte, *headrte;    /* is ring, and, have the same aspath. */{  struct bgphdr   *bh;  int              i, topa_p, mp_p, lennh_p, nlri_p;       /* cursor */  u_int8_t         origin;  int              aspathlen;  struct aspath   *asp;  u_int16_t        netafi;  u_int16_t        netmpnlrilen, nettpalen, netaspathlen;  u_int32_t        netorigid = 0;  u_int16_t        netnlrilen;  struct rtproto  *rtp;    /* origin protocol of rte                 */  struct rtproto   artp;  struct rt_entry *rt;     /* return value. the last RTE which advd. */  struct rt_entry *agg;    /* (1998/06/12) */  struct optatr *optatr;  extern byte       outpkt[];  extern u_int16_t  my_as_number;  extern byte       IamRR;  extern u_int32_t  bgpIdentifier;  extern char      *bgp_msgstr[], *bgp_statestr[];  extern char      *pa_typestr[], *origin_str[];  IFLOG(LOG_BGPOUTPUT)    syslog(LOG_DEBUG,	   "<%s>: invoked. AS=%u, ID=%s, state=%s",  /* iw97  */	   __FUNCTION__,	   bnp->rp_as, inet_ntoa(*(struct in_addr *)&bnp->rp_id),	   bgp_statestr[bnp->rp_state]);  if (bnp->rp_state != BGPSTATE_ESTABLISHED)    fatalx("<bgp_send_update>: internal error: invalid state");  if (rte == NULL) {                /* argument */    IFLOG(LOG_BGPOUTPUT)      syslog(LOG_DEBUG, "<%s>: Nothing to be sent.", __FUNCTION__);    return NULL;  }  memset(&artp, 0, sizeof(artp));  artp.rtp_type = RTPROTO_BGP;  artp.rtp_bgp   = bnp;  memset(outpkt, 0, BGPMAXPACKETSIZE);  rt = NULL;  bh = (struct bgphdr *)outpkt;    /*** fixed-size header ***/  /* Marker (16 octets to be all 1) */  memset(bh->bh_marker, 0xff, BGP_HEADER_MARKER_LEN);  /* Type   (1 octet) */  bh->bh_type = BGP_UPDATE;  i = BGP_HEADER_LEN;  /***  Update Message Format  ***/  /* Unfeasible Routes Length (2 octets)  */   i += 2;  /* IPv6 (BGP4+) doesn't send this.      */  /*   Total Path Attribute Length (2 octets) (0...65535)    */  i += 2;  topa_p = i;  rtp = &rte->rt_proto;              /* identical to each RTE */  /*   *   Path Attributes   */  /**  ORIGIN (Type Code 1)  **/  outpkt[i++] |= PA_FLAG_TRANS;      /* well-known mandatory */  outpkt[i++] =  PA4_TYPE_ORIGIN;    /* T */  BGP_LOG_ATTR;  outpkt[i++] =  PA4_LEN_ORIGIN;     /* L */  /* data len */                                     /* V */  switch (rtp->rtp_type) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -